Commit 0342c9fd authored by Jason R. Coombs's avatar Jason R. Coombs

Merge commit '619e229c' into feature/2093-docs-revamp

parents f2564d7d 619e229c
[bumpversion] [bumpversion]
current_version = 46.1.3 current_version = 46.3.1
commit = True commit = True
tag = True tag = True
......
v46.3.1
-------
No significant changes.
v46.3.0
-------
* #2089: Package index functionality no longer attempts to remove an md5 fragment from the index URL. This functionality, added for distribute #163 is no longer relevant.
* #2041: Preserve file modes during pkg files copying, but clear read only flag for target afterwards.
* #2105: Filter ``2to3`` deprecation warnings from ``TestDevelop.test_2to3_user_mode``.
v46.2.0
-------
* #2040: Deprecated the ``bdist_wininst`` command. Binary packages should be built as wheels instead.
* #2062: Change 'Mac OS X' to 'macOS' in code.
* #2075: Stop recognizing files ending with ``.dist-info`` as distribution metadata.
* #2086: Deprecate 'use_2to3' functionality. Packagers are encouraged to use single-source solutions or build tool chains to manage conversions outside of setuptools.
* #1698: Added documentation for ``build_meta`` (a bare minimum, not completed).
* #2082: Filter ``lib2to3`` ``PendingDeprecationWarning`` and ``DeprecationWarning`` in tests,
because ``lib2to3`` is `deprecated in Python 3.9 <https://bugs.python.org/issue40360>`_.
v46.1.3 v46.1.3
------- -------
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
.. _PyPI link: https://pypi.org/project/setuptools .. _PyPI link: https://pypi.org/project/setuptools
.. image:: https://dev.azure.com/jaraco/setuptools/_apis/build/status/jaraco.setuptools?branchName=master .. image:: https://dev.azure.com/jaraco/setuptools/_apis/build/status/pypa.setuptools?branchName=master
:target: https://dev.azure.com/jaraco/setuptools/_build/latest?definitionId=1&branchName=master :target: https://dev.azure.com/jaraco/setuptools/_build/latest?definitionId=1&branchName=master
.. image:: https://img.shields.io/travis/pypa/setuptools/master.svg?label=Linux%20CI&logo=travis&logoColor=white .. image:: https://img.shields.io/travis/pypa/setuptools/master.svg?label=Linux%20CI&logo=travis&logoColor=white
......
...@@ -11,10 +11,12 @@ trigger: ...@@ -11,10 +11,12 @@ trigger:
- '*' - '*'
pool: pool:
vmimage: 'Ubuntu-18.04' vmImage: $(pool_vm_image)
variables: variables:
- group: Azure secrets - group: Azure secrets
- name: pool_vm_image
value: Ubuntu-18.04
stages: stages:
- stage: Test - stage: Test
...@@ -23,10 +25,17 @@ stages: ...@@ -23,10 +25,17 @@ stages:
- job: 'Test' - job: 'Test'
strategy: strategy:
matrix: matrix:
Python36: Bionic Python 3.6:
python.version: '3.6' python.version: '3.6'
Python38: Bionic Python 3.8:
python.version: '3.8' python.version: '3.8'
Windows:
python.version: '3.8'
pool_vm_image: vs2017-win2016
MacOS:
python.version: '3.8'
pool_vm_image: macos-10.15
maxParallel: 4 maxParallel: 4
steps: steps:
......
Added documentation for ``build_meta`` (a bare minimum, not completed).
Deprecated the ``bdist_wininst`` command. Binary packages should be built as wheels instead.
Preserve file modes during pkg files copying, but clear read only flag for target afterwards.
Change 'Mac OS X' to 'macOS' in code.
Filter ``lib2to3`` ``PendingDeprecationWarning`` and ``DeprecationWarning`` in testes,
because ``lib2to3`` is `deprecated in Python 3.9 <https://bugs.python.org/issue40360>`_.
Deprecate 'use_2to3' functionality. Packagers are encouraged to use single-source solutions or build tool chains to manage conversions outside of setuptools.
...@@ -2,3 +2,6 @@ ...@@ -2,3 +2,6 @@
sphinx sphinx
jaraco.packaging>=6.1 jaraco.packaging>=6.1
rst.linker>=1.9 rst.linker>=1.9
pygments-github-lexers==0.0.5
setuptools>=34
...@@ -123,6 +123,48 @@ Our apologies for the inconvenience, and thank you for your patience. ...@@ -123,6 +123,48 @@ Our apologies for the inconvenience, and thank you for your patience.
setup.cfg-only projects
=======================
.. versionadded:: 40.9.0
If ``setup.py`` is missing from the project directory when a :pep:`517`
build is invoked, ``setuptools`` emulates a dummy ``setup.py`` file containing
only a ``setuptools.setup()`` call.
.. note::
:pep:`517` doesn't support editable installs so this is currently
incompatible with ``pip install -e .``, as :pep:`517` does not support editable installs.
This means that you can have a Python project with all build configuration
specified in ``setup.cfg``, without a ``setup.py`` file, if you **can rely
on** your project always being built by a :pep:`517`/:pep:`518` compatible
frontend.
To use this feature:
* Specify build requirements and :pep:`517` build backend in
``pyproject.toml``.
For example:
.. code-block:: toml
[build-system]
requires = [
"setuptools >= 40.9.0",
"wheel",
]
build-backend = "setuptools.build_meta"
* Use a :pep:`517` compatible build frontend, such as ``pip >= 19`` or ``pep517``.
.. warning::
As :pep:`517` is new, support is not universal, and frontends that
do support it may still have bugs. For compatibility, you may want to
put a ``setup.py`` file containing only a ``setuptools.setup()``
invocation.
Configuration API Configuration API
......
...@@ -55,7 +55,7 @@ except NameError: ...@@ -55,7 +55,7 @@ except NameError:
FileExistsError = OSError FileExistsError = OSError
from pkg_resources.extern import six from pkg_resources.extern import six
from pkg_resources.extern.six.moves import urllib, map, filter from pkg_resources.extern.six.moves import map, filter
# capture these to bypass sandboxing # capture these to bypass sandboxing
from os import utime from os import utime
...@@ -2069,11 +2069,14 @@ def find_on_path(importer, path_item, only=False): ...@@ -2069,11 +2069,14 @@ def find_on_path(importer, path_item, only=False):
def dist_factory(path_item, entry, only): def dist_factory(path_item, entry, only):
""" """Return a dist_factory for the given entry."""
Return a dist_factory for a path_item and entry
"""
lower = entry.lower() lower = entry.lower()
is_meta = any(map(lower.endswith, ('.egg-info', '.dist-info'))) is_egg_info = lower.endswith('.egg-info')
is_dist_info = (
lower.endswith('.dist-info') and
os.path.isdir(os.path.join(path_item, entry))
)
is_meta = is_egg_info or is_dist_info
return ( return (
distributions_from_metadata distributions_from_metadata
if is_meta else if is_meta else
...@@ -2543,15 +2546,6 @@ class EntryPoint: ...@@ -2543,15 +2546,6 @@ class EntryPoint:
return maps return maps
def _remove_md5_fragment(location):
if not location:
return ''
parsed = urllib.parse.urlparse(location)
if parsed[-1].startswith('md5='):
return urllib.parse.urlunparse(parsed[:-1] + ('',))
return location
def _version_from_file(lines): def _version_from_file(lines):
""" """
Given an iterable of lines from a Metadata file, return Given an iterable of lines from a Metadata file, return
...@@ -2608,7 +2602,7 @@ class Distribution: ...@@ -2608,7 +2602,7 @@ class Distribution:
self.parsed_version, self.parsed_version,
self.precedence, self.precedence,
self.key, self.key,
_remove_md5_fragment(self.location), self.location,
self.py_version or '', self.py_version or '',
self.platform or '', self.platform or '',
) )
......
...@@ -330,6 +330,14 @@ def test_distribution_version_missing_undetected_path(): ...@@ -330,6 +330,14 @@ def test_distribution_version_missing_undetected_path():
assert msg == expected assert msg == expected
@pytest.mark.parametrize('only', [False, True])
def test_dist_info_is_not_dir(tmp_path, only):
"""Test path containing a file with dist-info extension."""
dist_info = tmp_path / 'foobar.dist-info'
dist_info.touch()
assert not pkg_resources.dist_factory(str(tmp_path), str(dist_info), only)
class TestDeepVersionLookupDistutils: class TestDeepVersionLookupDistutils:
@pytest.fixture @pytest.fixture
def env(self, tmpdir): def env(self, tmpdir):
......
...@@ -14,8 +14,8 @@ __metaclass__ = type ...@@ -14,8 +14,8 @@ __metaclass__ = type
def strip_comments(s): def strip_comments(s):
return '\n'.join( return '\n'.join(
l for l in s.split('\n') line for line in s.split('\n')
if l.strip() and not l.strip().startswith('#') if line.strip() and not line.strip().startswith('#')
) )
......
...@@ -16,7 +16,7 @@ formats = zip ...@@ -16,7 +16,7 @@ formats = zip
[metadata] [metadata]
name = setuptools name = setuptools
version = 46.1.3 version = 46.3.1
description = Easily download, build, install, upgrade, and uninstall Python packages description = Easily download, build, install, upgrade, and uninstall Python packages
author = Python Packaging Authority author = Python Packaging Authority
author_email = distutils-sig@python.org author_email = distutils-sig@python.org
...@@ -78,3 +78,4 @@ docs = ...@@ -78,3 +78,4 @@ docs =
sphinx sphinx
jaraco.packaging>=6.1 jaraco.packaging>=6.1
rst.linker>=1.9 rst.linker>=1.9
pygments-github-lexers==0.0.5
...@@ -6,7 +6,7 @@ from setuptools.extern.six import PY2, PY3 ...@@ -6,7 +6,7 @@ from setuptools.extern.six import PY2, PY3
__all__ = [ __all__ = [
'fail_on_ascii', 'py2_only', 'py3_only' 'fail_on_ascii', 'py2_only', 'py3_only', 'ack_2to3'
] ]
...@@ -16,3 +16,5 @@ fail_on_ascii = pytest.mark.xfail(is_ascii, reason="Test fails in this locale") ...@@ -16,3 +16,5 @@ fail_on_ascii = pytest.mark.xfail(is_ascii, reason="Test fails in this locale")
py2_only = pytest.mark.skipif(not PY2, reason="Test runs on Python 2 only") py2_only = pytest.mark.skipif(not PY2, reason="Test runs on Python 2 only")
py3_only = pytest.mark.skipif(not PY3, reason="Test runs on Python 3 only") py3_only = pytest.mark.skipif(not PY3, reason="Test runs on Python 3 only")
ack_2to3 = pytest.mark.filterwarnings('ignore:2to3 support is deprecated')
...@@ -17,6 +17,7 @@ import pytest ...@@ -17,6 +17,7 @@ import pytest
from setuptools.command.develop import develop from setuptools.command.develop import develop
from setuptools.dist import Distribution from setuptools.dist import Distribution
from setuptools.tests import ack_2to3
from . import contexts from . import contexts
from . import namespaces from . import namespaces
...@@ -65,6 +66,7 @@ class TestDevelop: ...@@ -65,6 +66,7 @@ class TestDevelop:
@pytest.mark.skipif( @pytest.mark.skipif(
in_virtualenv or in_venv, in_virtualenv or in_venv,
reason="Cannot run when invoked in a virtualenv or venv") reason="Cannot run when invoked in a virtualenv or venv")
@ack_2to3
def test_2to3_user_mode(self, test_env): def test_2to3_user_mode(self, test_env):
settings = dict( settings = dict(
name='foo', name='foo',
......
...@@ -3,15 +3,14 @@ from __future__ import absolute_import ...@@ -3,15 +3,14 @@ from __future__ import absolute_import
import sys import sys
import os import os
import distutils.errors import distutils.errors
import platform
from setuptools.extern import six from setuptools.extern import six
from setuptools.extern.six.moves import urllib, http_client from setuptools.extern.six.moves import urllib, http_client
import mock import mock
import pytest import pytest
import pkg_resources
import setuptools.package_index import setuptools.package_index
from setuptools.tests.server import IndexServer
from .textwrap import DALS from .textwrap import DALS
...@@ -114,43 +113,6 @@ class TestPackageIndex: ...@@ -114,43 +113,6 @@ class TestPackageIndex:
url = 'file:///tmp/test_package_index' url = 'file:///tmp/test_package_index'
assert index.url_ok(url, True) assert index.url_ok(url, True)
def test_links_priority(self):
"""
Download links from the pypi simple index should be used before
external download links.
https://bitbucket.org/tarek/distribute/issue/163
Usecase :
- someone uploads a package on pypi, a md5 is generated
- someone manually copies this link (with the md5 in the url) onto an
external page accessible from the package page.
- someone reuploads the package (with a different md5)
- while easy_installing, an MD5 error occurs because the external link
is used
-> Setuptools should use the link from pypi, not the external one.
"""
if sys.platform.startswith('java'):
# Skip this test on jython because binding to :0 fails
return
# start an index server
server = IndexServer()
server.start()
index_url = server.base_url() + 'test_links_priority/simple/'
# scan a test index
pi = setuptools.package_index.PackageIndex(index_url)
requirement = pkg_resources.Requirement.parse('foobar')
pi.find_packages(requirement)
server.stop()
# the distribution has been found
assert 'foobar' in pi
# we have only one link, because links are compared without md5
assert len(pi['foobar']) == 1
# the link should be from the index
assert 'correct_md5' in pi['foobar'][0].location
def test_parse_bdist_wininst(self): def test_parse_bdist_wininst(self):
parse = setuptools.package_index.parse_bdist_wininst parse = setuptools.package_index.parse_bdist_wininst
...@@ -221,11 +183,11 @@ class TestPackageIndex: ...@@ -221,11 +183,11 @@ class TestPackageIndex:
('+ubuntu_0', '+ubuntu.0'), ('+ubuntu_0', '+ubuntu.0'),
] ]
versions = [ versions = [
[''.join([e, r, p, l]) for l in ll] [''.join([e, r, p, loc]) for loc in locs]
for e in epoch for e in epoch
for r in releases for r in releases
for p in sum([pre, post, dev], ['']) for p in sum([pre, post, dev], [''])
for ll in local] for locs in local]
for v, vc in versions: for v, vc in versions:
dists = list(setuptools.package_index.distros_for_url( dists = list(setuptools.package_index.distros_for_url(
'http://example.com/example.zip#egg=example-' + v)) 'http://example.com/example.zip#egg=example-' + v))
...@@ -322,12 +284,22 @@ class TestContentCheckers: ...@@ -322,12 +284,22 @@ class TestContentCheckers:
assert rep == 'My message about md5' assert rep == 'My message about md5'
@pytest.fixture
def temp_home(tmpdir, monkeypatch):
key = (
'USERPROFILE'
if platform.system() == 'Windows' and sys.version_info > (3, 8) else
'HOME'
)
monkeypatch.setitem(os.environ, key, str(tmpdir))
return tmpdir
class TestPyPIConfig: class TestPyPIConfig:
def test_percent_in_password(self, tmpdir, monkeypatch): def test_percent_in_password(self, temp_home):
monkeypatch.setitem(os.environ, 'HOME', str(tmpdir)) pypirc = temp_home / '.pypirc'
pypirc = tmpdir / '.pypirc' pypirc.write(DALS("""
with pypirc.open('w') as strm:
strm.write(DALS("""
[pypi] [pypi]
repository=https://pypi.org repository=https://pypi.org
username=jaraco username=jaraco
......
...@@ -10,6 +10,7 @@ import pytest ...@@ -10,6 +10,7 @@ import pytest
from setuptools.command.test import test from setuptools.command.test import test
from setuptools.dist import Distribution from setuptools.dist import Distribution
from setuptools.tests import ack_2to3
from .textwrap import DALS from .textwrap import DALS
...@@ -73,9 +74,6 @@ def quiet_log(): ...@@ -73,9 +74,6 @@ def quiet_log():
log.set_verbosity(0) log.set_verbosity(0)
ack_2to3 = pytest.mark.filterwarnings('ignore:2to3 support is deprecated')
@pytest.mark.usefixtures('sample_test', 'quiet_log') @pytest.mark.usefixtures('sample_test', 'quiet_log')
@ack_2to3 @ack_2to3
def test_test(capfd): def test_test(capfd):
......
...@@ -57,10 +57,7 @@ def test_clean_env_install(bare_virtualenv): ...@@ -57,10 +57,7 @@ def test_clean_env_install(bare_virtualenv):
""" """
Check setuptools can be installed in a clean environment. Check setuptools can be installed in a clean environment.
""" """
bare_virtualenv.run(' && '.join(( bare_virtualenv.run(['python', 'setup.py', 'install'], cd=SOURCE_DIR)
'cd {source}',
'python setup.py install',
)).format(source=SOURCE_DIR))
def _get_pip_versions(): def _get_pip_versions():
...@@ -115,10 +112,9 @@ def test_pip_upgrade_from_source(pip_version, virtualenv): ...@@ -115,10 +112,9 @@ def test_pip_upgrade_from_source(pip_version, virtualenv):
dist_dir = virtualenv.workspace dist_dir = virtualenv.workspace
# Generate source distribution / wheel. # Generate source distribution / wheel.
virtualenv.run(' && '.join(( virtualenv.run(' && '.join((
'cd {source}',
'python setup.py -q sdist -d {dist}', 'python setup.py -q sdist -d {dist}',
'python setup.py -q bdist_wheel -d {dist}', 'python setup.py -q bdist_wheel -d {dist}',
)).format(source=SOURCE_DIR, dist=dist_dir)) )).format(dist=dist_dir), cd=SOURCE_DIR)
sdist = glob.glob(os.path.join(dist_dir, '*.zip'))[0] sdist = glob.glob(os.path.join(dist_dir, '*.zip'))[0]
wheel = glob.glob(os.path.join(dist_dir, '*.whl'))[0] wheel = glob.glob(os.path.join(dist_dir, '*.whl'))[0]
# Then update from wheel. # Then update from wheel.
...@@ -183,10 +179,8 @@ def _check_test_command_install_requirements(virtualenv, tmpdir): ...@@ -183,10 +179,8 @@ def _check_test_command_install_requirements(virtualenv, tmpdir):
open('success', 'w').close() open('success', 'w').close()
''')) '''))
# Run test command for test package. # Run test command for test package.
virtualenv.run(' && '.join(( virtualenv.run(
'cd {tmpdir}', ['python', 'setup.py', 'test', '-s', 'test'], cd=str(tmpdir))
'python setup.py test -s test',
)).format(tmpdir=tmpdir))
assert tmpdir.join('success').check() assert tmpdir.join('success').check()
...@@ -207,7 +201,5 @@ def test_no_missing_dependencies(bare_virtualenv): ...@@ -207,7 +201,5 @@ def test_no_missing_dependencies(bare_virtualenv):
Quick and dirty test to ensure all external dependencies are vendored. Quick and dirty test to ensure all external dependencies are vendored.
""" """
for command in ('upload',): # sorted(distutils.command.__all__): for command in ('upload',): # sorted(distutils.command.__all__):
bare_virtualenv.run(' && '.join(( bare_virtualenv.run(
'cd {source}', ['python', 'setup.py', command, '-h'], cd=SOURCE_DIR)
'python setup.py {command} -h',
)).format(command=command, source=SOURCE_DIR))
...@@ -60,8 +60,22 @@ def ensure_config(): ...@@ -60,8 +60,22 @@ def ensure_config():
subprocess.check_output(['git', 'config', 'user.email']) subprocess.check_output(['git', 'config', 'user.email'])
def check_changes():
"""
Verify that all of the files in changelog.d have the appropriate
names.
"""
allowed = 'deprecation', 'breaking', 'change', 'doc', 'misc'
assert all(
any(key in file.name for key in allowed)
for file in pathlib.Path('changelog.d').iterdir()
if file.name != '.gitignore'
)
if __name__ == '__main__': if __name__ == '__main__':
print("Cutting release at", get_version()) print("Cutting release at", get_version())
ensure_config() ensure_config()
check_changes()
update_changelog() update_changelog()
bump_version() bump_version()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment