Imported Upstream version 36.6.1 upstream/36.6.1
authorDongHun Kwak <dh0128.kwak@samsung.com>
Mon, 14 Jan 2019 01:35:12 +0000 (10:35 +0900)
committerDongHun Kwak <dh0128.kwak@samsung.com>
Mon, 14 Jan 2019 01:35:12 +0000 (10:35 +0900)
CHANGES.rst
pkg_resources/__init__.py
setup.cfg
setup.py
setuptools/command/__init__.py
setuptools/command/bdist_egg.py
setuptools/command/develop.py
setuptools/command/dist_info.py
setuptools/command/easy_install.py
setuptools/tests/test_bdist_egg.py

index 3dbda9dc4be40bab4467459dfe4e43a53d657e13..bea607865c1c21e9633574c4622c019fa26f33f6 100644 (file)
@@ -1,3 +1,12 @@
+v36.6.1
+-------
+
+* #1132: Removed redundant and costly serialization/parsing step
+  in ``EntryPoint.__init__``.
+
+* #844: ``bdist_egg --exclude-source-files`` now tested and works
+  on Python 3.
+
 v36.6.0
 -------
 
index 049b8a5458e1bdfef65d2b7c08a8b248aac032bd..6f1071fb87ab431c84268e4b133fb2038d2dd493 100644 (file)
@@ -480,8 +480,10 @@ def get_build_platform():
         try:
             version = _macosx_vers()
             machine = os.uname()[4].replace(" ", "_")
-            return "macosx-%d.%d-%s" % (int(version[0]), int(version[1]),
-                _macosx_arch(machine))
+            return "macosx-%d.%d-%s" % (
+                int(version[0]), int(version[1]),
+                _macosx_arch(machine),
+            )
         except ValueError:
             # if someone is running a non-Mac darwin system, this will fall
             # through to the default implementation
@@ -806,7 +808,8 @@ class WorkingSet(object):
         already-installed distribution; it should return a ``Distribution`` or
         ``None``.
 
-        Unless `replace_conflicting=True`, raises a VersionConflict exception if
+        Unless `replace_conflicting=True`, raises a VersionConflict exception
+        if
         any requirements are found on the path that have the correct name but
         the wrong version.  Otherwise, if an `installer` is supplied it will be
         invoked to obtain the correct version of the requirement and activate
@@ -885,8 +888,8 @@ class WorkingSet(object):
         # return list of distros to activate
         return to_activate
 
-    def find_plugins(self, plugin_env, full_env=None, installer=None,
-            fallback=True):
+    def find_plugins(
+            self, plugin_env, full_env=None, installer=None, fallback=True):
         """Find all activatable distributions in `plugin_env`
 
         Example usage::
@@ -1040,7 +1043,8 @@ class _ReqExtras(dict):
 class Environment(object):
     """Searchable snapshot of distributions on a search path"""
 
-    def __init__(self, search_path=None, platform=get_supported_platform(),
+    def __init__(
+            self, search_path=None, platform=get_supported_platform(),
             python=PY_MAJOR):
         """Snapshot distributions available on a search path
 
@@ -1113,7 +1117,8 @@ class Environment(object):
                 dists.append(dist)
                 dists.sort(key=operator.attrgetter('hashcmp'), reverse=True)
 
-    def best_match(self, req, working_set, installer=None, replace_conflicting=False):
+    def best_match(
+            self, req, working_set, installer=None, replace_conflicting=False):
         """Find distribution best matching `req` and usable on `working_set`
 
         This calls the ``find(req)`` method of the `working_set` to see if a
@@ -1248,8 +1253,8 @@ class ResourceManager:
         tmpl = textwrap.dedent("""
             Can't extract file(s) to egg cache
 
-            The following error occurred while trying to extract file(s) to the Python egg
-            cache:
+            The following error occurred while trying to extract file(s)
+            to the Python egg cache:
 
               {old_exc}
 
@@ -1257,9 +1262,9 @@ class ResourceManager:
 
               {cache_path}
 
-            Perhaps your account does not have write access to this directory?  You can
-            change the cache directory by setting the PYTHON_EGG_CACHE environment
-            variable to point to an accessible directory.
+            Perhaps your account does not have write access to this directory?
+            You can change the cache directory by setting the PYTHON_EGG_CACHE
+            environment variable to point to an accessible directory.
             """).lstrip()
         err = ExtractionError(tmpl.format(**locals()))
         err.manager = self
@@ -1309,11 +1314,13 @@ class ResourceManager:
             return
         mode = os.stat(path).st_mode
         if mode & stat.S_IWOTH or mode & stat.S_IWGRP:
-            msg = ("%s is writable by group/others and vulnerable to attack "
+            msg = (
+                "%s is writable by group/others and vulnerable to attack "
                 "when "
                 "used with get_resource_filename. Consider a more secure "
                 "location (set with .set_extraction_path or the "
-                "PYTHON_EGG_CACHE environment variable)." % path)
+                "PYTHON_EGG_CACHE environment variable)." % path
+            )
             warnings.warn(msg, UserWarning)
 
     def postprocess(self, tempname, filename):
@@ -1597,8 +1604,11 @@ class DefaultProvider(EggProvider):
 
     @classmethod
     def _register(cls):
-        loader_cls = getattr(importlib_machinery, 'SourceFileLoader',
-            type(None))
+        loader_cls = getattr(
+            importlib_machinery,
+            'SourceFileLoader',
+            type(None),
+        )
         register_loader_type(loader_cls, cls)
 
 
@@ -1766,7 +1776,10 @@ class ZipProvider(EggProvider):
             if self._is_current(real_path, zip_path):
                 return real_path
 
-            outf, tmpnam = _mkstemp(".$extract", dir=os.path.dirname(real_path))
+            outf, tmpnam = _mkstemp(
+                ".$extract",
+                dir=os.path.dirname(real_path),
+            )
             os.write(outf, self.loader.get_data(zip_path))
             os.close(outf)
             utime(tmpnam, (timestamp, timestamp))
@@ -1972,7 +1985,8 @@ def find_eggs_in_zip(importer, path_item, only=False):
     for subitem in metadata.resource_listdir('/'):
         if _is_egg_path(subitem):
             subpath = os.path.join(path_item, subitem)
-            for dist in find_eggs_in_zip(zipimport.zipimporter(subpath), subpath):
+            dists = find_eggs_in_zip(zipimport.zipimporter(subpath), subpath)
+            for dist in dists:
                 yield dist
         elif subitem.lower().endswith('.dist-info'):
             subpath = os.path.join(path_item, subitem)
@@ -1981,7 +1995,6 @@ def find_eggs_in_zip(importer, path_item, only=False):
             yield Distribution.from_location(path_item, subitem, submeta)
 
 
-
 register_finder(zipimport.zipimporter, find_eggs_in_zip)
 
 
@@ -2379,7 +2392,7 @@ class EntryPoint(object):
         self.name = name
         self.module_name = module_name
         self.attrs = tuple(attrs)
-        self.extras = Requirement.parse(("x[%s]" % ','.join(extras))).extras
+        self.extras = tuple(extras)
         self.dist = dist
 
     def __str__(self):
@@ -2527,7 +2540,8 @@ class Distribution(object):
     """Wrap an actual or potential sys.path entry w/metadata"""
     PKG_INFO = 'PKG-INFO'
 
-    def __init__(self, location=None, metadata=None, project_name=None,
+    def __init__(
+            self, location=None, metadata=None, project_name=None,
             version=None, py_version=PY_MAJOR, platform=None,
             precedence=EGG_DIST):
         self.project_name = safe_name(project_name or 'Unknown')
@@ -2803,7 +2817,8 @@ class Distribution(object):
                 if replace:
                     break
                 else:
-                    # don't modify path (even removing duplicates) if found and not replace
+                    # don't modify path (even removing duplicates) if
+                    # found and not replace
                     return
             elif item == bdir and self.precedence == EGG_DIST:
                 # if it's an .egg, give it precedence over its directory
@@ -2900,7 +2915,10 @@ class EggInfoDistribution(Distribution):
 
 
 class DistInfoDistribution(Distribution):
-    """Wrap an actual or potential sys.path entry w/metadata, .dist-info style"""
+    """
+    Wrap an actual or potential sys.path entry
+    w/metadata, .dist-info style.
+    """
     PKG_INFO = 'METADATA'
     EQEQ = re.compile(r"([\(,])\s*(\d.*?)\s*([,\)])")
 
@@ -2950,7 +2968,7 @@ _distributionImpl = {
     '.egg': Distribution,
     '.egg-info': EggInfoDistribution,
     '.dist-info': DistInfoDistribution,
-    }
+}
 
 
 def issue_warning(*args, **kw):
@@ -3035,7 +3053,8 @@ class Requirement(packaging.requirements.Requirement):
     def __hash__(self):
         return self.__hash
 
-    def __repr__(self): return "Requirement.parse(%r)" % str(self)
+    def __repr__(self):
+        return "Requirement.parse(%r)" % str(self)
 
     @staticmethod
     def parse(s):
@@ -3169,7 +3188,10 @@ def _initialize_master_working_set():
         dist.activate(replace=False)
         for dist in working_set
     )
-    add_activation_listener(lambda dist: dist.activate(replace=True), existing=False)
+    add_activation_listener(
+        lambda dist: dist.activate(replace=True),
+        existing=False,
+    )
     working_set.entries = []
     # match order
     list(map(working_set.add_entry, sys.path))
index c1ee1ba49572de7f0b2af1ea86641c7c5f253ffa..7f8087826eb8af3d6f60a0b1fa23f8df6d5d58fd 100755 (executable)
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,5 +1,5 @@
 [bumpversion]
-current_version = 36.6.0
+current_version = 36.6.1
 commit = True
 tag = True
 
@@ -22,5 +22,8 @@ formats = zip
 [bdist_wheel]
 universal = 1
 
+[metadata]
+license_file = LICENSE
+
 [bumpversion:file:setup.py]
 
index 33003465a142b1f66babbc967185e51b6ce44896..c5bc72548a3b250048be2fe8b09d54dd1628ee6b 100755 (executable)
--- a/setup.py
+++ b/setup.py
@@ -89,7 +89,7 @@ def pypi_link(pkg_filename):
 
 setup_params = dict(
     name="setuptools",
-    version="36.6.0",
+    version="36.6.1",
     description="Easily download, build, install, upgrade, and uninstall "
         "Python packages",
     author="Python Packaging Authority",
index 4fe3bb5684634986c14ff1cfe328c18ea4c537e7..fe619e2e676f6e0cf95b2af63cdab33ed386f6b0 100644 (file)
@@ -2,7 +2,8 @@ __all__ = [
     'alias', 'bdist_egg', 'bdist_rpm', 'build_ext', 'build_py', 'develop',
     'easy_install', 'egg_info', 'install', 'install_lib', 'rotate', 'saveopts',
     'sdist', 'setopt', 'test', 'install_egg_info', 'install_scripts',
-    'register', 'bdist_wininst', 'upload_docs', 'upload', 'build_clib', 'dist_info',
+    'register', 'bdist_wininst', 'upload_docs', 'upload', 'build_clib',
+    'dist_info',
 ]
 
 from distutils.command.bdist import bdist
index 51755d52c9dcddb3d0781b090c1c14df30b773db..5fdb62d905e79e43140eaa538159789e26008f5f 100644 (file)
@@ -8,6 +8,7 @@ from distutils import log
 from types import CodeType
 import sys
 import os
+import re
 import textwrap
 import marshal
 
@@ -240,11 +241,26 @@ class bdist_egg(Command):
         log.info("Removing .py files from temporary directory")
         for base, dirs, files in walk_egg(self.bdist_dir):
             for name in files:
+                path = os.path.join(base, name)
+
                 if name.endswith('.py'):
-                    path = os.path.join(base, name)
                     log.debug("Deleting %s", path)
                     os.unlink(path)
 
+                if base.endswith('__pycache__'):
+                    path_old = path
+
+                    pattern = r'(?P<name>.+)\.(?P<magic>[^.]+)\.pyc'
+                    m = re.match(pattern, name)
+                    path_new = os.path.join(base, os.pardir, m.group('name') + '.pyc')
+                    log.info("Renaming file from [%s] to [%s]" % (path_old, path_new))
+                    try:
+                        os.remove(path_new)
+                    except OSError:
+                        pass
+                    os.rename(path_old, path_new)
+
+
     def zip_safe(self):
         safe = getattr(self.distribution, 'zip_safe', None)
         if safe is not None:
index 85b23c6080e9cee562624cbbb11d004f8d0d1ef4..959c932a5c0c3a94463e3547c05ba26958ae5b96 100755 (executable)
@@ -95,7 +95,9 @@ class develop(namespaces.DevelopInstaller, easy_install):
         path_to_setup = egg_base.replace(os.sep, '/').rstrip('/')
         if path_to_setup != os.curdir:
             path_to_setup = '../' * (path_to_setup.count('/') + 1)
-        resolved = normalize_path(os.path.join(install_dir, egg_path, path_to_setup))
+        resolved = normalize_path(
+            os.path.join(install_dir, egg_path, path_to_setup)
+        )
         if resolved != normalize_path(os.curdir):
             raise DistutilsOptionError(
                 "Can't get a consistent path to setup script from"
index c8dc659b1186d2ed17940a13b928e1fe18430cf7..c6c6dacb78b898460f72918b87cc69e2946c86f0 100644 (file)
@@ -7,6 +7,7 @@ import os
 import shutil
 
 from distutils.core import Command
+from distutils import log
 
 
 class dist_info(Command):
@@ -28,10 +29,12 @@ class dist_info(Command):
         egg_info = self.get_finalized_command('egg_info')
         egg_info.run()
         dist_info_dir = egg_info.egg_info[:-len('.egg-info')] + '.dist-info'
+        log.info("creating '{}'".format(os.path.abspath(dist_info_dir)))
 
         bdist_wheel = self.get_finalized_command('bdist_wheel')
         bdist_wheel.egg2dist(egg_info.egg_info, dist_info_dir)
 
         if self.egg_base:
-            shutil.move(dist_info_dir, os.path.join(
-                self.egg_base, dist_info_dir))
+            destination = os.path.join(self.egg_base, dist_info_dir)
+            log.info("creating '{}'".format(os.path.abspath(destination)))
+            shutil.move(dist_info_dir, destination)
index 8fba7b4115cd6415fef436fd41740ab8c200356f..71991efac104a631fc9a7987f80a6b8179458137 100755 (executable)
@@ -1817,7 +1817,7 @@ def _update_zipimporter_cache(normalized_path, cache, updater=None):
         #    get/del patterns instead. For more detailed information see the
         #    following links:
         #      https://github.com/pypa/setuptools/issues/202#issuecomment-202913420
-        #      https://bitbucket.org/pypy/pypy/src/dd07756a34a41f674c0cacfbc8ae1d4cc9ea2ae4/pypy/module/zipimport/interp_zipimport.py#cl-99
+        #      http://bit.ly/2h9itJX
         old_entry = cache[p]
         del cache[p]
         new_entry = updater and updater(p, old_entry)
index d24aa366d4196653da82b8d8adc43b733860a6d2..61615b385cf25f33a04111f073c682ba4f35e587 100644 (file)
@@ -2,6 +2,7 @@
 """
 import os
 import re
+import zipfile
 
 import pytest
 
@@ -16,7 +17,7 @@ setup(name='foo', py_modules=['hi'])
 """
 
 
-@pytest.yield_fixture
+@pytest.fixture(scope='function')
 def setup_context(tmpdir):
     with (tmpdir / 'setup.py').open('w') as f:
         f.write(SETUP_PY)
@@ -32,7 +33,7 @@ class Test:
             script_name='setup.py',
             script_args=['bdist_egg'],
             name='foo',
-            py_modules=['hi']
+            py_modules=['hi'],
         ))
         os.makedirs(os.path.join('build', 'src'))
         with contexts.quiet():
@@ -42,3 +43,20 @@ class Test:
         # let's see if we got our egg link at the right place
         [content] = os.listdir('dist')
         assert re.match(r'foo-0.0.0-py[23].\d.egg$', content)
+
+    def test_exclude_source_files(self, setup_context, user_override):
+        dist = Distribution(dict(
+            script_name='setup.py',
+            script_args=['bdist_egg', '--exclude-source-files'],
+            name='foo',
+            py_modules=['hi'],
+        ))
+        with contexts.quiet():
+            dist.parse_command_line()
+            dist.run_commands()
+        [dist_name] = os.listdir('dist')
+        dist_filename = os.path.join('dist', dist_name)
+        zip = zipfile.ZipFile(dist_filename)
+        names = list(zi.filename for zi in zip.filelist)
+        assert 'hi.pyc' in names
+        assert 'hi.py' not in names