Imported Upstream version 40.0.0 upstream/40.0.0
authorDongHun Kwak <dh0128.kwak@samsung.com>
Mon, 14 Jan 2019 01:42:43 +0000 (10:42 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Mon, 14 Jan 2019 01:42:43 +0000 (10:42 +0900)
48 files changed:
CHANGES.rst
README.rst
changelog.d/1364.rst [deleted file]
conftest.py
docs/developer-guide.txt
docs/easy_install.txt
docs/history.txt
docs/releases.txt
docs/roadmap.txt
docs/setuptools.txt
pkg_resources/__init__.py
pkg_resources/extern/__init__.py
pkg_resources/py31compat.py
pkg_resources/tests/test_pkg_resources.py
pkg_resources/tests/test_resources.py
pkg_resources/tests/test_working_set.py
pyproject.toml
pytest.ini
setup.cfg
setup.py
setuptools/__init__.py
setuptools/command/bdist_egg.py
setuptools/command/build_ext.py
setuptools/command/develop.py
setuptools/command/easy_install.py
setuptools/command/test.py
setuptools/config.py
setuptools/extern/__init__.py
setuptools/monkey.py
setuptools/package_index.py
setuptools/pep425tags.py
setuptools/py31compat.py
setuptools/py33compat.py
setuptools/script (dev).tmpl
setuptools/site-patch.py
setuptools/tests/test_build_meta.py
setuptools/tests/test_easy_install.py
setuptools/tests/test_egg_info.py
setuptools/tests/test_glibc.py
setuptools/tests/test_install_scripts.py
setuptools/tests/test_manifest.py
setuptools/tests/test_pep425tags.py
setuptools/tests/test_wheel.py
setuptools/wheel.py
tests/manual_test.py
tests/requirements.txt
tests/test_pypi.py [deleted file]
tox.ini

index d3d661cc3ebebc95fc33e963a2c34216e952e292..2f96af99c57650b223b71935d37083fc9c9dae85 100644 (file)
@@ -1,3 +1,14 @@
+v40.0.0
+-------
+* #1342: Drop support for Python 3.3.
+* #1366: In package_index, fixed handling of encoded entities in URLs.
+* #1383: In pkg_resources VendorImporter, avoid removing packages imported from the root.
+* #1379: Minor doc fixes after actually using the new release process.
+* #1385: Removed section on non-package data files.
+* #1403: Fix developer's guide.
+* #1404: Fix PEP 518 configuration: set build requirements in ``pyproject.toml`` to ``["wheel"]``.
+
+
 v39.2.0
 -------
 
@@ -5,6 +16,8 @@ v39.2.0
   a text file.
 * #1360: Fixed issue with a mismatch between the name of the package and the
   name of the .dist-info file in wheel files
+* #1364: Add `__dir__()` implementation to `pkg_resources.Distribution()` that
+  includes the attributes in the `_provider` instance variable.
 * #1365: Take the package_dir option into account when loading the version from
   a module attribute.
 * #1353: Added coverage badge to README.
@@ -17,7 +30,7 @@ v39.2.0
   after any ``distutils`` ``setup_keywords`` calls, allowing them to override
   values.
 * #1352: Added ``tox`` environment for documentation builds.
-* #1354: Added ``towncrier`` for changelog managment.
+* #1354: Added ``towncrier`` for changelog management.
 * #1355: Add PR template.
 * #1368: Fixed tests which failed without network connectivity.
 * #1369: Added unit tests for PEP 425 compatibility tags support.
index 2c008cc6e386d70ac7d5f7645fbb08439e8100d8..8505c5517f0b6fad5e010610fc437a33061308c7 100755 (executable)
@@ -20,7 +20,9 @@ See the `Installation Instructions
 User's Guide for instructions on installing, upgrading, and uninstalling
 Setuptools.
 
-The project is `maintained at GitHub <https://github.com/pypa/setuptools>`_.
+The project is `maintained at GitHub <https://github.com/pypa/setuptools>`_
+by the `Setuptools Developers
+<https://github.com/orgs/pypa/teams/setuptools-developers>`_.
 
 Questions and comments should be directed to the `distutils-sig
 mailing list <http://mail.python.org/pipermail/distutils-sig/>`_.
diff --git a/changelog.d/1364.rst b/changelog.d/1364.rst
deleted file mode 100644 (file)
index f7b4c01..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Add `__dir__()` implementation to `pkg_resources.Distribution()` that includes the attributes in the `_provider` instance variable.
\ No newline at end of file
index 3cccfe1abde5221cce396161441a5b2255b1614d..0d7b274c07823d280898db9d03d33d85573ba396 100644 (file)
@@ -1,3 +1,6 @@
+import sys
+
+
 pytest_plugins = 'setuptools.tests.fixtures'
 
 
@@ -6,3 +9,17 @@ def pytest_addoption(parser):
         "--package_name", action="append", default=[],
         help="list of package_name to pass to test functions",
     )
+
+
+collect_ignore = [
+    'tests/manual_test.py',
+    'setuptools/tests/mod_with_constant.py',
+]
+
+
+if sys.version_info < (3,):
+    collect_ignore.append('setuptools/lib2to3_ex.py')
+
+
+if sys.version_info < (3, 6):
+    collect_ignore.append('pavement.py')
index 6b04603b16c3c807d844f94ef83fb93584cd5609..c011491a30c8211078f1369d3e1c585d53ab23fb 100644 (file)
@@ -66,7 +66,7 @@ and a reference to any issue tickets that the PR is intended to solve.
 All PRs with code changes should include tests. All changes should include a
 changelog entry.
 
-``setuptools`` uses `towncrier <https://town-crier.readthedocs.io/en/latest/>`_
+``setuptools`` uses `towncrier <https://pypi.org/project/towncrier/>`_
 for changelog managment, so when making a PR, please add a news fragment in the
 ``changelog.d/`` folder. Changelog files are written in Restructured Text and
 should be a 1 or 2 sentence description of the substantive changes in the PR.
@@ -89,31 +89,6 @@ code changes. See the following for an example news fragment:
     $ cat changelog.d/1288.change.rst
     Add support for maintainer in PKG-INFO
 
------------
-Source Code
------------
-
-Grab the code at Github::
-
-    $ git clone https://github.com/pypa/setuptools
-
-If you want to contribute changes, we recommend you fork the repository on
-Github, commit the changes to your repository, and then make a pull request
-on Github. If you make some changes, don't forget to:
-
-- add a note in CHANGES.rst
-
-Please commit all changes in the 'master' branch against the latest available
-commit or for bug-fixes, against an earlier commit or release in which the
-bug occurred.
-
-If you find yourself working on more than one issue at a time, Setuptools
-generally prefers Git-style branches, so use Mercurial bookmarks or Git
-branches or multiple forks to maintain separate efforts.
-
-The Continuous Integration tests that validate every release are run
-from this repository.
-
 -------
 Testing
 -------
index 5c992343611386b10c1335c73d93cf32c515d4b1..f426b6ffd5bb6dd8ee5dd1cebf74997f2ff7c3ca 100644 (file)
@@ -35,7 +35,7 @@ Please see the `setuptools PyPI page <https://pypi.org/project/setuptools/>`_
 for download links and basic installation instructions for each of the
 supported platforms.
 
-You will need at least Python 3.3 or 2.7.  An ``easy_install`` script will be
+You will need at least Python 3.4 or 2.7.  An ``easy_install`` script will be
 installed in the normal location for Python scripts on your platform.
 
 Note that the instructions on the setuptools PyPI page assume that you are
index 8fd1dc6538884b9eb13b9ec5d33b60d4b64d843f..385cfa7eda507c19fe7a2b3e52a79bf0e71c7696 100644 (file)
@@ -40,7 +40,6 @@ Credits
   re-invigorated the community on the project, encouraged renewed innovation,
   and addressed many defects.
 
-* Since the merge with Distribute, Jason R. Coombs is the
-  maintainer of setuptools. The project is maintained in coordination with
-  the Python Packaging Authority (PyPA) and the larger Python community.
-
+* Jason R. Coombs performed the merge with Distribute, maintaining the
+  project for several years in coordination with the Python Packaging
+  Authority (PyPA).
index 234f69eeb9ec8f217a048e912786bdffd627aae6..98ba39e88d1089b12ddf830d13722e4b2be5f06e 100644 (file)
@@ -19,9 +19,13 @@ To update the changelog:
    ``git add`` for any modified files.
 3. Run ``towncrier --version {new.version.number}`` to stage the changelog
    updates in git.
+4. Verify that there are no remaining ``changelog.d/*.rst`` files.  If a
+   file was named incorrectly, it may be ignored by towncrier.
+5. Review the updated ``CHANGES.rst`` file.  If any changes are needed,
+   make the edits and stage them via ``git add CHANGES.rst``.
 
 Once the changelog edits are staged and ready to commit, cut a release by
-installing and running ``bump2version {part}`` where ``part``
+installing and running ``bump2version --allow-dirty {part}`` where ``part``
 is major, minor, or patch based on the scope of the changes in the
 release. Then, push the commits to the master branch::
 
index 8f175b9f7516555fd9a16150634dc300700b0f40..9bde49360aca547a8553a3c8e901e223217c4f5d 100644 (file)
@@ -2,5 +2,9 @@
 Roadmap
 =======
 
-Setuptools is primarily in maintenance mode. The project attempts to address
-user issues, concerns, and feature requests in a timely fashion.
+Setuptools has the following large-scale goals on the roadmap:
+
+- Harmonize declarative config with pyproject.toml syntax.
+- Deprecate and remove setup_requires and easy_install in
+  favor of PEP 518 build requirements and pip install.
+- Adopt the Distutils package and stop monkeypatching stdlib.
index f7b9351b78db9dd6612dcc60bca4a0a6b007db92..c82dc51133f9e7ce43b2a926419c2b218afb8ff0 100644 (file)
@@ -970,35 +970,14 @@ a quick example of converting code that uses ``__file__`` to use
 Non-Package Data Files
 ----------------------
 
-The ``distutils`` normally install general "data files" to a platform-specific
-location (e.g. ``/usr/share``).  This feature intended to be used for things
-like documentation, example configuration files, and the like.  ``setuptools``
-does not install these data files in a separate location, however.  They are
-bundled inside the egg file or directory, alongside the Python modules and
-packages.  The data files can also be accessed using the :ref:`ResourceManager
-API`, by specifying a ``Requirement`` instead of a package name::
-
-    from pkg_resources import Requirement, resource_filename
-    filename = resource_filename(Requirement.parse("MyProject"),"sample.conf")
-
-The above code will obtain the filename of the "sample.conf" file in the data
-root of the "MyProject" distribution.
-
-Note, by the way, that this encapsulation of data files means that you can't
-actually install data files to some arbitrary location on a user's machine;
-this is a feature, not a bug.  You can always include a script in your
-distribution that extracts and copies your the documentation or data files to
-a user-specified location, at their discretion.  If you put related data files
-in a single directory, you can use ``resource_filename()`` with the directory
-name to get a filesystem directory that then can be copied with the ``shutil``
-module.  (Even if your package is installed as a zipfile, calling
-``resource_filename()`` on a directory will return an actual filesystem
-directory, whose contents will be that entire subtree of your distribution.)
-
-(Of course, if you're writing a new package, you can just as easily place your
-data files or directories inside one of your packages, rather than using the
-distutils' approach.  However, if you're updating an existing application, it
-may be simpler not to change the way it currently specifies these data files.)
+Historically, ``setuptools`` by way of ``easy_install`` would encapsulate data
+files from the distribution into the egg (see `the old docs
+<https://github.com/pypa/setuptools/blob/52aacd5b276fedd6849c3a648a0014f5da563e93/docs/setuptools.txt#L970-L1001>`_). As eggs are deprecated and pip-based installs
+fall back to the platform-specific location for installing data files, there is
+no supported facility to reliably retrieve these resources.
+
+Instead, the PyPA recommends that any data files you wish to be accessible at
+run time be included in the package.
 
 
 Automatic Resource Extraction
index 4e4409b32b151e4f30a672ca5ff559d4d3640e69..6701540819530af3fa119b474ece725ec02a3343 100644 (file)
@@ -78,8 +78,11 @@ __import__('pkg_resources.extern.packaging.requirements')
 __import__('pkg_resources.extern.packaging.markers')
 
 
-if (3, 0) < sys.version_info < (3, 3):
-    raise RuntimeError("Python 3.3 or later is required")
+__metaclass__ = type
+
+
+if (3, 0) < sys.version_info < (3, 4):
+    raise RuntimeError("Python 3.4 or later is required")
 
 if six.PY2:
     # Those builtin exceptions are only defined in Python 3
@@ -537,7 +540,7 @@ class IResourceProvider(IMetadataProvider):
         """List of resource names in the directory (like ``os.listdir()``)"""
 
 
-class WorkingSet(object):
+class WorkingSet:
     """A collection of active distributions on sys.path (or a similar list)"""
 
     def __init__(self, entries=None):
@@ -944,7 +947,7 @@ class _ReqExtras(dict):
         return not req.marker or any(extra_evals)
 
 
-class Environment(object):
+class Environment:
     """Searchable snapshot of distributions on a search path"""
 
     def __init__(
@@ -959,7 +962,7 @@ class Environment(object):
         `platform` is an optional string specifying the name of the platform
         that platform-specific distributions must be compatible with.  If
         unspecified, it defaults to the current platform.  `python` is an
-        optional string naming the desired version of Python (e.g. ``'3.3'``);
+        optional string naming the desired version of Python (e.g. ``'3.6'``);
         it defaults to the current version.
 
         You may explicitly set `platform` (and/or `python`) to ``None`` if you
@@ -2279,7 +2282,7 @@ EGG_NAME = re.compile(
 ).match
 
 
-class EntryPoint(object):
+class EntryPoint:
     """Object representing an advertised importable object"""
 
     def __init__(self, name, module_name, attrs=(), extras=(), dist=None):
@@ -2433,7 +2436,7 @@ def _version_from_file(lines):
     return safe_version(value.strip()) or None
 
 
-class Distribution(object):
+class Distribution:
     """Wrap an actual or potential sys.path entry w/metadata"""
     PKG_INFO = 'PKG-INFO'
 
index b4156fec2021c9057665df4464a58a1faa836723..c1eb9e998f8e117c82c176bc83ab1d350c729cd7 100644 (file)
@@ -48,7 +48,7 @@ class VendorImporter:
                 # on later Python versions to cause relative imports
                 # in the vendor package to resolve the same modules
                 # as those going through this importer.
-                if sys.version_info > (3, 3):
+                if prefix and sys.version_info > (3, 3):
                     del sys.modules[extant]
                 return mod
             except ImportError:
index 331a51bb0fb208f4049d3a404e55f5fef517b63c..fd4b6fd08811b4b23dd814ec5f858689f89a7a18 100644 (file)
@@ -15,8 +15,7 @@ def _makedirs_31(path, exist_ok=False):
 #  and exists_ok considerations are disentangled.
 # See https://github.com/pypa/setuptools/pull/1083#issuecomment-315168663
 needs_makedirs = (
-    sys.version_info < (3, 2, 5) or
-    (3, 3) <= sys.version_info < (3, 3, 6) or
+    sys.version_info.major == 2 or
     (3, 4) <= sys.version_info < (3, 4, 1)
 )
 makedirs = _makedirs_31 if needs_makedirs else os.makedirs
index 7442b79f741ff7ce6e0af8080dcfe6938329c3c9..4e2cac94591309e24887b4d8a2c7fde7ea2beea1 100644 (file)
@@ -13,15 +13,13 @@ import distutils.dist
 import distutils.command.install_egg_info
 
 from pkg_resources.extern.six.moves import map
+from pkg_resources.extern.six import text_type, string_types
 
 import pytest
 
 import pkg_resources
 
-try:
-    unicode
-except NameError:
-    unicode = str
+__metaclass__ = type
 
 
 def timestamp(dt):
@@ -35,7 +33,7 @@ def timestamp(dt):
         return time.mktime(dt.timetuple())
 
 
-class EggRemover(unicode):
+class EggRemover(text_type):
     def __call__(self):
         if self in sys.path:
             sys.path.remove(self)
@@ -43,7 +41,7 @@ class EggRemover(unicode):
             os.remove(self)
 
 
-class TestZipProvider(object):
+class TestZipProvider:
     finalizers = []
 
     ref_time = datetime.datetime(2013, 5, 12, 13, 25, 0)
@@ -132,13 +130,13 @@ class TestZipProvider(object):
         manager.cleanup_resources()
 
 
-class TestResourceManager(object):
+class TestResourceManager:
     def test_get_cache_path(self):
         mgr = pkg_resources.ResourceManager()
         path = mgr.get_cache_path('foo')
         type_ = str(type(path))
         message = "Unexpected type from get_cache_path: " + type_
-        assert isinstance(path, (unicode, str)), message
+        assert isinstance(path, string_types), message
 
 
 class TestIndependence:
@@ -163,7 +161,7 @@ class TestIndependence:
         subprocess.check_call(cmd)
 
 
-class TestDeepVersionLookupDistutils(object):
+class TestDeepVersionLookupDistutils:
     @pytest.fixture
     def env(self, tmpdir):
         """
index 04d02c1f61817a32aa8f65a8487f1dd1bfc3623b..171ba2f96f9f3af6bda393879c4e8ddf551589cc 100644 (file)
@@ -668,7 +668,7 @@ class TestParsing:
         assert (
             Requirement.parse("name==1.1;python_version=='2.7'")
             !=
-            Requirement.parse("name==1.1;python_version=='3.3'")
+            Requirement.parse("name==1.1;python_version=='3.6'")
         )
         assert (
             Requirement.parse("name==1.0;python_version=='2.7'")
@@ -676,9 +676,9 @@ class TestParsing:
             Requirement.parse("name==1.2;python_version=='2.7'")
         )
         assert (
-            Requirement.parse("name[foo]==1.0;python_version=='3.3'")
+            Requirement.parse("name[foo]==1.0;python_version=='3.6'")
             !=
-            Requirement.parse("name[foo,bar]==1.0;python_version=='3.3'")
+            Requirement.parse("name[foo,bar]==1.0;python_version=='3.6'")
         )
 
     def test_local_version(self):
index 42ddcc86f28efcccd012cac0e7ff45443845eb48..b3ca4ea8e4c662150eec22ce45976f6fa2db2519 100644 (file)
@@ -9,6 +9,8 @@ import pkg_resources
 
 from .test_resources import Metadata
 
+__metaclass__ = type
+
 
 def strip_comments(s):
     return '\n'.join(
@@ -37,7 +39,7 @@ def parse_distributions(s):
           requires=['foo>=3.0', 'baz; extra=="feature"']
     '''
     s = s.strip()
-    for spec in re.split('\n(?=[^\s])', s):
+    for spec in re.split(r'\n(?=[^\s])', s):
         if not spec:
             continue
         fields = spec.split('\n', 1)
@@ -54,7 +56,7 @@ def parse_distributions(s):
         yield dist
 
 
-class FakeInstaller(object):
+class FakeInstaller:
 
     def __init__(self, installable_dists):
         self._installable_dists = installable_dists
@@ -87,7 +89,7 @@ def parametrize_test_working_set_resolve(*test_list):
         ):
             idlist.append(id_)
             expected = strip_comments(expected.strip())
-            if re.match('\w+$', expected):
+            if re.match(r'\w+$', expected):
                 expected = getattr(pkg_resources, expected)
                 assert issubclass(expected, Exception)
             else:
index cffd0e9afd96746ff3cb3b1ae27ba3d632d65e8b..07c23bb5f5cfa63dff16e813dbd2b06f903c2803 100644 (file)
@@ -1,3 +1,6 @@
+[build-system]
+requires = ["wheel"]
+
 [tool.towncrier]
     package = "setuptools"
     package_dir = "setuptools"
index 16fdc5af871a77634e08ab3995dfe4d095b2e56b..1c5b6b0934b042c6bcb2483a9f50fcf094362b8f 100755 (executable)
@@ -1,6 +1,7 @@
 [pytest]
-addopts=--doctest-modules --ignore release.py --ignore setuptools/lib2to3_ex.py --ignore tests/manual_test.py --ignore tests/test_pypi.py --ignore tests/shlib_test --doctest-glob=pkg_resources/api_tests.txt --ignore scripts/upload-old-releases-as-zip.py --ignore pavement.py --ignore setuptools/tests/mod_with_constant.py -rsxX
+addopts=--doctest-modules --doctest-glob=pkg_resources/api_tests.txt -rsxX
 norecursedirs=dist build *.egg setuptools/extern pkg_resources/extern .*
 flake8-ignore =
     setuptools/site-patch.py F821
     setuptools/py*compat.py F811
+doctest_optionflags=ELLIPSIS ALLOW_UNICODE
index e23ee6f041999d13268390526ee73e41ec87105e..2caeca9b76b4709cf613355f412787bca6b5bd33 100755 (executable)
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,5 +1,5 @@
 [bumpversion]
-current_version = 39.2.0
+current_version = 40.0.0
 commit = True
 tag = True
 
index b122df82f3289932a107df7b8045f113db803221..27a0e30e02abc78770cfce30a0d40ae5c9db9d0a 100755 (executable)
--- a/setup.py
+++ b/setup.py
@@ -89,7 +89,7 @@ def pypi_link(pkg_filename):
 
 setup_params = dict(
     name="setuptools",
-    version="39.2.0",
+    version="40.0.0",
     description=(
         "Easily download, build, install, upgrade, and uninstall "
         "Python packages"
@@ -161,7 +161,6 @@ setup_params = dict(
         Programming Language :: Python :: 2
         Programming Language :: Python :: 2.7
         Programming Language :: Python :: 3
-        Programming Language :: Python :: 3.3
         Programming Language :: Python :: 3.4
         Programming Language :: Python :: 3.5
         Programming Language :: Python :: 3.6
@@ -170,7 +169,7 @@ setup_params = dict(
         Topic :: System :: Systems Administration
         Topic :: Utilities
         """).strip().splitlines(),
-    python_requires='>=2.7,!=3.0.*,!=3.1.*,!=3.2.*',
+    python_requires='>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*',
     extras_require={
         "ssl:sys_platform=='win32'": "wincertstore==0.2",
         "certs": "certifi==2016.9.26",
index 7da47fbed5e5fa614f814c038b400360439144a5..ce55ec351d0e50e7ee67f1b6cb1fa39f1075af8a 100644 (file)
@@ -15,6 +15,8 @@ from setuptools.dist import Distribution, Feature
 from setuptools.depends import Require
 from . import monkey
 
+__metaclass__ = type
+
 __all__ = [
     'setup', 'Distribution', 'Feature', 'Command', 'Extension', 'Require',
     'find_packages',
@@ -31,7 +33,7 @@ run_2to3_on_doctests = True
 lib2to3_fixer_packages = ['lib2to3.fixes']
 
 
-class PackageFinder(object):
+class PackageFinder:
     """
     Generate a list of all Python packages found within a directory
     """
index 423b8187656c2274c52010d8fd3a25236b65120f..14530729b989aeea57b508fc3a50a38508decba7 100644 (file)
@@ -411,7 +411,7 @@ def scan_module(egg_dir, base, name, stubs):
         return True  # Extension module
     pkg = base[len(egg_dir) + 1:].replace(os.sep, '.')
     module = pkg + (pkg and '.' or '') + os.path.splitext(name)[0]
-    if sys.version_info < (3, 3):
+    if sys.version_info.major == 2:
         skip = 8  # skip magic & date
     elif sys.version_info < (3, 7):
         skip = 12  # skip magic & date & file size
index ea97b37b2c4dd97a1abc49ef9e33d322617c1895..60a8a32f08ce78e0881b2f64df1b98abd92120f1 100644 (file)
@@ -112,7 +112,7 @@ class build_ext(_build_ext):
                 and get_abi3_suffix()
             )
             if use_abi3:
-                so_ext = _get_config_var_837('EXT_SUFFIX')
+                so_ext = get_config_var('EXT_SUFFIX')
                 filename = filename[:-len(so_ext)]
                 filename = filename + get_abi3_suffix()
             if isinstance(ext, Library):
@@ -319,13 +319,3 @@ else:
         self.create_static_lib(
             objects, basename, output_dir, debug, target_lang
         )
-
-
-def _get_config_var_837(name):
-    """
-    In https://github.com/pypa/setuptools/pull/837, we discovered
-    Python 3.3.0 exposes the extension suffix under the name 'SO'.
-    """
-    if sys.version_info < (3, 3, 1):
-        name = 'SO'
-    return get_config_var(name)
index 959c932a5c0c3a94463e3547c05ba26958ae5b96..fdc9fc432b539cfe0274a6691d84aa16eaaa0a8c 100755 (executable)
@@ -12,6 +12,8 @@ from setuptools.command.easy_install import easy_install
 from setuptools import namespaces
 import setuptools
 
+__metaclass__ = type
+
 
 class develop(namespaces.DevelopInstaller, easy_install):
     """Set up package for development"""
@@ -192,7 +194,7 @@ class develop(namespaces.DevelopInstaller, easy_install):
         return easy_install.install_wrapper_scripts(self, dist)
 
 
-class VersionlessRequirement(object):
+class VersionlessRequirement:
     """
     Adapt a pkg_resources.Distribution to simply return the project
     name as the 'requirement' so that scripts will work across
index 85ee40f1d5cfbcdc7faeeffdea0ab6db76aee6fe..05508cebe1cc8a90c6ad91c1b1fcdb883656f7e8 100755 (executable)
@@ -40,12 +40,13 @@ import subprocess
 import shlex
 import io
 
+from sysconfig import get_config_vars, get_path
+
 from setuptools.extern import six
 from setuptools.extern.six.moves import configparser, map
 
 from setuptools import Command
 from setuptools.sandbox import run_setup
-from setuptools.py31compat import get_path, get_config_vars
 from setuptools.py27compat import rmtree_safe
 from setuptools.command import setopt
 from setuptools.archive_util import unpack_archive
@@ -62,6 +63,8 @@ from pkg_resources import (
 )
 import pkg_resources.py31compat
 
+__metaclass__ = type
+
 # Turn on PEP440Warnings
 warnings.filterwarnings("default", category=pkg_resources.PEP440Warning)
 
@@ -2049,7 +2052,7 @@ class WindowsCommandSpec(CommandSpec):
     split_args = dict(posix=False)
 
 
-class ScriptWriter(object):
+class ScriptWriter:
     """
     Encapsulates behavior around writing entry point scripts for console and
     gui apps.
index 51aee1f7b18d12c35a0a09533aaf54745aabbcd9..dde0118c905bf32313e11c21b827767390d5beb6 100644 (file)
@@ -16,6 +16,8 @@ from pkg_resources import (resource_listdir, resource_exists, normalize_path,
                            add_activation_listener, require, EntryPoint)
 from setuptools import Command
 
+__metaclass__ = type
+
 
 class ScanningLoader(TestLoader):
 
@@ -58,7 +60,7 @@ class ScanningLoader(TestLoader):
 
 
 # adapted from jaraco.classes.properties:NonDataProperty
-class NonDataProperty(object):
+class NonDataProperty:
     def __init__(self, fget):
         self.fget = fget
 
index d3f0b123d563d2e4a70f287745563796b2035aab..5f908cf12972c4c6f52603e88ec698e448ba9ad0 100644 (file)
@@ -11,6 +11,9 @@ from setuptools.extern.packaging.version import LegacyVersion, parse
 from setuptools.extern.six import string_types
 
 
+__metaclass__ = type
+
+
 def read_configuration(
         filepath, find_others=False, ignore_option_errors=False):
     """Read given configuration file and returns options from it as a dict.
@@ -113,7 +116,7 @@ def parse_configuration(
     return meta, options
 
 
-class ConfigHandler(object):
+class ConfigHandler:
     """Handles metadata supplied in configuration files."""
 
     section_prefix = None
index da3d668d997b4a6387d747639b749151207b3ccc..52785a0328182bc20cdbe8dd1be18ba7b2651aec 100644 (file)
@@ -48,7 +48,7 @@ class VendorImporter:
                 # on later Python versions to cause relative imports
                 # in the vendor package to resolve the same modules
                 # as those going through this importer.
-                if sys.version_info > (3, 3):
+                if sys.version_info.major >= 3:
                     del sys.modules[extant]
                 return mod
             except ImportError:
index 08ed50d9ecd06de0136bad14a45e08624ba77f01..05a738b055c04653d18344de901d260c1dbb75a8 100644 (file)
@@ -75,8 +75,6 @@ def patch_all():
     needs_warehouse = (
         sys.version_info < (2, 7, 13)
         or
-        (3, 0) < sys.version_info < (3, 3, 7)
-        or
         (3, 4) < sys.version_info < (3, 4, 6)
         or
         (3, 5) < sys.version_info <= (3, 5, 3)
index b6407be304f9d18b562b30d5bf43d13b6127a68f..cda54b71713d058acbea929dc60c7d249d08b54d 100755 (executable)
@@ -26,12 +26,13 @@ from setuptools.py27compat import get_all_headers
 from setuptools.py33compat import unescape
 from setuptools.wheel import Wheel
 
+__metaclass__ = type
+
 EGG_FRAGMENT = re.compile(r'^egg=([-A-Za-z0-9_.+!]+)$')
-HREF = re.compile("""href\\s*=\\s*['"]?([^'"> ]+)""", re.I)
-# this is here to fix emacs' cruddy broken syntax highlighting
+HREF = re.compile(r"""href\s*=\s*['"]?([^'"> ]+)""", re.I)
 PYPI_MD5 = re.compile(
-    '<a href="([^"#]+)">([^<]+)</a>\n\\s+\\(<a (?:title="MD5 hash"\n\\s+)'
-    'href="[^?]+\\?:action=show_md5&amp;digest=([0-9a-f]{32})">md5</a>\\)'
+    r'<a href="([^"#]+)">([^<]+)</a>\n\s+\(<a (?:title="MD5 hash"\n\s+)'
+    r'href="[^?]+\?:action=show_md5&amp;digest=([0-9a-f]{32})">md5</a>\)'
 )
 URL_SCHEME = re.compile('([-+.a-z0-9]{2,}):', re.I).match
 EXTENSIONS = ".tar.gz .tar.bz2 .tar .zip .tgz".split()
@@ -235,7 +236,7 @@ def find_external_links(url, page):
                 yield urllib.parse.urljoin(url, htmldecode(match.group(1)))
 
 
-class ContentChecker(object):
+class ContentChecker:
     """
     A null content checker that defines the interface for checking content
     """
@@ -933,12 +934,19 @@ entity_sub = re.compile(r'&(#(\d+|x[\da-fA-F]+)|[\w.:-]+);?').sub
 
 
 def decode_entity(match):
-    what = match.group(1)
+    what = match.group(0)
     return unescape(what)
 
 
 def htmldecode(text):
-    """Decode HTML entities in the given text."""
+    """
+    Decode HTML entities in the given text.
+
+    >>> htmldecode(
+    ...     'https://../package_name-0.1.2.tar.gz'
+    ...     '?tokena=A&amp;tokenb=B">package_name-0.1.2.tar.gz')
+    'https://../package_name-0.1.2.tar.gz?tokena=A&tokenb=B">package_name-0.1.2.tar.gz'
+    """
     return entity_sub(decode_entity, text)
 
 
@@ -980,7 +988,7 @@ def _encode_auth(auth):
     return encoded.replace('\n', '')
 
 
-class Credential(object):
+class Credential:
     """
     A username/password pair. Use like a namedtuple.
     """
index 3bdd3285a5b4bd0ba32a2b09bf9d6b54ad784168..a86a0d183e1519988bc685ce7c3ee34042b51a64 100644 (file)
@@ -97,8 +97,8 @@ def get_abi_tag():
                     lambda: sys.maxunicode == 0x10ffff,
                     expected=4,
                     warn=(impl == 'cp' and
-                          sys.version_info < (3, 3))) \
-                and sys.version_info < (3, 3):
+                          sys.version_info.major == 2)) \
+                and sys.version_info.major == 2:
             u = 'u'
         abi = '%s%s%s%s%s' % (impl, get_impl_ver(), d, m, u)
     elif soabi and soabi.startswith('cpython-'):
index 4ea953201f48a7049f70eab4ea0c32b06f16e6eb..1a0705ece35b718a98bbb89c1ba35cbf0ff255dc 100644 (file)
@@ -1,15 +1,6 @@
-__all__ = ['get_config_vars', 'get_path']
+__all__ = []
 
-try:
-    # Python 2.7 or >=3.2
-    from sysconfig import get_config_vars, get_path
-except ImportError:
-    from distutils.sysconfig import get_config_vars, get_python_lib
-
-    def get_path(name):
-        if name not in ('platlib', 'purelib'):
-            raise ValueError("Name must be purelib or platlib")
-        return get_python_lib(name == 'platlib')
+__metaclass__ = type
 
 
 try:
@@ -19,7 +10,7 @@ except ImportError:
     import shutil
     import tempfile
 
-    class TemporaryDirectory(object):
+    class TemporaryDirectory:
         """
         Very simple temporary directory context manager.
         Will try to delete afterward, but will also ignore OS and similar
index 2a73ebb3c7a34af961fc45f8eb437113dc55c2bc..87cf53983c3bf1a39c5186ce1c67f6ac7f3b64a0 100644 (file)
@@ -10,11 +10,12 @@ except ImportError:
 from setuptools.extern import six
 from setuptools.extern.six.moves import html_parser
 
+__metaclass__ = type
 
 OpArg = collections.namedtuple('OpArg', 'opcode arg')
 
 
-class Bytecode_compat(object):
+class Bytecode_compat:
     def __init__(self, code):
         self.code = code
 
index d58b1bb5bfa58964966863bef1c8102a729fef79..39a24b04888e79df51e2237577b303a2f901be63 100644 (file)
@@ -2,4 +2,5 @@
 __requires__ = %(spec)r
 __import__('pkg_resources').require(%(spec)r)
 __file__ = %(dev_path)r
-exec(compile(open(__file__).read(), __file__, 'exec'))
+with open(__file__) as f:
+    exec(compile(f.read(), __file__, 'exec'))
index 0d2d2ff8da3960ecdaa6591fcee836c186fb8c91..40b00de0a799686485b266fd92abb9fb100ed718 100644 (file)
@@ -23,7 +23,7 @@ def __boot():
                 break
         else:
             try:
-                import imp  # Avoid import loop in Python >= 3.3
+                import imp  # Avoid import loop in Python 3
                 stream, path, descr = imp.find_module('site', [item])
             except ImportError:
                 continue
index 659c1a6587ed7ef3a4a207aa8c28cac81e8e6888..b39b7b8f90a2cd4ea9642f6cf6060e78db99d422 100644 (file)
@@ -5,12 +5,14 @@ import pytest
 from .files import build_files
 from .textwrap import DALS
 
+__metaclass__ = type
+
 
 futures = pytest.importorskip('concurrent.futures')
 importlib = pytest.importorskip('importlib')
 
 
-class BuildBackendBase(object):
+class BuildBackendBase:
     def __init__(self, cwd=None, env={}, backend_name='setuptools.build_meta'):
         self.cwd = cwd
         self.env = env
index 57339c8a128353867be475f17938a95ebee0fc52..345d283c313299b749b2b801abf25d5b73425a9e 100644 (file)
@@ -36,8 +36,10 @@ import pkg_resources
 from . import contexts
 from .textwrap import DALS
 
+__metaclass__ = type
 
-class FakeDist(object):
+
+class FakeDist:
     def get_entry_map(self, group):
         if group != 'console_scripts':
             return {}
@@ -688,7 +690,7 @@ def create_setup_requires_package(path, distname='foobar', version='0.1',
 )
 class TestScriptHeader:
     non_ascii_exe = '/Users/José/bin/python'
-    exe_with_spaces = r'C:\Program Files\Python33\python.exe'
+    exe_with_spaces = r'C:\Program Files\Python36\python.exe'
 
     def test_get_script_header(self):
         expected = '#!%s\n' % ei.nt_quote_arg(os.path.normpath(sys.executable))
index 8b3b90f77f4c423cb5e9f52fb437d5edf23a0359..1a100266eabf0307911908d4dc27a379cf06f861 100644 (file)
@@ -16,12 +16,14 @@ from .files import build_files
 from .textwrap import DALS
 from . import contexts
 
+__metaclass__ = type
+
 
 class Environment(str):
     pass
 
 
-class TestEggInfo(object):
+class TestEggInfo:
 
     setup_script = DALS("""
         from setuptools import setup
@@ -181,7 +183,7 @@ class TestEggInfo(object):
     )
     invalid_marker = "<=>++"
 
-    class RequiresTestHelper(object):
+    class RequiresTestHelper:
 
         @staticmethod
         def parametrize(*test_list, **format_dict):
@@ -452,7 +454,7 @@ class TestEggInfo(object):
 
     def test_doesnt_provides_extra(self, tmpdir_cwd, env):
         self._setup_script_with_requires(
-            '''install_requires=["spam ; python_version<'3.3'"]''')
+            '''install_requires=["spam ; python_version<'3.6'"]''')
         environ = os.environ.copy().update(
             HOME=env.paths['home'],
         )
index 9cb979648282e2ff332204f3487b18ab2af7b655..795fdc5665bca24140db244e61a292c620ef2171 100644 (file)
@@ -1,37 +1,52 @@
 import warnings
 
+import pytest
+
 from setuptools.glibc import check_glibc_version
 
+__metaclass__ = type
+
+
+@pytest.fixture(params=[
+    "2.20",
+    # used by "linaro glibc", see gh-3588
+    "2.20-2014.11",
+    # weird possibilities that I just made up
+    "2.20+dev",
+    "2.20-custom",
+    "2.20.1",
+    ])
+def two_twenty(request):
+    return request.param
+
+
+@pytest.fixture(params=["asdf", "", "foo.bar"])
+def bad_string(request):
+    return request.param
 
-class TestGlibc(object):
-    def test_manylinux1_check_glibc_version(self):
+
+class TestGlibc:
+    def test_manylinux1_check_glibc_version(self, two_twenty):
         """
         Test that the check_glibc_version function is robust against weird
         glibc version strings.
         """
-        for two_twenty in ["2.20",
-                           # used by "linaro glibc", see gh-3588
-                           "2.20-2014.11",
-                           # weird possibilities that I just made up
-                           "2.20+dev",
-                           "2.20-custom",
-                           "2.20.1",
-                           ]:
-            assert check_glibc_version(two_twenty, 2, 15)
-            assert check_glibc_version(two_twenty, 2, 20)
-            assert not check_glibc_version(two_twenty, 2, 21)
-            assert not check_glibc_version(two_twenty, 3, 15)
-            assert not check_glibc_version(two_twenty, 1, 15)
-
-        # For strings that we just can't parse at all, we should warn and
-        # return false
-        for bad_string in ["asdf", "", "foo.bar"]:
-            with warnings.catch_warnings(record=True) as ws:
-                warnings.filterwarnings("always")
-                assert not check_glibc_version(bad_string, 2, 5)
-                for w in ws:
-                    if "Expected glibc version with" in str(w.message):
-                        break
-                else:
-                    # Didn't find the warning we were expecting
-                    assert False
+        assert check_glibc_version(two_twenty, 2, 15)
+        assert check_glibc_version(two_twenty, 2, 20)
+        assert not check_glibc_version(two_twenty, 2, 21)
+        assert not check_glibc_version(two_twenty, 3, 15)
+        assert not check_glibc_version(two_twenty, 1, 15)
+
+    def test_bad_versions(self, bad_string):
+        """
+        For unparseable strings, warn and return False
+        """
+        with warnings.catch_warnings(record=True) as ws:
+            warnings.filterwarnings("always")
+            assert not check_glibc_version(bad_string, 2, 5)
+            for w in ws:
+                if "Expected glibc version with" in str(w.message):
+                    break
+            else:
+                # Didn't find the warning we were expecting
+                assert False
index 7393241f84956a98346df048716295ba942fdea3..727ad65b13d15f4658025c70f3e93f9b668d6eb2 100644 (file)
@@ -19,7 +19,7 @@ class TestInstallScripts:
     )
     unix_exe = '/usr/dummy-test-path/local/bin/python'
     unix_spaces_exe = '/usr/bin/env dummy-test-python'
-    win32_exe = 'C:\\Dummy Test Path\\Program Files\\Python 3.3\\python.exe'
+    win32_exe = 'C:\\Dummy Test Path\\Program Files\\Python 3.6\\python.exe'
 
     def _run_install_scripts(self, install_dir, executable=None):
         dist = Distribution(self.settings)
index 65eec7d93f0dadda6ac3c831b9a8f686cdf17915..c9533dda9f3343f1d17c123f5df6a971d9792df4 100644 (file)
@@ -18,6 +18,8 @@ from setuptools.tests.textwrap import DALS
 
 import pytest
 
+__metaclass__ = type
+
 py3_only = pytest.mark.xfail(six.PY2, reason="Test runs on Python 3 only")
 
 
@@ -157,7 +159,7 @@ def test_translated_pattern_mismatch(pattern_mismatch):
     assert not translate_pattern(pattern).match(target)
 
 
-class TempDirTestCase(object):
+class TempDirTestCase:
     def setup_method(self, method):
         self.temp_dir = tempfile.mkdtemp()
         self.old_cwd = os.getcwd()
index 0f60e0ede49a193acd9e0ea9611fcee21a21a5a1..658784ac95dac811ed3b86c3a9b9a1ca81acf0ad 100644 (file)
@@ -4,8 +4,10 @@ from mock import patch
 
 from setuptools import pep425tags
 
+__metaclass__ = type
 
-class TestPEP425Tags(object):
+
+class TestPEP425Tags:
 
     def mock_get_config_var(self, **kwd):
         """
@@ -104,7 +106,7 @@ class TestPEP425Tags(object):
         self.abi_tag_unicode('dm', {'Py_DEBUG': True, 'WITH_PYMALLOC': True})
 
 
-class TestManylinux1Tags(object):
+class TestManylinux1Tags:
 
     @patch('setuptools.pep425tags.get_platform', lambda: 'linux_x86_64')
     @patch('setuptools.glibc.have_compatible_glibc',
index cf6508686d78df1a1c9ff974316476948d28422b..6db5fa117e0ea35f721347134ed84426a60b20b5 100644 (file)
@@ -24,6 +24,8 @@ from .contexts import tempdir
 from .files import build_files
 from .textwrap import DALS
 
+__metaclass__ = type
+
 
 WHEEL_INFO_TESTS = (
     ('invalid.whl', ValueError),
@@ -148,7 +150,7 @@ def _check_wheel_install(filename, install_dir, install_tree_includes,
         assert requires_txt == dist.get_metadata('requires.txt').lstrip()
 
 
-class Record(object):
+class Record:
 
     def __init__(self, id, **kwargs):
         self._id = id
index 4a33b20324a0d9b8b030dc2b55f8f213af0c0c3f..95a794a85361be66f1862ff3e8035cb807eb6503 100644 (file)
@@ -1,4 +1,4 @@
-'''Wheels support.'''
+"""Wheels support."""
 
 from distutils.util import get_platform
 import email
@@ -16,11 +16,14 @@ from setuptools import pep425tags
 from setuptools.command.egg_info import write_requirements
 
 
+__metaclass__ = type
+
+
 WHEEL_NAME = re.compile(
     r"""^(?P<project_name>.+?)-(?P<version>\d.*?)
     ((-(?P<build>\d.*?))?-(?P<py_version>.+?)-(?P<abi>.+?)-(?P<platform>.+?)
     )\.whl$""",
-re.VERBOSE).match
+    re.VERBOSE).match
 
 NAMESPACE_PACKAGE_INIT = '''\
 try:
@@ -52,7 +55,7 @@ def unpack(src_dir, dst_dir):
         os.rmdir(dirpath)
 
 
-class Wheel(object):
+class Wheel:
 
     def __init__(self, filename):
         match = WHEEL_NAME(os.path.basename(filename))
@@ -64,9 +67,11 @@ class Wheel(object):
 
     def tags(self):
         '''List tags (py_version, abi, platform) supported by this wheel.'''
-        return itertools.product(self.py_version.split('.'),
-                                 self.abi.split('.'),
-                                 self.platform.split('.'))
+        return itertools.product(
+            self.py_version.split('.'),
+            self.abi.split('.'),
+            self.platform.split('.'),
+        )
 
     def is_compatible(self):
         '''Is the wheel is compatible with the current platform?'''
@@ -92,84 +97,114 @@ class Wheel(object):
     def install_as_egg(self, destination_eggdir):
         '''Install wheel as an egg directory.'''
         with zipfile.ZipFile(self.filename) as zf:
-            dist_basename = '%s-%s' % (self.project_name, self.version)
-            dist_info = self.get_dist_info(zf)
-            dist_data = '%s.data' % dist_basename
-            def get_metadata(name):
-                with zf.open(posixpath.join(dist_info, name)) as fp:
-                    value = fp.read().decode('utf-8') if PY3 else fp.read()
-                    return email.parser.Parser().parsestr(value)
-            wheel_metadata = get_metadata('WHEEL')
-            dist_metadata = get_metadata('METADATA')
-            # Check wheel format version is supported.
-            wheel_version = parse_version(wheel_metadata.get('Wheel-Version'))
-            if not parse_version('1.0') <= wheel_version < parse_version('2.0dev0'):
-                raise ValueError('unsupported wheel format version: %s' % wheel_version)
-            # Extract to target directory.
-            os.mkdir(destination_eggdir)
-            zf.extractall(destination_eggdir)
-            # Convert metadata.
-            dist_info = os.path.join(destination_eggdir, dist_info)
-            dist = Distribution.from_location(
-                destination_eggdir, dist_info,
-                metadata=PathMetadata(destination_eggdir, dist_info)
+            self._install_as_egg(destination_eggdir, zf)
+
+    def _install_as_egg(self, destination_eggdir, zf):
+        dist_basename = '%s-%s' % (self.project_name, self.version)
+        dist_info = self.get_dist_info(zf)
+        dist_data = '%s.data' % dist_basename
+        egg_info = os.path.join(destination_eggdir, 'EGG-INFO')
+
+        self._convert_metadata(zf, destination_eggdir, dist_info, egg_info)
+        self._move_data_entries(destination_eggdir, dist_data)
+        self._fix_namespace_packages(egg_info, destination_eggdir)
+
+    @staticmethod
+    def _convert_metadata(zf, destination_eggdir, dist_info, egg_info):
+        def get_metadata(name):
+            with zf.open(posixpath.join(dist_info, name)) as fp:
+                value = fp.read().decode('utf-8') if PY3 else fp.read()
+                return email.parser.Parser().parsestr(value)
+
+        wheel_metadata = get_metadata('WHEEL')
+        # Check wheel format version is supported.
+        wheel_version = parse_version(wheel_metadata.get('Wheel-Version'))
+        wheel_v1 = (
+            parse_version('1.0') <= wheel_version < parse_version('2.0dev0')
+        )
+        if not wheel_v1:
+            raise ValueError(
+                'unsupported wheel format version: %s' % wheel_version)
+        # Extract to target directory.
+        os.mkdir(destination_eggdir)
+        zf.extractall(destination_eggdir)
+        # Convert metadata.
+        dist_info = os.path.join(destination_eggdir, dist_info)
+        dist = Distribution.from_location(
+            destination_eggdir, dist_info,
+            metadata=PathMetadata(destination_eggdir, dist_info),
+        )
+
+        # Note: Evaluate and strip markers now,
+        # as it's difficult to convert back from the syntax:
+        # foobar; "linux" in sys_platform and extra == 'test'
+        def raw_req(req):
+            req.marker = None
+            return str(req)
+        install_requires = list(sorted(map(raw_req, dist.requires())))
+        extras_require = {
+            extra: sorted(
+                req
+                for req in map(raw_req, dist.requires((extra,)))
+                if req not in install_requires
             )
-            # Note: we need to evaluate and strip markers now,
-            # as we can't easily convert back from the syntax:
-            # foobar; "linux" in sys_platform and extra == 'test'
-            def raw_req(req):
-                req.marker = None
-                return str(req)
-            install_requires = list(sorted(map(raw_req, dist.requires())))
-            extras_require = {
-                extra: list(sorted(
-                    req
-                    for req in map(raw_req, dist.requires((extra,)))
-                    if req not in install_requires
-                ))
-                for extra in dist.extras
-            }
-            egg_info = os.path.join(destination_eggdir, 'EGG-INFO')
-            os.rename(dist_info, egg_info)
-            os.rename(os.path.join(egg_info, 'METADATA'),
-                      os.path.join(egg_info, 'PKG-INFO'))
-            setup_dist = SetuptoolsDistribution(attrs=dict(
+            for extra in dist.extras
+        }
+        os.rename(dist_info, egg_info)
+        os.rename(
+            os.path.join(egg_info, 'METADATA'),
+            os.path.join(egg_info, 'PKG-INFO'),
+        )
+        setup_dist = SetuptoolsDistribution(
+            attrs=dict(
                 install_requires=install_requires,
                 extras_require=extras_require,
-            ))
-            write_requirements(setup_dist.get_command_obj('egg_info'),
-                               None, os.path.join(egg_info, 'requires.txt'))
-            # Move data entries to their correct location.
-            dist_data = os.path.join(destination_eggdir, dist_data)
-            dist_data_scripts = os.path.join(dist_data, 'scripts')
-            if os.path.exists(dist_data_scripts):
-                egg_info_scripts = os.path.join(destination_eggdir,
-                                                'EGG-INFO', 'scripts')
-                os.mkdir(egg_info_scripts)
-                for entry in os.listdir(dist_data_scripts):
-                    # Remove bytecode, as it's not properly handled
-                    # during easy_install scripts install phase.
-                    if entry.endswith('.pyc'):
-                        os.unlink(os.path.join(dist_data_scripts, entry))
-                    else:
-                        os.rename(os.path.join(dist_data_scripts, entry),
-                                  os.path.join(egg_info_scripts, entry))
-                os.rmdir(dist_data_scripts)
-            for subdir in filter(os.path.exists, (
-                os.path.join(dist_data, d)
-                for d in ('data', 'headers', 'purelib', 'platlib')
-            )):
-                unpack(subdir, destination_eggdir)
-            if os.path.exists(dist_data):
-                os.rmdir(dist_data)
-            # Fix namespace packages.
-            namespace_packages = os.path.join(egg_info, 'namespace_packages.txt')
-            if os.path.exists(namespace_packages):
-                with open(namespace_packages) as fp:
-                    namespace_packages = fp.read().split()
-                for mod in namespace_packages:
-                    mod_dir = os.path.join(destination_eggdir, *mod.split('.'))
-                    mod_init = os.path.join(mod_dir, '__init__.py')
-                    if os.path.exists(mod_dir) and not os.path.exists(mod_init):
-                        with open(mod_init, 'w') as fp:
-                            fp.write(NAMESPACE_PACKAGE_INIT)
+            ),
+        )
+        write_requirements(
+            setup_dist.get_command_obj('egg_info'),
+            None,
+            os.path.join(egg_info, 'requires.txt'),
+        )
+
+    @staticmethod
+    def _move_data_entries(destination_eggdir, dist_data):
+        """Move data entries to their correct location."""
+        dist_data = os.path.join(destination_eggdir, dist_data)
+        dist_data_scripts = os.path.join(dist_data, 'scripts')
+        if os.path.exists(dist_data_scripts):
+            egg_info_scripts = os.path.join(
+                destination_eggdir, 'EGG-INFO', 'scripts')
+            os.mkdir(egg_info_scripts)
+            for entry in os.listdir(dist_data_scripts):
+                # Remove bytecode, as it's not properly handled
+                # during easy_install scripts install phase.
+                if entry.endswith('.pyc'):
+                    os.unlink(os.path.join(dist_data_scripts, entry))
+                else:
+                    os.rename(
+                        os.path.join(dist_data_scripts, entry),
+                        os.path.join(egg_info_scripts, entry),
+                    )
+            os.rmdir(dist_data_scripts)
+        for subdir in filter(os.path.exists, (
+            os.path.join(dist_data, d)
+            for d in ('data', 'headers', 'purelib', 'platlib')
+        )):
+            unpack(subdir, destination_eggdir)
+        if os.path.exists(dist_data):
+            os.rmdir(dist_data)
+
+    @staticmethod
+    def _fix_namespace_packages(egg_info, destination_eggdir):
+        namespace_packages = os.path.join(
+            egg_info, 'namespace_packages.txt')
+        if os.path.exists(namespace_packages):
+            with open(namespace_packages) as fp:
+                namespace_packages = fp.read().split()
+            for mod in namespace_packages:
+                mod_dir = os.path.join(destination_eggdir, *mod.split('.'))
+                mod_init = os.path.join(mod_dir, '__init__.py')
+                if os.path.exists(mod_dir) and not os.path.exists(mod_init):
+                    with open(mod_init, 'w') as fp:
+                        fp.write(NAMESPACE_PACKAGE_INIT)
index e5aaf179c6529c9e0b920a0678839dae633378bf..52295f9a56d8793d2d612fc737c9ea923a12be14 100644 (file)
@@ -89,8 +89,10 @@ def test_full():
     assert len(eggs) == 3
     assert eggs[1].startswith('setuptools')
     del eggs[1]
-    assert eggs == ['extensions-0.3-py2.6.egg',
-        'zc.recipe.egg-1.2.2-py2.6.egg']
+    assert eggs == [
+        'extensions-0.3-py2.6.egg',
+        'zc.recipe.egg-1.2.2-py2.6.egg',
+    ]
 
 
 if __name__ == '__main__':
index aff32c10eab239b053bb32b1211ffb013641fad7..b38fcbf06e2780dea0c74cf5364fbdb122635276 100644 (file)
@@ -1,10 +1,10 @@
-importlib; python_version<"2.7"
 mock
-pytest-flake8<=1.0.0; python_version>="3.3" and python_version<"3.5"
-pytest-flake8; python_version>="2.7" and python_version!="3.3" and python_version!="3.4"
+pytest-flake8; python_version!="3.4"
+pytest-flake8<=1.0.0; python_version=="3.4"
 virtualenv>=13.0.0
 pytest-virtualenv>=1.2.7
 pytest>=3.0.2
 wheel
 coverage>=4.5.1
 pytest-cov>=2.5.1
+paver; python_version>="3.6"
diff --git a/tests/test_pypi.py b/tests/test_pypi.py
deleted file mode 100644 (file)
index b3425e5..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-import os
-import subprocess
-
-import virtualenv
-from setuptools.extern.six.moves import http_client
-from setuptools.extern.six.moves import xmlrpc_client
-
-TOP = 200
-PYPI_HOSTNAME = 'pypi.python.org'
-
-
-def rpc_pypi(method, *args):
-    """Call an XML-RPC method on the Pypi server."""
-    conn = http_client.HTTPSConnection(PYPI_HOSTNAME)
-    headers = {'Content-Type': 'text/xml'}
-    payload = xmlrpc_client.dumps(args, method)
-
-    conn.request("POST", "/pypi", payload, headers)
-    response = conn.getresponse()
-    if response.status == 200:
-        result = xmlrpc_client.loads(response.read())[0][0]
-        return result
-    else:
-        raise RuntimeError("Unable to download the list of top "
-                           "packages from Pypi.")
-
-
-def get_top_packages(limit):
-    """Collect the name of the top packages on Pypi."""
-    packages = rpc_pypi('top_packages')
-    return packages[:limit]
-
-
-def _package_install(package_name, tmp_dir=None, local_setuptools=True):
-    """Try to install a package and return the exit status.
-
-    This function creates a virtual environment, install setuptools using pip
-    and then install the required package. If local_setuptools is True, it
-    will install the local version of setuptools.
-    """
-    package_dir = os.path.join(tmp_dir, "test_%s" % package_name)
-    if not local_setuptools:
-        package_dir = package_dir + "_baseline"
-
-    virtualenv.create_environment(package_dir)
-
-    pip_path = os.path.join(package_dir, "bin", "pip")
-    if local_setuptools:
-        subprocess.check_call([pip_path, "install", "."])
-    returncode = subprocess.call([pip_path, "install", package_name])
-    return returncode
-
-
-def test_package_install(package_name, tmpdir):
-    """Test to verify the outcome of installing a package.
-
-    This test compare that the return code when installing a package is the
-    same as with the current stable version of setuptools.
-    """
-    new_exit_status = _package_install(package_name, tmp_dir=str(tmpdir))
-    if new_exit_status:
-        print("Installation failed, testing against stable setuptools",
-              package_name)
-        old_exit_status = _package_install(package_name, tmp_dir=str(tmpdir),
-                                           local_setuptools=False)
-        assert new_exit_status == old_exit_status
-
-
-def pytest_generate_tests(metafunc):
-    """Generator function for test_package_install.
-
-    This function will generate calls to test_package_install. If a package
-    list has been specified on the command line, it will be used. Otherwise,
-    Pypi will be queried to get the current list of top packages.
-    """
-    if "package_name" in metafunc.fixturenames:
-        if not metafunc.config.option.package_name:
-            packages = get_top_packages(TOP)
-            packages = [name for name, downloads in packages]
-        else:
-            packages = metafunc.config.option.package_name
-        metafunc.parametrize("package_name", packages)
diff --git a/tox.ini b/tox.ini
index a16e89faa727fd4f644c66bc9ae983a2e31780b6..1a369653fcbf9272626f37679cb4aed7881f473f 100644 (file)
--- a/tox.ini
+++ b/tox.ini
@@ -2,7 +2,7 @@
 #
 # To run Tox against all supported Python interpreters, you can set:
 #
-# export TOXENV='py27,py3{3,4,5,6},pypy,pypy3'
+# export TOXENV='py27,py3{4,5,6},pypy,pypy3'
 
 [tox]
 envlist=python