From e0e02ba96d8ee3b7be76adeec1ec9b9c3c004516 Mon Sep 17 00:00:00 2001 From: Erik Bray Date: Thu, 31 Dec 2015 13:36:36 -0500 Subject: Adds the regression test for distribute issue 323 that I attached to #207. This is to ensure that any fix to #207 does not introduce another regression. --- setuptools/tests/contexts.py | 13 +++ setuptools/tests/test_easy_install.py | 189 ++++++++++++++++++++++++++++------ 2 files changed, 173 insertions(+), 29 deletions(-) diff --git a/setuptools/tests/contexts.py b/setuptools/tests/contexts.py index 8c9a2d3e..ae28c7c3 100644 --- a/setuptools/tests/contexts.py +++ b/setuptools/tests/contexts.py @@ -6,6 +6,7 @@ import contextlib import site from setuptools.extern import six +import pkg_resources @contextlib.contextmanager @@ -77,6 +78,18 @@ def save_user_site_setting(): site.ENABLE_USER_SITE = saved +@contextlib.contextmanager +def save_pkg_resources_state(): + pr_state = pkg_resources.__getstate__() + # also save sys.path + sys_path = sys.path[:] + try: + yield pr_state, sys_path + finally: + sys.path[:] = sys_path + pkg_resources.__setstate__(pr_state) + + @contextlib.contextmanager def suppress_exceptions(*excs): try: diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py index 94e317b3..4f9e52d1 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -18,6 +18,7 @@ import io from setuptools.extern import six from setuptools.extern.six.moves import urllib +import time import pytest try: @@ -310,32 +311,32 @@ class TestSetupRequires: """ with contexts.tempdir() as dir: dist_path = os.path.join(dir, 'setuptools-test-fetcher-1.0.tar.gz') - script = DALS(""" - import setuptools - setuptools.setup( - name="setuptools-test-fetcher", - version="1.0", - setup_requires = ['does-not-exist'], - ) - """) - make_trivial_sdist(dist_path, script) + make_sdist(dist_path, [ + ('setup.py', DALS(""" + import setuptools + setuptools.setup( + name="setuptools-test-fetcher", + version="1.0", + setup_requires = ['does-not-exist'], + ) + """))]) yield dist_path def test_setup_requires_overrides_version_conflict(self): """ - Regression test for issue #323. + Regression test for distribution issue 323: + https://bitbucket.org/tarek/distribute/issues/323 Ensures that a distribution's setup_requires requirements can still be installed and used locally even if a conflicting version of that requirement is already on the path. """ - pr_state = pkg_resources.__getstate__() fake_dist = PRDistribution('does-not-matter', project_name='foobar', version='0.0') working_set.add(fake_dist) - try: + with contexts.save_pkg_resources_state(): with contexts.tempdir() as temp_dir: test_pkg = create_setup_requires_package(temp_dir) test_setup_py = os.path.join(test_pkg, 'setup.py') @@ -347,19 +348,154 @@ class TestSetupRequires: lines = stdout.readlines() assert len(lines) > 0 assert lines[-1].strip(), 'test_pkg' - finally: - pkg_resources.__setstate__(pr_state) + def test_setup_requires_override_nspkg(self): + """ + Like ``test_setup_requires_overrides_version_conflict`` but where the + ``setup_requires`` package is part of a namespace package that has + *already* been imported. + """ + + with contexts.save_pkg_resources_state(): + with contexts.tempdir() as temp_dir: + foobar_1_archive = os.path.join(temp_dir, 'foo.bar-0.1.tar.gz') + make_nspkg_sdist(foobar_1_archive, 'foo.bar', '0.1') + # Now actually go ahead an extract to the temp dir and add the + # extracted path to sys.path so foo.bar v0.1 is importable + foobar_1_dir = os.path.join(temp_dir, 'foo.bar-0.1') + os.mkdir(foobar_1_dir) + with tarfile.open(foobar_1_archive) as tf: + tf.extractall(foobar_1_dir) + sys.path.insert(1, foobar_1_dir) + + dist = PRDistribution(foobar_1_dir, project_name='foo.bar', + version='0.1') + working_set.add(dist) + + template = DALS("""\ + import foo # Even with foo imported first the + # setup_requires package should override + import setuptools + setuptools.setup(**%r) + + if not (hasattr(foo, '__path__') and + len(foo.__path__) == 2): + print('FAIL') + + if 'foo.bar-0.2' not in foo.__path__[0]: + print('FAIL') + """) + + test_pkg = create_setup_requires_package( + temp_dir, 'foo.bar', '0.2', make_nspkg_sdist, template) + + test_setup_py = os.path.join(test_pkg, 'setup.py') -def create_setup_requires_package(path): + with contexts.quiet() as (stdout, stderr): + try: + # Don't even need to install the package, just + # running the setup.py at all is sufficient + run_setup(test_setup_py, ['--name']) + except VersionConflict: + self.fail('Installing setup.py requirements ' + 'caused a VersionConflict') + + assert 'FAIL' not in stdout.getvalue() + lines = stdout.readlines() + assert len(lines) > 0 + assert lines[-1].strip() == 'test_pkg' + + +def make_trivial_sdist(dist_path, distname, version): + """ + Create a simple sdist tarball at dist_path, containing just a simple + setup.py. + """ + + make_sdist(dist_path, [ + ('setup.py', + DALS("""\ + import setuptools + setuptools.setup( + name=%r, + version=%r + ) + """ % (distname, version)))]) + + +def make_nspkg_sdist(dist_path, distname, version): + """ + Make an sdist tarball with distname and version which also contains one + package with the same name as distname. The top-level package is + designated a namespace package). + """ + + parts = distname.split('.') + nspackage = parts[0] + + packages = ['.'.join(parts[:idx]) for idx in range(1, len(parts) + 1)] + + setup_py = DALS("""\ + import setuptools + setuptools.setup( + name=%r, + version=%r, + packages=%r, + namespace_packages=[%r] + ) + """ % (distname, version, packages, nspackage)) + + init = "__import__('pkg_resources').declare_namespace(__name__)" + + files = [('setup.py', setup_py), + (os.path.join(nspackage, '__init__.py'), init)] + for package in packages[1:]: + filename = os.path.join(*(package.split('.') + ['__init__.py'])) + files.append((filename, '')) + + make_sdist(dist_path, files) + + +def make_sdist(dist_path, files): + """ + Create a simple sdist tarball at dist_path, containing the files + listed in ``files`` as ``(filename, content)`` tuples. + """ + + dist = tarfile.open(dist_path, 'w:gz') + + try: + # Python 3 (StringIO gets converted to io module) + MemFile = BytesIO + except AttributeError: + MemFile = StringIO + + try: + for filename, content in files: + file_bytes = MemFile(content.encode('utf-8')) + file_info = tarfile.TarInfo(name=filename) + file_info.size = len(file_bytes.getvalue()) + file_info.mtime = int(time.time()) + dist.addfile(file_info, fileobj=file_bytes) + finally: + dist.close() + + +def create_setup_requires_package(path, distname='foobar', version='0.1', + make_package=make_trivial_sdist, + setup_py_template=None): """Creates a source tree under path for a trivial test package that has a single requirement in setup_requires--a tarball for that requirement is also created and added to the dependency_links argument. + + ``distname`` and ``version`` refer to the name/version of the package that + the test package requires via ``setup_requires``. The name of the test + package itself is just 'test_pkg'. """ test_setup_attrs = { 'name': 'test_pkg', 'version': '0.0', - 'setup_requires': ['foobar==0.1'], + 'setup_requires': ['%s==%s' % (distname, version)], 'dependency_links': [os.path.abspath(path)] } @@ -367,22 +503,17 @@ def create_setup_requires_package(path): test_setup_py = os.path.join(test_pkg, 'setup.py') os.mkdir(test_pkg) - with open(test_setup_py, 'w') as f: - f.write(DALS(""" + if setup_py_template is None: + setup_py_template = DALS("""\ import setuptools setuptools.setup(**%r) - """ % test_setup_attrs)) + """) - foobar_path = os.path.join(path, 'foobar-0.1.tar.gz') - make_trivial_sdist( - foobar_path, - DALS(""" - import setuptools - setuptools.setup( - name='foobar', - version='0.1' - ) - """)) + with open(test_setup_py, 'w') as f: + f.write(setup_py_template % test_setup_attrs) + + foobar_path = os.path.join(path, '%s-%s.tar.gz' % (distname, version)) + make_package(foobar_path, distname, version) return test_pkg -- cgit v1.2.1 From d3de33538948081d9ef39168fde870c977e30115 Mon Sep 17 00:00:00 2001 From: Erik Bray Date: Thu, 31 Dec 2015 14:17:41 -0500 Subject: Fixes the original root cause of #231, and re-enables the test when the tempdir is a symlink (this does not explicitly test that /tmp itself is a symlink, but the effect is the same--only one of the path levels needs to be a symlink to reproduce this isssue) --- pkg_resources/__init__.py | 9 +++++++-- pkg_resources/tests/test_resources.py | 26 ++++++++++++++++++++------ 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/pkg_resources/__init__.py b/pkg_resources/__init__.py index 7becc951..7d2fa7e9 100644 --- a/pkg_resources/__init__.py +++ b/pkg_resources/__init__.py @@ -2182,9 +2182,14 @@ def _handle_ns(packageName, path_item): path = module.__path__ path.append(subpath) loader.load_module(packageName) + + # Ensure that all paths on __path__ have been run through + # normalize_path + normalized_paths = set(_normalize_cached(p) for p in module.__path__) for path_item in path: - if path_item not in module.__path__: - module.__path__.append(path_item) + normalized = _normalize_cached(path_item) + if normalized not in normalized_paths: + module.__path__.append(normalized) return subpath def declare_namespace(packageName): diff --git a/pkg_resources/tests/test_resources.py b/pkg_resources/tests/test_resources.py index 4241765a..ba12d857 100644 --- a/pkg_resources/tests/test_resources.py +++ b/pkg_resources/tests/test_resources.py @@ -610,18 +610,32 @@ class TestNamespaces: def setup_method(self, method): self._ns_pkgs = pkg_resources._namespace_packages.copy() - self._tmpdir = tempfile.mkdtemp(prefix="tests-setuptools-") + + # Further, test case where the temp dir is a symlink, where applicable + # See #231 + if hasattr(os, 'symlink'): + real_tmpdir = tempfile.mkdtemp(prefix="real-tests-setuptools-") + tmpdir_base, tmpdir_name = os.path.split(real_tmpdir) + tmpdir = os.path.join(tmpdir_base, tmpdir_name[5:]) + os.symlink(real_tmpdir, tmpdir) + self._real_tmpdir = real_tmpdir + self._tmpdir = tmpdir + else: + tmpdir = tempfile.mkdtemp(prefix="tests-setuptools-") + self._real_tmpdir = self._tmpdir = tmpdir + os.makedirs(os.path.join(self._tmpdir, "site-pkgs")) self._prev_sys_path = sys.path[:] sys.path.append(os.path.join(self._tmpdir, "site-pkgs")) def teardown_method(self, method): - shutil.rmtree(self._tmpdir) + shutil.rmtree(self._real_tmpdir) + if os.path.islink(self._tmpdir): + os.unlink(self._tmpdir) + pkg_resources._namespace_packages = self._ns_pkgs.copy() sys.path = self._prev_sys_path[:] - @pytest.mark.skipif(os.path.islink(tempfile.gettempdir()), - reason="Test fails when /tmp is a symlink. See #231") def test_two_levels_deep(self): """ Test nested namespace packages @@ -653,7 +667,7 @@ class TestNamespaces: assert pkg_resources._namespace_packages["pkg1"] == ["pkg1.pkg2"] # check the __path__ attribute contains both paths expected = [ - os.path.join(self._tmpdir, "site-pkgs", "pkg1", "pkg2"), - os.path.join(self._tmpdir, "site-pkgs2", "pkg1", "pkg2"), + os.path.join(self._real_tmpdir, "site-pkgs", "pkg1", "pkg2"), + os.path.join(self._real_tmpdir, "site-pkgs2", "pkg1", "pkg2"), ] assert pkg1.pkg2.__path__ == expected -- cgit v1.2.1 From a1a4a1f1358f73ee58e8f068352903f42f88a27a Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 6 Jan 2016 16:07:36 -0500 Subject: Update changelog --- CHANGES.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index 339b137d..e8106c40 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -235,6 +235,8 @@ CHANGES parsed requirements. * Pull Request #133: Removed ``setuptools.tests`` from the installed packages. +* Pull Request #129: Address deprecation warning due to usage + of imp module. ---- 15.2 -- cgit v1.2.1 From ebc54982b1085b05054a75dbcdd16008ac20a60e Mon Sep 17 00:00:00 2001 From: Erik Bray Date: Wed, 6 Jan 2016 17:08:56 -0500 Subject: Sort __path__ entries for namespace packages according to their order in sys.path. This ensures that lookups in __path__ will be the same as sys.path resolution. This also adds a replace argument to Distribution.insert_on meant to be used with the replace argumen to WorkingSet.add. This ensures that new sys.path entries added via WorkingSet.add are inserted at the beginning, rather than appended to the end. This is necessary for consistency with the above change, and kind of makes more sense anyways. This means that if a Distribution is added to a WorkingSet, that replaces a different version of that Distribution, the new version of that Distribution will have its location first on sys.path. --- pkg_resources/__init__.py | 28 +++++++++++++++++----------- pkg_resources/tests/test_resources.py | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 11 deletions(-) diff --git a/pkg_resources/__init__.py b/pkg_resources/__init__.py index 7d2fa7e9..46db5cc7 100644 --- a/pkg_resources/__init__.py +++ b/pkg_resources/__init__.py @@ -755,7 +755,7 @@ class WorkingSet(object): will be called. """ if insert: - dist.insert_on(self.entries, entry) + dist.insert_on(self.entries, entry, replace=replace) if entry is None: entry = dist.location @@ -2183,13 +2183,16 @@ def _handle_ns(packageName, path_item): path.append(subpath) loader.load_module(packageName) - # Ensure that all paths on __path__ have been run through - # normalize_path - normalized_paths = set(_normalize_cached(p) for p in module.__path__) - for path_item in path: - normalized = _normalize_cached(path_item) - if normalized not in normalized_paths: - module.__path__.append(normalized) + # Rebuild mod.__path__ ensuring that all entries are ordered + # corresponding to their sys.path order + sys_path= [(p and _normalize_cached(p) or p) for p in sys.path] + def sort_key(p): + parts = p.split(os.sep) + parts = parts[:-(packageName.count('.') + 1)] + return sys_path.index(_normalize_cached(os.sep.join(parts))) + + path.sort(key=sort_key) + module.__path__[:] = [_normalize_cached(p) for p in path] return subpath def declare_namespace(packageName): @@ -2644,7 +2647,7 @@ class Distribution(object): """Ensure distribution is importable on `path` (default=sys.path)""" if path is None: path = sys.path - self.insert_on(path) + self.insert_on(path, replace=True) if path is sys.path: fixup_namespace_packages(self.location) for pkg in self._get_metadata('namespace_packages.txt'): @@ -2721,7 +2724,7 @@ class Distribution(object): """Return the EntryPoint object for `group`+`name`, or ``None``""" return self.get_entry_map(group).get(name) - def insert_on(self, path, loc = None): + def insert_on(self, path, loc=None, replace=False): """Insert self.location in path before its nearest parent directory""" loc = loc or self.location @@ -2745,7 +2748,10 @@ class Distribution(object): else: if path is sys.path: self.check_version_conflict() - path.append(loc) + if replace: + path.insert(0, loc) + else: + path.append(loc) return # p is the spot where we found or inserted loc; now remove duplicates diff --git a/pkg_resources/tests/test_resources.py b/pkg_resources/tests/test_resources.py index ba12d857..7176cc70 100644 --- a/pkg_resources/tests/test_resources.py +++ b/pkg_resources/tests/test_resources.py @@ -671,3 +671,37 @@ class TestNamespaces: os.path.join(self._real_tmpdir, "site-pkgs2", "pkg1", "pkg2"), ] assert pkg1.pkg2.__path__ == expected + + def test_path_order(self): + """ + Test that if multiple versions of the same namespace package subpackage + are on different sys.path entries, that only the one earliest on + sys.path is imported, and that the namespace package's __path__ is in + the correct order. + + Regression test for https://bitbucket.org/pypa/setuptools/issues/207 + """ + + site_pkgs = ["site-pkgs", "site-pkgs2", "site-pkgs3"] + + ns_str = "__import__('pkg_resources').declare_namespace(__name__)\n" + vers_str = "__version__ = %r" + + for idx, site in enumerate(site_pkgs): + if idx > 0: + sys.path.append(os.path.join(self._tmpdir, site)) + os.makedirs(os.path.join(self._tmpdir, site, "nspkg", "subpkg")) + with open(os.path.join(self._tmpdir, site, "nspkg", + "__init__.py"), "w") as f: + f.write(ns_str) + + with open(os.path.join(self._tmpdir, site, "nspkg", "subpkg", + "__init__.py"), "w") as f: + f.write(vers_str % (idx + 1)) + + import nspkg.subpkg + import nspkg + assert nspkg.__path__ == [os.path.join(self._real_tmpdir, site, + "nspkg") + for site in site_pkgs] + assert nspkg.subpkg.__version__ == 1 -- cgit v1.2.1 From 2b3cf9b12b23ac6beca6808c4c7620aa77f168e3 Mon Sep 17 00:00:00 2001 From: Darjus Loktevic Date: Mon, 11 Jan 2016 23:23:36 +1100 Subject: Remove JythonCommandSpec as it's not required on Jython 2.7 and setuptools no longer supports anything 2.5, but had to test for 'Jython on Windows' in two other places --- setup.py | 3 ++- setuptools/command/easy_install.py | 48 ++++------------------------------- setuptools/tests/test_easy_install.py | 45 -------------------------------- 3 files changed, 7 insertions(+), 89 deletions(-) diff --git a/setup.py b/setup.py index dfb578a1..5378e6c5 100755 --- a/setup.py +++ b/setup.py @@ -59,7 +59,8 @@ force_windows_specific_files = ( os.environ.get("SETUPTOOLS_INSTALL_WINDOWS_SPECIFIC_FILES") not in (None, "", "0") ) -if sys.platform == 'win32' or force_windows_specific_files: +if (sys.platform == 'win32' or (os.name == 'java' and os._name == 'nt')) \ + or force_windows_specific_files: package_data.setdefault('setuptools', []).extend(['*.exe']) package_data.setdefault('setuptools.command', []).extend(['*.xml']) diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index a11618d1..fccfade2 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -1876,17 +1876,6 @@ def chmod(path, mode): log.debug("chmod failed: %s", e) -def fix_jython_executable(executable, options): - warnings.warn("Use JythonCommandSpec", DeprecationWarning, stacklevel=2) - - if not JythonCommandSpec.relevant(): - return executable - - cmd = CommandSpec.best().from_param(executable) - cmd.install_options(options) - return cmd.as_header().lstrip('#!').rstrip('\n') - - class CommandSpec(list): """ A command spec for a #! header, specified as a list of arguments akin to @@ -1901,7 +1890,7 @@ class CommandSpec(list): """ Choose the best CommandSpec class based on environmental conditions. """ - return cls if not JythonCommandSpec.relevant() else JythonCommandSpec + return cls @classmethod def _sys_executable(cls): @@ -1968,36 +1957,6 @@ class WindowsCommandSpec(CommandSpec): split_args = dict(posix=False) -class JythonCommandSpec(CommandSpec): - @classmethod - def relevant(cls): - return ( - sys.platform.startswith('java') - and - __import__('java').lang.System.getProperty('os.name') != 'Linux' - ) - - def as_header(self): - """ - Workaround Jython's sys.executable being a .sh (an invalid - shebang line interpreter) - """ - if not is_sh(self[0]): - return super(JythonCommandSpec, self).as_header() - - if self.options: - # Can't apply the workaround, leave it broken - log.warn( - "WARNING: Unable to adapt shebang line for Jython," - " the following script is NOT executable\n" - " see http://bugs.jython.org/issue1112 for" - " more information.") - return super(JythonCommandSpec, self).as_header() - - items = ['/usr/bin/env'] + self + list(self.options) - return self._render(items) - - class ScriptWriter(object): """ Encapsulates behavior around writing entry point scripts for console and @@ -2074,7 +2033,10 @@ class ScriptWriter(object): """ Select the best ScriptWriter for this environment. """ - return WindowsScriptWriter.best() if sys.platform == 'win32' else cls + if sys.platform == 'win32' or (os.name == 'java' and os._name == 'nt'): + return WindowsScriptWriter.best() + else: + return cls @classmethod def _get_script_args(cls, type_, name, header, script_text): diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py index 94e317b3..93f94b85 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -427,51 +427,6 @@ class TestScriptHeader: expected = '#!"%s"\n' % self.exe_with_spaces assert actual == expected - @pytest.mark.xfail( - six.PY3 and is_ascii, - reason="Test fails in this locale on Python 3" - ) - @mock.patch.dict(sys.modules, java=mock.Mock(lang=mock.Mock(System= - mock.Mock(getProperty=mock.Mock(return_value=""))))) - @mock.patch('sys.platform', 'java1.5.0_13') - def test_get_script_header_jython_workaround(self, tmpdir): - # Create a mock sys.executable that uses a shebang line - header = DALS(""" - #!/usr/bin/python - # -*- coding: utf-8 -*- - """) - exe = tmpdir / 'exe.py' - with exe.open('w') as f: - f.write(header) - - exe = ei.nt_quote_arg(os.path.normpath(str(exe))) - - # Make sure Windows paths are quoted properly before they're sent - # through shlex.split by get_script_header - executable = '"%s"' % exe if os.path.splitdrive(exe)[0] else exe - - header = ei.ScriptWriter.get_script_header('#!/usr/local/bin/python', - executable=executable) - assert header == '#!/usr/bin/env %s\n' % exe - - expect_out = 'stdout' if sys.version_info < (2,7) else 'stderr' - - with contexts.quiet() as (stdout, stderr): - # When options are included, generate a broken shebang line - # with a warning emitted - candidate = ei.ScriptWriter.get_script_header('#!/usr/bin/python -x', - executable=executable) - assert candidate == '#!%s -x\n' % exe - output = locals()[expect_out] - assert 'Unable to adapt shebang line' in output.getvalue() - - with contexts.quiet() as (stdout, stderr): - candidate = ei.ScriptWriter.get_script_header('#!/usr/bin/python', - executable=self.non_ascii_exe) - assert candidate == '#!%s -x\n' % self.non_ascii_exe - output = locals()[expect_out] - assert 'Unable to adapt shebang line' in output.getvalue() - class TestCommandSpec: def test_custom_launch_command(self): -- cgit v1.2.1 From d293e9bcca56765b0ec06d6d7f542cc2c71ad001 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 15 Jan 2016 20:06:17 -0500 Subject: Added tag 19.3 for changeset 32bba9bf8cce --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index ab249d8f..4f89a01a 100644 --- a/.hgtags +++ b/.hgtags @@ -234,3 +234,4 @@ cc41477ecf92f221c113736fac2830bf8079d40c 19.0 0a2a3d89416e1642cf6f41d22dbc07b3d3c15a4d 19.1.1 5d24cf9d1ced76c406ab3c4a94c25d1fe79b94bc 19.2 66fa131a0d77a1b0e6f89ccb76b254cfb07d3da3 19.3b1 +32bba9bf8cce8350b560a7591c9ef5884a194211 19.3 -- cgit v1.2.1 From ecc8c659b45cec0b69335a74445de2be500c382a Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 15 Jan 2016 20:08:11 -0500 Subject: Bumped to 19.4 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setuptools/version.py b/setuptools/version.py index 09bbb730..7ff48baa 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '19.3' +__version__ = '19.4' -- cgit v1.2.1 From 434aef220e6ec7cfc609bce631ef8528c930c20c Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 16 Jan 2016 06:11:13 -0500 Subject: Move trailing comment to docstring --- setuptools/command/build_py.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/setuptools/command/build_py.py b/setuptools/command/build_py.py index 8a50f032..32e37e52 100644 --- a/setuptools/command/build_py.py +++ b/setuptools/command/build_py.py @@ -59,7 +59,8 @@ class build_py(orig.build_py, Mixin2to3): self.byte_compile(orig.build_py.get_outputs(self, include_bytecode=0)) def __getattr__(self, attr): - if attr == 'data_files': # lazily compute data files + "lazily compute data files" + if attr == 'data_files': self.data_files = files = self._get_data_files() return files return orig.build_py.__getattr__(self, attr) -- cgit v1.2.1 From f55db00043f3f47b7121c42d54433bc80a01c243 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 16 Jan 2016 06:11:54 -0500 Subject: Remove superfluous local variable --- setuptools/command/build_py.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setuptools/command/build_py.py b/setuptools/command/build_py.py index 32e37e52..c24646c3 100644 --- a/setuptools/command/build_py.py +++ b/setuptools/command/build_py.py @@ -61,8 +61,8 @@ class build_py(orig.build_py, Mixin2to3): def __getattr__(self, attr): "lazily compute data files" if attr == 'data_files': - self.data_files = files = self._get_data_files() - return files + self.data_files = self._get_data_files() + return self.data_files return orig.build_py.__getattr__(self, attr) def build_module(self, module, module_file, package): -- cgit v1.2.1 From 775cb73ed72e87951254bbbe373951be9caac4df Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 16 Jan 2016 06:16:11 -0500 Subject: Extract function for getting data files for package. --- setuptools/command/build_py.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/setuptools/command/build_py.py b/setuptools/command/build_py.py index c24646c3..3ddc7673 100644 --- a/setuptools/command/build_py.py +++ b/setuptools/command/build_py.py @@ -75,8 +75,9 @@ class build_py(orig.build_py, Mixin2to3): def _get_data_files(self): """Generate list of '(package,src_dir,build_dir,filenames)' tuples""" self.analyze_manifest() - data = [] - for package in self.packages or (): + return list(map(self._get_pkg_data_files, self.packages or ())) + + def _get_pkg_data_files(self, package): # Locate package source directory src_dir = self.get_package_dir(package) @@ -90,8 +91,7 @@ class build_py(orig.build_py, Mixin2to3): filenames = [ file[plen:] for file in self.find_data_files(package, src_dir) ] - data.append((package, src_dir, build_dir, filenames)) - return data + return package, src_dir, build_dir, filenames def find_data_files(self, package, src_dir): """Return filenames for package's data files in 'src_dir'""" -- cgit v1.2.1 From ddfbfa731e2cf73dc03b5a3345996afac843441e Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 16 Jan 2016 06:16:39 -0500 Subject: Reindent --- setuptools/command/build_py.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/setuptools/command/build_py.py b/setuptools/command/build_py.py index 3ddc7673..5021bd1f 100644 --- a/setuptools/command/build_py.py +++ b/setuptools/command/build_py.py @@ -78,20 +78,20 @@ class build_py(orig.build_py, Mixin2to3): return list(map(self._get_pkg_data_files, self.packages or ())) def _get_pkg_data_files(self, package): - # Locate package source directory - src_dir = self.get_package_dir(package) + # Locate package source directory + src_dir = self.get_package_dir(package) - # Compute package build directory - build_dir = os.path.join(*([self.build_lib] + package.split('.'))) + # Compute package build directory + build_dir = os.path.join(*([self.build_lib] + package.split('.'))) - # Length of path to strip from found files - plen = len(src_dir) + 1 + # Length of path to strip from found files + plen = len(src_dir) + 1 - # Strip directory from globbed filenames - filenames = [ - file[plen:] for file in self.find_data_files(package, src_dir) - ] - return package, src_dir, build_dir, filenames + # Strip directory from globbed filenames + filenames = [ + file[plen:] for file in self.find_data_files(package, src_dir) + ] + return package, src_dir, build_dir, filenames def find_data_files(self, package, src_dir): """Return filenames for package's data files in 'src_dir'""" -- cgit v1.2.1 From 0f590c0d72709128f32c23437fe0183386c69d1c Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 16 Jan 2016 06:33:04 -0500 Subject: Prefer relpath to string slicing for computing a path relative to a base. Fixes #341. --- CHANGES.txt | 6 ++++++ setuptools/command/build_py.py | 6 ++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index e8106c40..c8a9f8ab 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -2,6 +2,12 @@ CHANGES ======= +19.3.1 +------ + +* Issue #341: Correct error in path handling of package data + files in ``build_py`` command when package is empty. + ---- 19.3 ---- diff --git a/setuptools/command/build_py.py b/setuptools/command/build_py.py index 5021bd1f..0c1026aa 100644 --- a/setuptools/command/build_py.py +++ b/setuptools/command/build_py.py @@ -84,12 +84,10 @@ class build_py(orig.build_py, Mixin2to3): # Compute package build directory build_dir = os.path.join(*([self.build_lib] + package.split('.'))) - # Length of path to strip from found files - plen = len(src_dir) + 1 - # Strip directory from globbed filenames filenames = [ - file[plen:] for file in self.find_data_files(package, src_dir) + os.path.relpath(file, src_dir) + for file in self.find_data_files(package, src_dir) ] return package, src_dir, build_dir, filenames -- cgit v1.2.1 From 8af3b6ef5b4173a0d0d6735147c98c882ae98344 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 16 Jan 2016 06:54:00 -0500 Subject: Always use Python 3 version of map --- pkg_resources/__init__.py | 2 +- pkg_resources/tests/test_pkg_resources.py | 2 ++ pkg_resources/tests/test_resources.py | 4 +++- setuptools/__init__.py | 2 +- setuptools/command/alias.py | 2 ++ setuptools/command/build_py.py | 1 + setuptools/command/easy_install.py | 2 +- setuptools/command/egg_info.py | 1 + setuptools/command/install_egg_info.py | 2 ++ setuptools/command/test.py | 1 + setuptools/dist.py | 1 + setuptools/extension.py | 2 ++ setuptools/package_index.py | 2 +- setuptools/sandbox.py | 2 +- setuptools/ssl_support.py | 2 +- setuptools/tests/test_dist_info.py | 2 ++ setuptools/tests/test_egg_info.py | 2 ++ setuptools/tests/test_sdist.py | 1 + 18 files changed, 26 insertions(+), 7 deletions(-) diff --git a/pkg_resources/__init__.py b/pkg_resources/__init__.py index 7becc951..8382571e 100644 --- a/pkg_resources/__init__.py +++ b/pkg_resources/__init__.py @@ -46,7 +46,7 @@ except ImportError: import imp as _imp from pkg_resources.extern import six -from pkg_resources.extern.six.moves import urllib +from pkg_resources.extern.six.moves import urllib, map # capture these to bypass sandboxing from os import utime diff --git a/pkg_resources/tests/test_pkg_resources.py b/pkg_resources/tests/test_pkg_resources.py index 31eee635..8b276ffc 100644 --- a/pkg_resources/tests/test_pkg_resources.py +++ b/pkg_resources/tests/test_pkg_resources.py @@ -12,6 +12,8 @@ import stat import distutils.dist import distutils.command.install_egg_info +from pkg_resources.extern.six.moves import map + import pytest import pkg_resources diff --git a/pkg_resources/tests/test_resources.py b/pkg_resources/tests/test_resources.py index 4241765a..84133a32 100644 --- a/pkg_resources/tests/test_resources.py +++ b/pkg_resources/tests/test_resources.py @@ -4,6 +4,8 @@ import tempfile import shutil import string +from pkg_resources.extern.six.moves import map + import pytest from pkg_resources.extern import packaging @@ -158,7 +160,7 @@ class TestDistro: for i in range(3): targets = list(ws.resolve(parse_requirements("Foo"), ad)) assert targets == [Foo] - list(map(ws.add,targets)) + list(map(ws.add, targets)) with pytest.raises(VersionConflict): ws.resolve(parse_requirements("Foo==0.9"), ad) ws = WorkingSet([]) # reset diff --git a/setuptools/__init__.py b/setuptools/__init__.py index ec0d5dc2..67b57e4f 100644 --- a/setuptools/__init__.py +++ b/setuptools/__init__.py @@ -8,7 +8,7 @@ from distutils.core import Command as _Command from distutils.util import convert_path from fnmatch import fnmatchcase -from setuptools.extern.six.moves import filterfalse +from setuptools.extern.six.moves import filterfalse, map import setuptools.version from setuptools.extension import Extension diff --git a/setuptools/command/alias.py b/setuptools/command/alias.py index 452a9244..4532b1cc 100755 --- a/setuptools/command/alias.py +++ b/setuptools/command/alias.py @@ -1,5 +1,7 @@ from distutils.errors import DistutilsOptionError +from setuptools.extern.six.moves import map + from setuptools.command.setopt import edit_config, option_base, config_file diff --git a/setuptools/command/build_py.py b/setuptools/command/build_py.py index 0c1026aa..8623c777 100644 --- a/setuptools/command/build_py.py +++ b/setuptools/command/build_py.py @@ -9,6 +9,7 @@ import distutils.errors import collections import itertools +from setuptools.extern.six.moves import map try: from setuptools.lib2to3_ex import Mixin2to3 diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index a11618d1..d3c0acfb 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -41,7 +41,7 @@ import shlex import io from setuptools.extern import six -from setuptools.extern.six.moves import configparser +from setuptools.extern.six.moves import configparser, map from setuptools import Command from setuptools.sandbox import run_setup diff --git a/setuptools/command/egg_info.py b/setuptools/command/egg_info.py index 18a3105f..d1bd9b04 100755 --- a/setuptools/command/egg_info.py +++ b/setuptools/command/egg_info.py @@ -15,6 +15,7 @@ import warnings import time from setuptools.extern import six +from setuptools.extern.six.moves import map from setuptools import Command from setuptools.command.sdist import sdist diff --git a/setuptools/command/install_egg_info.py b/setuptools/command/install_egg_info.py index fd0f118b..f777538f 100755 --- a/setuptools/command/install_egg_info.py +++ b/setuptools/command/install_egg_info.py @@ -1,6 +1,8 @@ from distutils import log, dir_util import os +from setuptools.extern.six.moves import map + from setuptools import Command from setuptools.archive_util import unpack_archive import pkg_resources diff --git a/setuptools/command/test.py b/setuptools/command/test.py index 3a2a9b93..371e913b 100644 --- a/setuptools/command/test.py +++ b/setuptools/command/test.py @@ -3,6 +3,7 @@ from unittest import TestLoader import sys from setuptools.extern import six +from setuptools.extern.six.moves import map from pkg_resources import (resource_listdir, resource_exists, normalize_path, working_set, _namespace_packages, diff --git a/setuptools/dist.py b/setuptools/dist.py index 4964a9e8..77855415 100644 --- a/setuptools/dist.py +++ b/setuptools/dist.py @@ -14,6 +14,7 @@ from distutils.errors import (DistutilsOptionError, DistutilsPlatformError, DistutilsSetupError) from setuptools.extern import six +from setuptools.extern.six.moves import map from pkg_resources.extern import packaging from setuptools.depends import Require diff --git a/setuptools/extension.py b/setuptools/extension.py index 35eb7c7c..d10609b6 100644 --- a/setuptools/extension.py +++ b/setuptools/extension.py @@ -5,6 +5,8 @@ import distutils.core import distutils.errors import distutils.extension +from setuptools.extern.six.moves import map + from .dist import _get_unpatched from . import msvc9_support diff --git a/setuptools/package_index.py b/setuptools/package_index.py index ea136c09..c53343e4 100755 --- a/setuptools/package_index.py +++ b/setuptools/package_index.py @@ -15,7 +15,7 @@ except ImportError: from urllib2 import splituser from setuptools.extern import six -from setuptools.extern.six.moves import urllib, http_client, configparser +from setuptools.extern.six.moves import urllib, http_client, configparser, map from pkg_resources import ( CHECKOUT_DIST, Distribution, BINARY_DIST, normalize_path, SOURCE_DIST, diff --git a/setuptools/sandbox.py b/setuptools/sandbox.py index 37035f37..668bcac7 100755 --- a/setuptools/sandbox.py +++ b/setuptools/sandbox.py @@ -9,7 +9,7 @@ import contextlib import pickle from setuptools.extern import six -from setuptools.extern.six.moves import builtins +from setuptools.extern.six.moves import builtins, map import pkg_resources diff --git a/setuptools/ssl_support.py b/setuptools/ssl_support.py index 7baedd19..511d2fa8 100644 --- a/setuptools/ssl_support.py +++ b/setuptools/ssl_support.py @@ -3,7 +3,7 @@ import socket import atexit import re -from setuptools.extern.six.moves import urllib, http_client +from setuptools.extern.six.moves import urllib, http_client, map import pkg_resources from pkg_resources import ResolutionError, ExtractionError diff --git a/setuptools/tests/test_dist_info.py b/setuptools/tests/test_dist_info.py index 6d0ab587..abd0a763 100644 --- a/setuptools/tests/test_dist_info.py +++ b/setuptools/tests/test_dist_info.py @@ -4,6 +4,8 @@ import os import shutil import tempfile +from setuptools.extern.six.moves import map + import pytest import pkg_resources diff --git a/setuptools/tests/test_egg_info.py b/setuptools/tests/test_egg_info.py index 333d11d6..7d51585b 100644 --- a/setuptools/tests/test_egg_info.py +++ b/setuptools/tests/test_egg_info.py @@ -1,6 +1,8 @@ import os import stat +from setuptools.extern.six.moves import map + import pytest from . import environment diff --git a/setuptools/tests/test_sdist.py b/setuptools/tests/test_sdist.py index 753b507d..d2a1f1bb 100644 --- a/setuptools/tests/test_sdist.py +++ b/setuptools/tests/test_sdist.py @@ -10,6 +10,7 @@ import contextlib import io from setuptools.extern import six +from setuptools.extern.six.moves import map import pytest -- cgit v1.2.1 From 71429b10081c7ae0ad596c33d95b735af80f9248 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 16 Jan 2016 10:41:47 -0500 Subject: Fix two failures in sorting where filename parts became a factor in the version. Ref #432. --- scripts/upload-old-releases-as-zip.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/scripts/upload-old-releases-as-zip.py b/scripts/upload-old-releases-as-zip.py index 38cfcd55..d718e3bb 100644 --- a/scripts/upload-old-releases-as-zip.py +++ b/scripts/upload-old-releases-as-zip.py @@ -195,11 +195,19 @@ class SetuptoolsOldReleasesWithoutZip: if e.errno != errno.EEXIST: raise e + @staticmethod + def version_from_filename(filename): + basename = os.path.basename(filename) + name, ext = os.path.splitext(basename) + if name.endswith('.tar'): + name, ext2 = os.path.splitext(name) + return LooseVersion(name) + def convert_targz_to_zip(self): print("Converting the tar.gz to zip...") files = glob.glob('%s/*.tar.gz' % self.dirpath) total_converted = 0 - for targz in sorted(files, key=LooseVersion): + for targz in sorted(files, key=self.version_from_filename): # Extract and remove tar. tar = tarfile.open(targz) tar.extractall(path=self.dirpath) @@ -230,8 +238,7 @@ class SetuptoolsOldReleasesWithoutZip: def upload_zips_to_pypi(self): print('Uploading to pypi...') - zips = sorted(glob.glob('%s/*.zip' % self.dirpath), key=LooseVersion) - print("simulated upload of", zips); return + zips = sorted(glob.glob('%s/*.zip' % self.dirpath), key=self.version_from_filename) upload.upload(dists=zips) -- cgit v1.2.1 From b6056e0aa0de04bc1fe702f299d8187a8c224a03 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 16 Jan 2016 10:51:45 -0500 Subject: Copy all the defaults from twine.commands.upload, as they're not exposed in the API. Ref #432 --- scripts/upload-old-releases-as-zip.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/scripts/upload-old-releases-as-zip.py b/scripts/upload-old-releases-as-zip.py index d718e3bb..94fd1ce8 100644 --- a/scripts/upload-old-releases-as-zip.py +++ b/scripts/upload-old-releases-as-zip.py @@ -239,7 +239,20 @@ class SetuptoolsOldReleasesWithoutZip: def upload_zips_to_pypi(self): print('Uploading to pypi...') zips = sorted(glob.glob('%s/*.zip' % self.dirpath), key=self.version_from_filename) - upload.upload(dists=zips) + upload.upload( + dists=zips, + repository='pypi', + sign=False, + identity=None, + username=None, + password=None, + comment=None, + sign_with='gpg', + config_file='~/.pypirc', + skip_existing=False, + cert=None, + client_cert=None, + ) if __name__ == '__main__': -- cgit v1.2.1 From 3f702d545e8fcb20d60224420b9c3b20a0700608 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 16 Jan 2016 10:55:18 -0500 Subject: Omit cert and client_cert, the latest release of twine is different than what is seen in master. --- scripts/upload-old-releases-as-zip.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/scripts/upload-old-releases-as-zip.py b/scripts/upload-old-releases-as-zip.py index 94fd1ce8..9737337c 100644 --- a/scripts/upload-old-releases-as-zip.py +++ b/scripts/upload-old-releases-as-zip.py @@ -250,8 +250,6 @@ class SetuptoolsOldReleasesWithoutZip: sign_with='gpg', config_file='~/.pypirc', skip_existing=False, - cert=None, - client_cert=None, ) -- cgit v1.2.1 From 3c6446900f27be1c954e0123a94d797bd6e70b83 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 16 Jan 2016 11:06:11 -0500 Subject: Pin to 1.6.4 due to https://github.com/pypa/twine/issues/158. Ref #432. --- scripts/upload-old-releases-as-zip.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/upload-old-releases-as-zip.py b/scripts/upload-old-releases-as-zip.py index 9737337c..e3047fde 100644 --- a/scripts/upload-old-releases-as-zip.py +++ b/scripts/upload-old-releases-as-zip.py @@ -3,7 +3,7 @@ # declare and require dependencies __requires__ = [ - 'twine', + 'twine==1.6.4', ]; __import__('pkg_resources') import errno -- cgit v1.2.1 From 70697b3a8c795a25de56a30d41cca76ad18d78fb Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 16 Jan 2016 11:20:04 -0500 Subject: Remove script as it's no longer needed. Fixes #432. --- scripts/upload-old-releases-as-zip.py | 260 ---------------------------------- 1 file changed, 260 deletions(-) delete mode 100644 scripts/upload-old-releases-as-zip.py diff --git a/scripts/upload-old-releases-as-zip.py b/scripts/upload-old-releases-as-zip.py deleted file mode 100644 index e3047fde..00000000 --- a/scripts/upload-old-releases-as-zip.py +++ /dev/null @@ -1,260 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -# declare and require dependencies -__requires__ = [ - 'twine==1.6.4', -]; __import__('pkg_resources') - -import errno -import glob -import hashlib -import json -import os -import shutil -import tarfile -import codecs -import urllib.request -import urllib.parse -import urllib.error -from distutils.version import LooseVersion - -from twine.commands import upload - - -OK = '\033[92m' -FAIL = '\033[91m' -END = '\033[0m' -DISTRIBUTION = "setuptools" - - -class SetuptoolsOldReleasesWithoutZip: - """docstring for SetuptoolsOldReleases""" - - def __init__(self): - self.dirpath = './dist' - os.makedirs(self.dirpath, exist_ok=True) - print("Downloading %s releases..." % DISTRIBUTION) - print("All releases will be downloaded to %s" % self.dirpath) - self.data_json_setuptools = self.get_json_data(DISTRIBUTION) - self.valid_releases_numbers = sorted([ - release - for release in self.data_json_setuptools['releases'] - # This condition is motivated by 13.0 release, which - # comes as "13.0": [], in the json - if self.data_json_setuptools['releases'][release] - ], key=LooseVersion) - self.total_downloaded_ok = 0 - - def get_json_data(self, package_name): - """ - "releases": { - "0.7.2": [ - { - "has_sig": false, - "upload_time": "2013-06-09T16:10:00", - "comment_text": "", - "python_version": "source", - "url": "https://pypi.python.org/packages/source/s/setuptools/setuptools-0.7.2.tar.gz", # NOQA - "md5_digest": "de44cd90f8a1c713d6c2bff67bbca65d", - "downloads": 159014, - "filename": "setuptools-0.7.2.tar.gz", - "packagetype": "sdist", - "size": 633077 - } - ], - "0.7.3": [ - { - "has_sig": false, - "upload_time": "2013-06-18T21:08:56", - "comment_text": "", - "python_version": "source", - "url": "https://pypi.python.org/packages/source/s/setuptools/setuptools-0.7.3.tar.gz", # NOQA - "md5_digest": "c854adacbf9067d330a847f06f7a8eba", - "downloads": 30594, - "filename": "setuptools-0.7.3.tar.gz", - "packagetype": "sdist", - "size": 751152 - } - ], - "12.3": [ - { - "has_sig": false, - "upload_time": "2015-02-26T19:15:51", - "comment_text": "", - "python_version": "3.4", - "url": "https://pypi.python.org/packages/3.4/s/setuptools/setuptools-12.3-py2.py3-none-any.whl", # NOQA - "md5_digest": "31f51a38497a70efadf5ce8d4c2211ab", - "downloads": 288451, - "filename": "setuptools-12.3-py2.py3-none-any.whl", - "packagetype": "bdist_wheel", - "size": 501904 - }, - { - "has_sig": false, - "upload_time": "2015-02-26T19:15:43", - "comment_text": "", - "python_version": "source", - "url": "https://pypi.python.org/packages/source/s/setuptools/setuptools-12.3.tar.gz", # NOQA - "md5_digest": "67614b6d560fa4f240e99cd553ec7f32", - "downloads": 110109, - "filename": "setuptools-12.3.tar.gz", - "packagetype": "sdist", - "size": 635025 - }, - { - "has_sig": false, - "upload_time": "2015-02-26T19:15:47", - "comment_text": "", - "python_version": "source", - "url": "https://pypi.python.org/packages/source/s/setuptools/setuptools-12.3.zip", # NOQA - "md5_digest": "abc799e7db6e7281535bf342bfc41a12", - "downloads": 67539, - "filename": "setuptools-12.3.zip", - "packagetype": "sdist", - "size": 678783 - } - ], - """ - url = "https://pypi.python.org/pypi/%s/json" % (package_name,) - resp = urllib.request.urlopen(urllib.request.Request(url)) - charset = resp.info().get_content_charset() - reader = codecs.getreader(charset)(resp) - data = json.load(reader) - - # Mainly for debug. - json_filename = "%s/%s.json" % (self.dirpath, DISTRIBUTION) - with open(json_filename, 'w') as outfile: - json.dump( - data, - outfile, - sort_keys=True, - indent=4, - separators=(',', ': '), - ) - - return data - - def get_setuptools_releases_without_zip_counterpart(self): - # Get set(all_valid_releases) - set(releases_with_zip), so now we have - # the releases without zip. - return set(self.valid_releases_numbers) - set([ - release - for release in self.valid_releases_numbers - for same_version_release_dict in self.data_json_setuptools['releases'][release] # NOQA - if 'zip' in same_version_release_dict['filename'] - ]) - - def download_setuptools_releases_without_zip_counterpart(self): - try: - releases_without_zip = self.get_setuptools_releases_without_zip_counterpart() # NOQA - failed_md5_releases = [] - # This is a "strange" loop, going through all releases and - # testing only the release I need to download, but I thought it - # would be mouch more readable than trying to iterate through - # releases I need and get into traverse hell values inside dicts - # inside dicts of the json to get the distribution's url to - # download. - for release in self.valid_releases_numbers: - if release in releases_without_zip: - for same_version_release_dict in self.data_json_setuptools['releases'][release]: # NOQA - if 'tar.gz' in same_version_release_dict['filename']: - print("Downloading %s..." % release) - local_file = '%s/%s' % ( - self.dirpath, - same_version_release_dict["filename"] - ) - urllib.request.urlretrieve( - same_version_release_dict["url"], - local_file - ) - targz = open(local_file, 'rb').read() - hexdigest = hashlib.md5(targz).hexdigest() - if (hexdigest != same_version_release_dict['md5_digest']): # NOQA - print(FAIL + "FAIL: md5 for %s didn't match!" % release + END) # NOQA - failed_md5_releases.append(release) - else: - self.total_downloaded_ok += 1 - print('Total releases without zip: %s' % len(releases_without_zip)) - print('Total downloaded: %s' % self.total_downloaded_ok) - if failed_md5_releases: - msg = FAIL + ( - "FAIL: these releases %s failed the md5 check!" % - ','.join(failed_md5_releases) - ) + END - raise Exception(msg) - elif self.total_downloaded_ok != len(releases_without_zip): - msg = FAIL + ( - "FAIL: Unknown error occured. Please check the logs." - ) + END - raise Exception(msg) - else: - print(OK + "All releases downloaded and md5 checked." + END) - - except OSError as e: - if e.errno != errno.EEXIST: - raise e - - @staticmethod - def version_from_filename(filename): - basename = os.path.basename(filename) - name, ext = os.path.splitext(basename) - if name.endswith('.tar'): - name, ext2 = os.path.splitext(name) - return LooseVersion(name) - - def convert_targz_to_zip(self): - print("Converting the tar.gz to zip...") - files = glob.glob('%s/*.tar.gz' % self.dirpath) - total_converted = 0 - for targz in sorted(files, key=self.version_from_filename): - # Extract and remove tar. - tar = tarfile.open(targz) - tar.extractall(path=self.dirpath) - tar.close() - os.remove(targz) - - # Zip the extracted tar. - setuptools_folder_path = targz.replace('.tar.gz', '') - setuptools_folder_name = setuptools_folder_path.split("/")[-1] - print(setuptools_folder_name) - shutil.make_archive( - setuptools_folder_path, - 'zip', - self.dirpath, - setuptools_folder_name - ) - # Exclude extracted tar folder. - shutil.rmtree(setuptools_folder_path.replace('.zip', '')) - total_converted += 1 - print('Total converted: %s' % total_converted) - if self.total_downloaded_ok != total_converted: - msg = FAIL + ( - "FAIL: Total number of downloaded releases is different" - " from converted ones. Please check the logs." - ) + END - raise Exception(msg) - print("Done with the tar.gz->zip. Check folder %s." % main.dirpath) - - def upload_zips_to_pypi(self): - print('Uploading to pypi...') - zips = sorted(glob.glob('%s/*.zip' % self.dirpath), key=self.version_from_filename) - upload.upload( - dists=zips, - repository='pypi', - sign=False, - identity=None, - username=None, - password=None, - comment=None, - sign_with='gpg', - config_file='~/.pypirc', - skip_existing=False, - ) - - -if __name__ == '__main__': - main = SetuptoolsOldReleasesWithoutZip() - main.download_setuptools_releases_without_zip_counterpart() - main.convert_targz_to_zip() - main.upload_zips_to_pypi() -- cgit v1.2.1 From 38f276fb8b9ef77c7f34d11460f0ba072def3467 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 16 Jan 2016 17:17:52 -0500 Subject: Update changelog --- CHANGES.txt | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index c8a9f8ab..06c6aad1 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -2,11 +2,17 @@ CHANGES ======= -19.3.1 ------- +19.4 +---- * Issue #341: Correct error in path handling of package data files in ``build_py`` command when package is empty. +* Distribute #323, Issue #141, Issue #207, and + Pull Request #167: Another implementation of + ``pkg_resources.WorkingSet`` and ``pkg_resources.Distribution`` + that supports replacing an extant package with a new one, + allowing for setup_requires dependencies to supersede installed + packages for the session. ---- 19.3 -- cgit v1.2.1 From efb37fc9c2e20f79f742e976e1bcd7fa2a27c5f0 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 16 Jan 2016 17:23:18 -0500 Subject: Just use BytesIO --- setuptools/tests/test_easy_install.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py index 4f9e52d1..77cf8da1 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -464,15 +464,9 @@ def make_sdist(dist_path, files): dist = tarfile.open(dist_path, 'w:gz') - try: - # Python 3 (StringIO gets converted to io module) - MemFile = BytesIO - except AttributeError: - MemFile = StringIO - try: for filename, content in files: - file_bytes = MemFile(content.encode('utf-8')) + file_bytes = io.BytesIO(content.encode('utf-8')) file_info = tarfile.TarInfo(name=filename) file_info.size = len(file_bytes.getvalue()) file_info.mtime = int(time.time()) -- cgit v1.2.1 From d716b3c03b111512133126a5f42c7553bfb43174 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 16 Jan 2016 17:32:19 -0500 Subject: Re-use tarfile_open for Python 2.6 compatibilty. --- setuptools/tests/test_easy_install.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py index 77cf8da1..895ce7aa 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -364,7 +364,7 @@ class TestSetupRequires: # extracted path to sys.path so foo.bar v0.1 is importable foobar_1_dir = os.path.join(temp_dir, 'foo.bar-0.1') os.mkdir(foobar_1_dir) - with tarfile.open(foobar_1_archive) as tf: + with tarfile_open(foobar_1_archive) as tf: tf.extractall(foobar_1_dir) sys.path.insert(1, foobar_1_dir) @@ -462,17 +462,13 @@ def make_sdist(dist_path, files): listed in ``files`` as ``(filename, content)`` tuples. """ - dist = tarfile.open(dist_path, 'w:gz') - - try: + with tarfile_open(dist_path, 'w:gz') as dist: for filename, content in files: file_bytes = io.BytesIO(content.encode('utf-8')) file_info = tarfile.TarInfo(name=filename) file_info.size = len(file_bytes.getvalue()) file_info.mtime = int(time.time()) dist.addfile(file_info, fileobj=file_bytes) - finally: - dist.close() def create_setup_requires_package(path, distname='foobar', version='0.1', -- cgit v1.2.1 From 670a9c895e6180e72a069f5208f0ed2ae38b9728 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 16 Jan 2016 17:38:00 -0500 Subject: Get VersionConflict from pkg_resources. --- setuptools/tests/test_easy_install.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py index 895ce7aa..99ac7317 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -396,7 +396,7 @@ class TestSetupRequires: # Don't even need to install the package, just # running the setup.py at all is sufficient run_setup(test_setup_py, ['--name']) - except VersionConflict: + except pkg_resources.VersionConflict: self.fail('Installing setup.py requirements ' 'caused a VersionConflict') -- cgit v1.2.1 From 400d10f9ed6d353fcd349727342c153839eb8a69 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 16 Jan 2016 17:38:44 -0500 Subject: Added tag 19.4 for changeset f47f3671508b --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 4f89a01a..1e7eeff0 100644 --- a/.hgtags +++ b/.hgtags @@ -235,3 +235,4 @@ cc41477ecf92f221c113736fac2830bf8079d40c 19.0 5d24cf9d1ced76c406ab3c4a94c25d1fe79b94bc 19.2 66fa131a0d77a1b0e6f89ccb76b254cfb07d3da3 19.3b1 32bba9bf8cce8350b560a7591c9ef5884a194211 19.3 +f47f3671508b015e9bb735603d3a0a6ec6a77b01 19.4 -- cgit v1.2.1 From 7372d185e72fda6c8ad3eea6c5faac61eae602c5 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 16 Jan 2016 17:39:54 -0500 Subject: Bumped to 19.5 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setuptools/version.py b/setuptools/version.py index 7ff48baa..59c45529 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '19.4' +__version__ = '19.5' -- cgit v1.2.1 From e888c6cdacaa883214a06fad0ccd5789f2066b4f Mon Sep 17 00:00:00 2001 From: Alexander Artemenko Date: Mon, 18 Jan 2016 08:48:21 +0000 Subject: Make 19.4 same level header as other version numbers. The problem was that restructured text considered 19.4 is a sibtitle to "CHANGES". --HG-- branch : svetlyak40wt/make-194-same-level-header-as-other-vers-1453106898145 --- CHANGES.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.txt b/CHANGES.txt index 06c6aad1..8992df6a 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -2,6 +2,7 @@ CHANGES ======= +---- 19.4 ---- -- cgit v1.2.1 From 0f0ca87e0b6fb7a9737962cf41d9d4ba81ff9c0f Mon Sep 17 00:00:00 2001 From: Alexander Artemenko Date: Tue, 19 Jan 2016 04:58:32 +0000 Subject: Make all headers on the same level in CHANGES.txt. --HG-- branch : svetlyak40wt/make-194-same-level-header-as-other-vers-1453106898145 --- CHANGES.txt | 232 +----------------------------------------------------------- 1 file changed, 1 insertion(+), 231 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 8992df6a..5242f731 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -2,7 +2,6 @@ CHANGES ======= ----- 19.4 ---- @@ -15,7 +14,6 @@ CHANGES allowing for setup_requires dependencies to supersede installed packages for the session. ----- 19.3 ---- @@ -23,7 +21,6 @@ CHANGES dependencies conditionally from vendored copies or primary locations. Adds a new dependency on six. ----- 19.2 ---- @@ -31,7 +28,6 @@ CHANGES * Pull Request #162: Add missing whitespace to multiline string literals. ------- 19.1.1 ------ @@ -41,7 +37,6 @@ CHANGES of strings, rather than rely on ``repr``, which can be incorrect (especially on Python 2). ----- 19.1 ---- @@ -51,14 +46,12 @@ CHANGES than hard-coding a particular value. * Issue #475: Fix incorrect usage in _translate_metadata2. ----- 19.0 ---- * Issue #442: Use RawConfigParser for parsing .pypirc file. Interpolated values are no longer honored in .pypirc files. ------- 18.8.1 ------ @@ -67,7 +60,6 @@ CHANGES with setuptools hidden. Fixes regression introduced in Setuptools 12.0. ----- 18.8 ---- @@ -79,14 +71,12 @@ CHANGES * Issue #472: Remove deprecated use of 'U' in mode parameter when opening files. ------- 18.7.1 ------ * Issue #469: Refactored logic for Issue #419 fix to re-use metadata loading from Provider. ----- 18.7 ---- @@ -104,14 +94,12 @@ CHANGES reading the version info from distutils-installed metadata rather than using the version in the filename. ------- 18.6.1 ------ * Issue #464: Correct regression in invocation of superclass on old-style class on Python 2. ----- 18.6 ---- @@ -119,7 +107,6 @@ CHANGES omit the version number of the package, allowing any version of the package to be used. ----- 18.5 ---- @@ -131,27 +118,23 @@ CHANGES * `Fix dictionary mutation during iteration `_. ----- 18.4 ---- * Issue #446: Test command now always invokes unittest, even if no test suite is supplied. ------- 18.3.2 ------ * Correct another regression in setuptools.findall where the fix for Python #12885 was lost. ------- 18.3.1 ------ * Issue #425: Correct regression in setuptools.findall. ----- 18.3 ---- @@ -172,25 +155,21 @@ CHANGES * Refactor setuptools.findall in preparation for re-submission back to distutils. ----- 18.2 ---- * Issue #412: More efficient directory search in ``find_packages``. ----- 18.1 ---- * Upgrade to vendored packaging 15.3. ------- 18.0.1 ------ * Issue #401: Fix failure in test suite. ----- 18.0 ---- @@ -216,7 +195,6 @@ CHANGES * Pull Request #136: Remove excessive quoting from shebang headers for Jython. ------- 17.1.1 ------ @@ -224,14 +202,12 @@ CHANGES deprecated imp module (`ref `_). ----- 17.1 ---- * Issue #380: Add support for range operators on environment marker evaluation. ----- 17.0 ---- @@ -240,7 +216,6 @@ CHANGES the name. Removes unintended functionality and brings behavior into parity with pip. ----- 16.0 ---- @@ -251,7 +226,6 @@ CHANGES * Pull Request #129: Address deprecation warning due to usage of imp module. ----- 15.2 ---- @@ -259,14 +233,12 @@ CHANGES ``pkg_resources._initialize_master_working_set``, allowing for imperative re-initialization of the master working set. ----- 15.1 ---- * Updated to Packaging 15.1 to address Packaging #28. * Fix ``setuptools.sandbox._execfile()`` with Python 3.1. ----- 15.0 ---- @@ -280,7 +252,6 @@ CHANGES has since been changed, but older versions of buildout may experience problems. See Buildout #242 for details. ------- 14.3.1 ------ @@ -289,7 +260,6 @@ CHANGES * Issue #364: Replace deprecated usage with recommended usage of ``EntryPoint.load``. ----- 14.3 ---- @@ -297,7 +267,6 @@ CHANGES for creating the directory to avoid the subsequent warning if the directory is group writable. ----- 14.2 ---- @@ -305,21 +274,18 @@ CHANGES None for pyversion or platform can be compared against Distributions defining those attributes. ------- 14.1.1 ------ * Issue #360: Removed undesirable behavior from test runs, preventing write tests and installation to system site packages. ----- 14.1 ---- * Pull Request #125: Add ``__ne__`` to Requirement class. * Various refactoring of easy_install. ----- 14.0 ---- @@ -335,21 +301,18 @@ CHANGES using the "install-dir" and "scripts-dir" parameters to easy_install through an appropriate distutils config file. ------- 13.0.2 ------ * Issue #359: Include pytest.ini in the sdist so invocation of py.test on the sdist honors the pytest configuration. ------- 13.0.1 ------ Re-release of 13.0. Intermittent connectivity issues caused the release process to fail and PyPI uploads no longer accept files for 13.0. ----- 13.0 ---- @@ -359,14 +322,12 @@ process to fail and PyPI uploads no longer accept files for 13.0. functionality was added to support upgrades from old Distribute versions, 0.6.5 and 0.6.6. ----- 12.4 ---- * Pull Request #119: Restore writing of ``setup_requires`` to metadata (previously added in 8.4 and removed in 9.0). ----- 12.3 ---- @@ -376,7 +337,6 @@ process to fail and PyPI uploads no longer accept files for 13.0. * Issue #354. Added documentation on building setuptools documentation. ----- 12.2 ---- @@ -387,40 +347,34 @@ process to fail and PyPI uploads no longer accept files for 13.0. remains deprecated for use by individual packages. * Simplified implementation of ``ez_setup.use_setuptools``. ----- 12.1 ---- * Pull Request #118: Soften warning for non-normalized versions in Distribution. ------- 12.0.5 ------ * Issue #339: Correct Attribute reference in ``cant_write_to_target``. * Issue #336: Deprecated ``ez_setup.use_setuptools``. ------- 12.0.4 ------ * Issue #335: Fix script header generation on Windows. ------- 12.0.3 ------ * Fixed incorrect class attribute in ``install_scripts``. Tests would be nice. ------- 12.0.2 ------ * Issue #331: Fixed ``install_scripts`` command on Windows systems corrupting the header. ------- 12.0.1 ------ @@ -428,7 +382,6 @@ process to fail and PyPI uploads no longer accept files for 13.0. compatibility. For the future, tools should construct a CommandSpec explicitly. ----- 12.0 ---- @@ -439,14 +392,12 @@ process to fail and PyPI uploads no longer accept files for 13.0. * Deprecated ``easy_install.ScriptWriter.get_writer``, replaced by ``.best()`` with slightly different semantics (no force_windows flag). ------- 11.3.1 ------ * Issue #327: Formalize and restore support for any printable character in an entry point name. ----- 11.3 ---- @@ -460,13 +411,11 @@ process to fail and PyPI uploads no longer accept files for 13.0. getattr(ep, "resolve", lambda: ep.load(require=False))() ----- 11.2 ---- * Pip #2326: Report deprecation warning at stacklevel 2 for easier diagnosis. ----- 11.1 ---- @@ -477,20 +426,17 @@ process to fail and PyPI uploads no longer accept files for 13.0. a VersionConflict when no dependent package context is known. New unit tests now capture the expected interface. ----- 11.0 ---- * Interop #3: Upgrade to Packaging 15.0; updates to PEP 440 so that >1.7 does not exclude 1.7.1 but does exclude 1.7.0 and 1.7.0.post1. ------- 10.2.1 ------ * Issue #323: Fix regression in entry point name parsing. ----- 10.2 ---- @@ -500,7 +446,6 @@ process to fail and PyPI uploads no longer accept files for 13.0. * Substantial refactoring of all unit tests. Tests are now much leaner and re-use a lot of fixtures and contexts for better clarity of purpose. ----- 10.1 ---- @@ -509,13 +454,11 @@ process to fail and PyPI uploads no longer accept files for 13.0. so that systems relying on that interface do not fail (namely, Ubuntu 12.04 and similar Debian releases). ------- 10.0.1 ------ * Issue #319: Fixed issue installing pure distutils packages. ----- 10.0 ---- @@ -528,53 +471,45 @@ process to fail and PyPI uploads no longer accept files for 13.0. upgrade (or downgrade) itself even when its own metadata and implementation change. ---- 9.1 --- * Prefer vendored packaging library `as recommended `_. ------ 9.0.1 ----- * Issue #312: Restored presence of pkg_resources API tests (doctest) to sdist. ---- 9.0 --- * Issue #314: Disabled support for ``setup_requires`` metadata to avoid issue where Setuptools was unable to upgrade over earlier versions. ---- 8.4 --- * Pull Request #106: Now write ``setup_requires`` metadata. ---- 8.3 --- * Issue #311: Decoupled pkg_resources from setuptools once again. ``pkg_resources`` is now a package instead of a module. ------ 8.2.1 ----- * Issue #306: Suppress warnings about Version format except in select scenarios (such as installation). ---- 8.2 --- * Pull Request #85: Search egg-base when adding egg-info to manifest. ---- 8.1 --- @@ -584,7 +519,6 @@ process to fail and PyPI uploads no longer accept files for 13.0. ``pkg_resources.PEP440Warning``, instead of RuntimeWarning. * Disabled warnings on empty versions. ------ 8.0.4 ----- @@ -594,27 +528,23 @@ process to fail and PyPI uploads no longer accept files for 13.0. * Issue #296: Add warning when a version is parsed as legacy. This warning will make it easier for developers to recognize deprecated version numbers. ------ 8.0.3 ----- * Issue #296: Restored support for ``__hash__`` on parse_version results. ------ 8.0.2 ----- * Issue #296: Restored support for ``__getitem__`` and sort operations on parse_version result. ------ 8.0.1 ----- * Issue #296: Restore support for iteration over parse_version result, but deprecated that usage with a warning. Fixes failure with buildout. ---- 8.0 --- @@ -627,7 +557,6 @@ process to fail and PyPI uploads no longer accept files for 13.0. supported. Setuptools now "vendors" the `packaging `_ library. ---- 7.0 --- @@ -644,28 +573,24 @@ process to fail and PyPI uploads no longer accept files for 13.0. adapted to ignore ``.eggs``. The files will need to be manually moved or will be retrieved again. Most use cases will require no attention. ---- 6.1 --- * Issue #268: When resolving package versions, a VersionConflict now reports which package previously required the conflicting version. ------ 6.0.2 ----- * Issue #262: Fixed regression in pip install due to egg-info directories being omitted. Re-opens Issue #118. ------ 6.0.1 ----- * Issue #259: Fixed regression with namespace package handling on ``single version, externally managed`` installs. ---- 6.0 --- @@ -696,7 +621,6 @@ process to fail and PyPI uploads no longer accept files for 13.0. recognize the specially-packaged compiler package for easy extension module support on Python 2.6, 2.7, and 3.2. ---- 5.8 --- @@ -704,7 +628,6 @@ process to fail and PyPI uploads no longer accept files for 13.0. Python 3, supporting environments where builtins have been patched to make Python 3 look more like Python 2. ---- 5.7 --- @@ -715,20 +638,17 @@ process to fail and PyPI uploads no longer accept files for 13.0. notes and detailed in Issue #154 was likely not an increase over the status quo, but rather only an increase over not storing the zip info at all. ---- 5.6 --- * Issue #242: Use absolute imports in svn_utils to avoid issues if the installing package adds an xml module to the path. ------ 5.5.1 ----- * Issue #239: Fix typo in 5.5 such that fix did not take. ---- 5.5 --- @@ -736,20 +656,17 @@ process to fail and PyPI uploads no longer accept files for 13.0. Distribution objects and validates the syntax just like install_requires and tests_require directives. ------ 5.4.2 ----- * Issue #236: Corrected regression in execfile implementation for Python 2.6. ------ 5.4.1 ----- * Python #7776: (ssl_support) Correct usage of host for validation when tunneling for HTTPS. ---- 5.4 --- @@ -760,7 +677,6 @@ process to fail and PyPI uploads no longer accept files for 13.0. in startup time by enabling this feature. This feature is not enabled by default because it causes a substantial increase in memory usage. ---- 5.3 --- @@ -769,7 +685,6 @@ process to fail and PyPI uploads no longer accept files for 13.0. * Prune revision control directories (e.g .svn) from base path as well as sub-directories. ---- 5.2 --- @@ -781,7 +696,6 @@ process to fail and PyPI uploads no longer accept files for 13.0. * During install_egg_info, the generated lines for namespace package .pth files are now processed even during a dry run. ---- 5.1 --- @@ -789,20 +703,17 @@ process to fail and PyPI uploads no longer accept files for 13.0. building on the work in Issue #168. Special thanks to Jurko Gospodnetic and PJE. ------ 5.0.2 ----- * Issue #220: Restored script templates. ------ 5.0.1 ----- * Renamed script templates to end with .tmpl now that they no longer need to be processed by 2to3. Fixes spurious syntax errors during build/install. ---- 5.0 --- @@ -810,7 +721,6 @@ process to fail and PyPI uploads no longer accept files for 13.0. * Incidentally, script templates were updated not to include the triple-quote escaping. -------------------------- 3.7.1 and 3.8.1 and 4.0.1 ------------------------- @@ -818,48 +728,41 @@ process to fail and PyPI uploads no longer accept files for 13.0. * Issue #218: Setuptools 3.8.1 superseded 4.0.1, and 4.x was removed from the available versions to install. ---- 4.0 --- * Issue #210: ``setup.py develop`` now copies scripts in binary mode rather than text mode, matching the behavior of the ``install`` command. ---- 3.8 --- * Extend Issue #197 workaround to include all Python 3 versions prior to 3.2.2. ---- 3.7 --- * Issue #193: Improved handling of Unicode filenames when building manifests. ---- 3.6 --- * Issue #203: Honor proxy settings for Powershell downloader in the bootstrap routine. ------ 3.5.2 ----- * Issue #168: More robust handling of replaced zip files and stale caches. Fixes ZipImportError complaining about a 'bad local header'. ------ 3.5.1 ----- * Issue #199: Restored ``install._install`` for compatibility with earlier NumPy versions. ---- 3.5 --- @@ -870,32 +773,27 @@ process to fail and PyPI uploads no longer accept files for 13.0. * Issue #192: Preferred bootstrap location is now https://bootstrap.pypa.io/ez_setup.py (mirrored from former location). ------ 3.4.4 ----- * Issue #184: Correct failure where find_package over-matched packages when directory traversal isn't short-circuited. ------ 3.4.3 ----- * Issue #183: Really fix test command with Python 3.1. ------ 3.4.2 ----- * Issue #183: Fix additional regression in test command on Python 3.1. ------ 3.4.1 ----- * Issue #180: Fix regression in test command not caught by py.test-run tests. ---- 3.4 --- @@ -906,13 +804,11 @@ process to fail and PyPI uploads no longer accept files for 13.0. now installs naturally on IronPython. Behavior on CPython should be unchanged. ---- 3.3 --- * Add ``include`` parameter to ``setuptools.find_packages()``. ---- 3.2 --- @@ -920,27 +816,23 @@ process to fail and PyPI uploads no longer accept files for 13.0. * Issue #162: Update dependency on certifi to 1.0.1. * Issue #164: Update dependency on wincertstore to 0.2. ---- 3.1 --- * Issue #161: Restore Features functionality to allow backward compatibility (for Features) until the uses of that functionality is sufficiently removed. ------ 3.0.2 ----- * Correct typo in previous bugfix. ------ 3.0.1 ----- * Issue #157: Restore support for Python 2.6 in bootstrap script where ``zipfile.ZipFile`` does not yet have support for context managers. ---- 3.0 --- @@ -968,7 +860,6 @@ process to fail and PyPI uploads no longer accept files for 13.0. Python 3 environments. * Issue #156: Fix spelling of __PYVENV_LAUNCHER__ variable. ---- 2.2 --- @@ -977,21 +868,18 @@ process to fail and PyPI uploads no longer accept files for 13.0. * Issue #128: Fixed issue where only the first dependency link was honored in a distribution where multiple dependency links were supplied. ------ 2.1.2 ----- * Issue #144: Read long_description using codecs module to avoid errors installing on systems where LANG=C. ------ 2.1.1 ----- * Issue #139: Fix regression in re_finder for CVS repos (and maybe Git repos as well). ---- 2.1 --- @@ -999,7 +887,6 @@ process to fail and PyPI uploads no longer accept files for 13.0. in a zip-imported file. * Issue #131: Fix RuntimeError when constructing an egg fetcher. ------ 2.0.2 ----- @@ -1007,13 +894,11 @@ process to fail and PyPI uploads no longer accept files for 13.0. not containing parser module. * Fix NameError in ``sdist:re_finder``. ------ 2.0.1 ----- * Issue #124: Fixed error in list detection in upload_docs. ---- 2.0 --- @@ -1026,14 +911,12 @@ process to fail and PyPI uploads no longer accept files for 13.0. * Removed ``pkg_resources.ImpWrapper``. Clients that expected this class should use ``pkgutil.ImpImporter`` instead. ------ 1.4.2 ----- * Issue #116: Correct TypeError when reading a local package index on Python 3. ------ 1.4.1 ----- @@ -1063,7 +946,6 @@ process to fail and PyPI uploads no longer accept files for 13.0. for legacy SVN releases and support for SVN without the subprocess command would simple go away as support for the older SVNs does. ---- 1.4 --- @@ -1072,19 +954,16 @@ process to fail and PyPI uploads no longer accept files for 13.0. * Pull Request #21: Omit unwanted newlines in ``package_index._encode_auth`` when the username/password pair length indicates wrapping. ------ 1.3.2 ----- * Issue #99: Fix filename encoding issues in SVN support. ------ 1.3.1 ----- * Remove exuberant warning in SVN support when SVN is not used. ---- 1.3 --- @@ -1095,7 +974,6 @@ process to fail and PyPI uploads no longer accept files for 13.0. implementation if present. * Correct NameError in ``ssl_support`` module (``socket.error``). ---- 1.2 --- @@ -1108,7 +986,6 @@ process to fail and PyPI uploads no longer accept files for 13.0. * Setuptools "natural" launcher support, introduced in 1.0, is now officially supported. ------ 1.1.7 ----- @@ -1119,39 +996,33 @@ process to fail and PyPI uploads no longer accept files for 13.0. * Distribute #363 and Issue #55: Skip an sdist test that fails on locales other than UTF-8. ------ 1.1.6 ----- * Distribute #349: ``sandbox.execfile`` now opens the target file in binary mode, thus honoring a BOM in the file when compiled. ------ 1.1.5 ----- * Issue #69: Second attempt at fix (logic was reversed). ------ 1.1.4 ----- * Issue #77: Fix error in upload command (Python 2.4). ------ 1.1.3 ----- * Fix NameError in previous patch. ------ 1.1.2 ----- * Issue #69: Correct issue where 404 errors are returned for URLs with fragments in them (such as #egg=). ------ 1.1.1 ----- @@ -1159,7 +1030,6 @@ process to fail and PyPI uploads no longer accept files for 13.0. environments where a trusted SSL connection cannot be validated. * Issue #76: Fix AttributeError in upload command with Python 2.4. ---- 1.1 --- @@ -1167,7 +1037,6 @@ process to fail and PyPI uploads no longer accept files for 13.0. condition when a host is blocked via ``--allow-hosts``. * Issue #72: Restored Python 2.4 compatibility in ``ez_setup.py``. ---- 1.0 --- @@ -1204,13 +1073,11 @@ not all users will find 1.0 a drop-in replacement for 0.9. * Removed ``--ignore-conflicts-at-my-risk`` and ``--delete-conflicting`` options to easy_install. These options have been deprecated since 0.6a11. ------ 0.9.8 ----- * Issue #53: Fix NameErrors in `_vcs_split_rev_from_url`. ------ 0.9.7 ----- @@ -1220,79 +1087,67 @@ not all users will find 1.0 a drop-in replacement for 0.9. referenced by bookmark. * Add underscore-separated keys to environment markers (markerlib). ------ 0.9.6 ----- * Issue #44: Test failure on Python 2.4 when MD5 hash doesn't have a `.name` attribute. ------ 0.9.5 ----- * Python #17980: Fix security vulnerability in SSL certificate validation. ------ 0.9.4 ----- * Issue #43: Fix issue (introduced in 0.9.1) with version resolution when upgrading over other releases of Setuptools. ------ 0.9.3 ----- * Issue #42: Fix new ``AttributeError`` introduced in last fix. ------ 0.9.2 ----- * Issue #42: Fix regression where blank checksums would trigger an ``AttributeError``. ------ 0.9.1 ----- * Distribute #386: Allow other positional and keyword arguments to os.open. * Corrected dependency on certifi mis-referenced in 0.9. ---- 0.9 --- * `package_index` now validates hashes other than MD5 in download links. ---- 0.8 --- * Code base now runs on Python 2.4 - Python 3.3 without Python 2to3 conversion. ------ 0.7.8 ----- * Distribute #375: Yet another fix for yet another regression. ------ 0.7.7 ----- * Distribute #375: Repair AttributeError created in last release (redo). * Issue #30: Added test for get_cache_path. ------ 0.7.6 ----- * Distribute #375: Repair AttributeError created in last release. ------ 0.7.5 ----- @@ -1302,33 +1157,28 @@ not all users will find 1.0 a drop-in replacement for 0.9. ``SETUPTOOLS_DISABLE_VERSIONED_EASY_INSTALL_SCRIPT`` in addition to the now deprecated ``DISTRIBUTE_DISABLE_VERSIONED_EASY_INSTALL_SCRIPT``. ------ 0.7.4 ----- * Issue #20: Fix comparison of parsed SVN version on Python 3. ------ 0.7.3 ----- * Issue #1: Disable installation of Windows-specific files on non-Windows systems. * Use new sysconfig module with Python 2.7 or >=3.2. ------ 0.7.2 ----- * Issue #14: Use markerlib when the `parser` module is not available. * Issue #10: ``ez_setup.py`` now uses HTTPS to download setuptools from PyPI. ------ 0.7.1 ----- * Fix NameError (Issue #3) again - broken in bad merge. ---- 0.7 --- @@ -1346,13 +1196,11 @@ Added several features that were slated for setuptools 0.6c12: * Added support for SSL certificate validation when installing packages from an HTTPS service. ------ 0.7b4 ----- * Issue #3: Fixed NameError in SSL support. ------- 0.6.49 ------ @@ -1360,21 +1208,18 @@ Added several features that were slated for setuptools 0.6c12: to avoid errors when the cache path does not yet exist. Fixes the error reported in Distribute #375. ------- 0.6.48 ------ * Correct AttributeError in ``ResourceManager.get_cache_path`` introduced in 0.6.46 (redo). ------- 0.6.47 ------ * Correct AttributeError in ``ResourceManager.get_cache_path`` introduced in 0.6.46. ------- 0.6.46 ------ @@ -1382,27 +1227,23 @@ Added several features that were slated for setuptools 0.6c12: customized egg cache location specifies a directory that's group- or world-writable. ------- 0.6.45 ------ * Distribute #379: ``distribute_setup.py`` now traps VersionConflict as well, restoring ability to upgrade from an older setuptools version. ------- 0.6.44 ------ * ``distribute_setup.py`` has been updated to allow Setuptools 0.7 to satisfy use_setuptools. ------- 0.6.43 ------ * Distribute #378: Restore support for Python 2.4 Syntax (regression in 0.6.42). ------- 0.6.42 ------ @@ -1410,7 +1251,6 @@ Added several features that were slated for setuptools 0.6c12: * Distribute #337: Moved site.py to setuptools/site-patch.py (graft of very old patch from setuptools trunk which inspired PR #31). ------- 0.6.41 ------ @@ -1419,14 +1259,12 @@ Added several features that were slated for setuptools 0.6c12: * Added a new function ``easy_install.get_win_launcher`` which may be used by third-party libraries such as buildout to get a suitable script launcher. ------- 0.6.40 ------ * Distribute #376: brought back cli.exe and gui.exe that were deleted in the previous release. ------- 0.6.39 ------ @@ -1438,13 +1276,11 @@ Added several features that were slated for setuptools 0.6c12: check the contents of the file against the zip contents during each invocation of get_resource_filename. ------- 0.6.38 ------ * Distribute #371: The launcher manifest file is now installed properly. ------- 0.6.37 ------ @@ -1454,7 +1290,6 @@ Added several features that were slated for setuptools 0.6c12: in `this Microsoft article `_. ------- 0.6.36 ------ @@ -1464,7 +1299,6 @@ Added several features that were slated for setuptools 0.6c12: under Windows. Easy_install now skips all directories when processing metadata scripts. ------- 0.6.35 ------ @@ -1476,13 +1310,11 @@ how it parses version numbers. 0.6. Updated the documentation to match more closely with the version parsing as intended in setuptools 0.6. ------- 0.6.34 ------ * Distribute #341: 0.6.33 fails to build under Python 2.4. ------- 0.6.33 ------ @@ -1495,7 +1327,6 @@ how it parses version numbers. for details. * Distribute #341: Fix a ResourceWarning. ------- 0.6.32 ------ @@ -1504,7 +1335,6 @@ how it parses version numbers. * Distribute #335: Backed out `setup_requires` superceding installed requirements until regression can be addressed. ------- 0.6.31 ------ @@ -1529,14 +1359,12 @@ how it parses version numbers. would have been in had that egg been on the path when pkg_resources was first imported. ------- 0.6.30 ------ * Distribute #328: Clean up temporary directories in distribute_setup.py. * Fix fatal bug in distribute_setup.py. ------- 0.6.29 ------ @@ -1568,7 +1396,6 @@ how it parses version numbers. * `distribute_setup.py` now allows a `--download-base` argument for retrieving distribute from a specified location. ------- 0.6.28 ------ @@ -1578,7 +1405,6 @@ how it parses version numbers. * Distribute #283: Fix and disable scanning of `*.pyc` / `*.pyo` files on Python 3.3. ------- 0.6.27 ------ @@ -1589,7 +1415,6 @@ how it parses version numbers. * Distribute #231: Don't fiddle with system python when used with buildout (bootstrap.py) ------- 0.6.26 ------ @@ -1598,7 +1423,6 @@ how it parses version numbers. installation of a source distribution; now fulfillment of setup_requires dependencies will honor the parameters passed to easy_install. ------- 0.6.25 ------ @@ -1614,13 +1438,11 @@ how it parses version numbers. 449. * Distribute #273: Legacy script launchers now install with Python2/3 support. ------- 0.6.24 ------ * Distribute #249: Added options to exclude 2to3 fixers ------- 0.6.23 ------ @@ -1636,13 +1458,11 @@ how it parses version numbers. * Distribute #227: easy_install now passes its arguments to setup.py bdist_egg * Distribute #225: Fixed a NameError on Python 2.5, 2.4 ------- 0.6.21 ------ * Distribute #225: FIxed a regression on py2.4 ------- 0.6.20 ------ @@ -1650,19 +1470,16 @@ how it parses version numbers. * Distribute #212: Fix issue where easy_instal fails on Python 3 on windows installer. * Distribute #213: Fix typo in documentation. ------- 0.6.19 ------ * Distribute #206: AttributeError: 'HTTPMessage' object has no attribute 'getheaders' ------- 0.6.18 ------ * Distribute #210: Fixed a regression introduced by Distribute #204 fix. ------- 0.6.17 ------ @@ -1675,7 +1492,6 @@ how it parses version numbers. * Distribute #205: Sandboxing doesn't preserve working_set. Leads to setup_requires problems. ------- 0.6.16 ------ @@ -1685,7 +1501,6 @@ how it parses version numbers. * Distribute #195: Cython build support. * Distribute #200: Issues with recognizing 64-bit packages on Windows. ------- 0.6.15 ------ @@ -1693,7 +1508,6 @@ how it parses version numbers. * Several issues under Python 3 has been solved. * Distribute #146: Fixed missing DLL files after easy_install of windows exe package. ------- 0.6.14 ------ @@ -1703,7 +1517,6 @@ how it parses version numbers. Thanks to David and Zooko. * Distribute #174: Fixed the edit mode when its used with setuptools itself ------- 0.6.13 ------ @@ -1712,13 +1525,11 @@ how it parses version numbers. * Distribute #163: scan index links before external links, and don't use the md5 when comparing two distributions ------- 0.6.12 ------ * Distribute #149: Fixed various failures on 2.3/2.4 ------- 0.6.11 ------ @@ -1735,7 +1546,6 @@ how it parses version numbers. * Distribute #138: cant_write_to_target error when setup_requires is used. * Distribute #147: respect the sys.dont_write_bytecode flag ------- 0.6.10 ------ @@ -1743,7 +1553,6 @@ how it parses version numbers. zc.buildout uses the exception message to get the name of the distribution. ------ 0.6.9 ----- @@ -1770,14 +1579,12 @@ how it parses version numbers. * Distribute #100: making sure there's no SandboxViolation when the setup script patches setuptools. ------ 0.6.8 ----- * Added "check_packages" in dist. (added in Setuptools 0.6c11) * Fixed the DONT_PATCH_SETUPTOOLS state. ------ 0.6.7 ----- @@ -1802,14 +1609,12 @@ how it parses version numbers. * Distribute #74: no_fake should be True by default. * Distribute #72: avoid a bootstrapping issue with easy_install -U ------ 0.6.6 ----- * Unified the bootstrap file so it works on both py2.x and py3k without 2to3 (patch by Holger Krekel) ------ 0.6.5 ----- @@ -1828,7 +1633,6 @@ how it parses version numbers. * Fixed a hole in sandboxing allowing builtin file to write outside of the sandbox. ------ 0.6.4 ----- @@ -1840,7 +1644,6 @@ how it parses version numbers. * Fixed a bootstrap bug on the use_setuptools() API. ------ 0.6.3 ----- @@ -1854,7 +1657,6 @@ bootstrapping * Fixed a bug in sorting that caused bootstrap to fail on Python 3. ------ 0.6.2 ----- @@ -1886,7 +1688,6 @@ bootstrapping * Make sure setuptools is patched when running through easy_install This closes Old Setuptools #40. ------ 0.6.1 ----- @@ -1914,7 +1715,6 @@ bootstrapping and --root or --prefix is provided, but is not in the same location. This closes Distribute #10. ---- 0.6 --- @@ -1957,7 +1757,6 @@ easy_install * Immediately close all file handles. This closes Distribute #3. ------ 0.6c9 ----- @@ -1998,7 +1797,6 @@ easy_install gracefully under Google App Engine (with an ``ImportError`` loading the C-based module, instead of getting a ``NameError``). ------ 0.6c7 ----- @@ -2009,7 +1807,6 @@ easy_install ``--root`` or ``--single-version-externally-managed``, due to the parent package not having the child package as an attribute. ------ 0.6c6 ----- @@ -2033,7 +1830,6 @@ easy_install * Fix ``find_packages()`` treating ``ez_setup`` and directories with ``.`` in their names as packages. ------ 0.6c5 ----- @@ -2043,7 +1839,6 @@ easy_install * Fix uploaded ``bdist_wininst`` packages being described as suitable for "any" version by Python 2.5, even if a ``--target-version`` was specified. ------ 0.6c4 ----- @@ -2073,13 +1868,11 @@ easy_install listed a namespace package ``foo.bar`` without explicitly listing ``foo`` as a namespace package. ------ 0.6c3 ----- * Fixed breakages caused by Subversion 1.4's new "working copy" format ------ 0.6c2 ----- @@ -2090,7 +1883,6 @@ easy_install * Running ``setup.py develop`` on a setuptools-using project will now install setuptools if needed, instead of only downloading the egg. ------ 0.6c1 ----- @@ -2114,7 +1906,6 @@ easy_install the version was overridden on the command line that built the source distribution.) ------ 0.6b4 ----- @@ -2127,7 +1918,6 @@ easy_install * Fixed redundant warnings about missing ``README`` file(s); it should now appear only if you are actually a source distribution. ------ 0.6b3 ----- @@ -2138,7 +1928,6 @@ easy_install ``include_package_data`` and ``package_data`` are used to refer to the same files. ------ 0.6b1 ----- @@ -2146,7 +1935,6 @@ easy_install the name of a ``.py`` loader/wrapper. (Python's import machinery ignores this suffix when searching for an extension module.) ------- 0.6a11 ------ @@ -2180,13 +1968,11 @@ easy_install it. Previously, the file could be left open and the actual error would be masked by problems trying to remove the open file on Windows systems. ------- 0.6a10 ------ * Fixed the ``develop`` command ignoring ``--find-links``. ------ 0.6a9 ----- @@ -2238,7 +2024,6 @@ easy_install back into an ``.egg`` file or directory and install it as such. ------ 0.6a8 ----- @@ -2266,13 +2051,11 @@ easy_install metadata cache to pretend that the egg has valid version information, until it has a chance to make it actually be so (via the ``egg_info`` command). ------ 0.6a5 ----- * Fixed missing gui/cli .exe files in distribution. Fixed bugs in tests. ------ 0.6a3 ----- @@ -2280,7 +2063,6 @@ easy_install on Windows and other platforms. (The special handling is only for Windows; other platforms are treated the same as for ``console_scripts``.) ------ 0.6a2 ----- @@ -2289,7 +2071,6 @@ easy_install scripts get an ``.exe`` wrapper so you can just type their name. On other platforms, the scripts are written without a file extension. ------ 0.6a1 ----- @@ -2335,7 +2116,6 @@ easy_install or documented, and never would have worked without EasyInstall - which it pre-dated and was never compatible with. ------- 0.5a12 ------ @@ -2343,14 +2123,12 @@ easy_install ``python -m``, and marks them as unsafe for zipping, since Python 2.4 can't handle ``-m`` on zipped modules. ------- 0.5a11 ------ * Fix breakage of the "develop" command that was caused by the addition of ``--always-unzip`` to the ``easy_install`` command. ------ 0.5a9 ----- @@ -2385,7 +2163,6 @@ easy_install * Fixed the swapped ``-d`` and ``-b`` options of ``bdist_egg``. ------ 0.5a8 ----- @@ -2413,7 +2190,6 @@ easy_install * Added a "setopt" command that sets a single option in a specified distutils configuration file. ------ 0.5a7 ----- @@ -2421,7 +2197,6 @@ easy_install fix for "upload" and a temporary workaround for lack of .egg support in PyPI. ------ 0.5a6 ----- @@ -2440,7 +2215,6 @@ easy_install revisions compare *lower* than the version specified in setup.py (e.g. by using ``--tag-build=dev``). ------ 0.5a5 ----- @@ -2468,7 +2242,6 @@ easy_install accordingly. ``easy_install.py`` is still installed as a script, but not as a module. ------ 0.5a4 ----- @@ -2484,7 +2257,6 @@ easy_install * Setup scripts using setuptools now always install using ``easy_install`` internally, for ease of uninstallation and upgrading. ------ 0.5a1 ----- @@ -2499,7 +2271,6 @@ easy_install from setuptools import setup # etc... ------ 0.4a2 ----- @@ -2527,7 +2298,6 @@ easy_install their ``command_consumes_arguments`` attribute to ``True`` in order to receive an ``args`` option containing the rest of the command line. ------ 0.3a2 ----- @@ -2537,8 +2307,8 @@ easy_install * Misc. bug fixes ------ 0.3a1 ----- * Initial release. + -- cgit v1.2.1 From e2f1814e0d3d8963cf3a1eb4dff6d400b58b4a52 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 23 Jan 2016 18:13:32 -0500 Subject: Invoke import on importlib.machinery directly. Access an attribute to force import in delayed-import environments. Fixes #487. --- CHANGES.txt | 7 +++++++ pkg_resources/__init__.py | 7 ++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 06c6aad1..a6f58b2d 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -2,6 +2,13 @@ CHANGES ======= +19.4.1 +------ + +* Issue #487: Use direct invocation of ``importlib.machinery`` + in ``pkg_resources`` to avoid missing detection on relevant + platforms. + 19.4 ---- diff --git a/pkg_resources/__init__.py b/pkg_resources/__init__.py index 50b86cdb..3ecf4c64 100644 --- a/pkg_resources/__init__.py +++ b/pkg_resources/__init__.py @@ -60,10 +60,11 @@ except ImportError: from os import open as os_open from os.path import isdir, split -# Avoid try/except due to potential problems with delayed import mechanisms. -if sys.version_info >= (3, 3) and sys.implementation.name == "cpython": +try: import importlib.machinery as importlib_machinery -else: + # access attribute to force import under delayed import mechanisms. + importlib_machinery.__name__ +except ImportError: importlib_machinery = None try: -- cgit v1.2.1 From dcfeab73aa5309b24c31d2d3f32073aad99ef05c Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 23 Jan 2016 18:37:25 -0500 Subject: Bumped to 19.4.1 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setuptools/version.py b/setuptools/version.py index 59c45529..3ee13bc9 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '19.5' +__version__ = '19.4.1' -- cgit v1.2.1 From 25a12d49012ef636eb5cc929163f89188b084c3f Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 23 Jan 2016 18:37:27 -0500 Subject: Added tag 19.4.1 for changeset 0bda3291ac72 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 1e7eeff0..f3337a20 100644 --- a/.hgtags +++ b/.hgtags @@ -236,3 +236,4 @@ cc41477ecf92f221c113736fac2830bf8079d40c 19.0 66fa131a0d77a1b0e6f89ccb76b254cfb07d3da3 19.3b1 32bba9bf8cce8350b560a7591c9ef5884a194211 19.3 f47f3671508b015e9bb735603d3a0a6ec6a77b01 19.4 +0bda3291ac725750b899b4ba3e4b6765e7645daa 19.4.1 -- cgit v1.2.1 From 9363ee420bd803f333b31466796ff00a183de66e Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 23 Jan 2016 18:49:52 -0500 Subject: Extract variable for candidate encodings --- setuptools/unicode_utils.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/setuptools/unicode_utils.py b/setuptools/unicode_utils.py index 18903d9e..6eee6351 100644 --- a/setuptools/unicode_utils.py +++ b/setuptools/unicode_utils.py @@ -22,11 +22,13 @@ def filesys_decode(path): NONE when no expected encoding works """ - fs_enc = sys.getfilesystemencoding() if isinstance(path, six.text_type): return path - for enc in (fs_enc, "utf-8"): + fs_enc = sys.getfilesystemencoding() + candidates = fs_enc, 'utf-8' + + for enc in candidates: try: return path.decode(enc) except UnicodeDecodeError: -- cgit v1.2.1 From 3d018c03405ecb21dfb717311f176c6586df343a Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 23 Jan 2016 19:02:08 -0500 Subject: Add test capturing failure. Ref #486. --- setuptools/tests/test_unicode_utils.py | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 setuptools/tests/test_unicode_utils.py diff --git a/setuptools/tests/test_unicode_utils.py b/setuptools/tests/test_unicode_utils.py new file mode 100644 index 00000000..a24a9bd5 --- /dev/null +++ b/setuptools/tests/test_unicode_utils.py @@ -0,0 +1,10 @@ +from setuptools import unicode_utils + + +def test_filesys_decode_fs_encoding_is_None(monkeypatch): + """ + Test filesys_decode does not raise TypeError when + getfilesystemencoding returns None. + """ + monkeypatch.setattr('sys.getfilesystemencoding', lambda: None) + unicode_utils.filesys_decode(b'test') -- cgit v1.2.1 From 3223234b137e9766a6f4e892a3369b13f57f878b Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 23 Jan 2016 19:08:57 -0500 Subject: Avoid TypeError when getfilesystemencoding returns None. Fixes #486. --- CHANGES.txt | 6 ++++++ setuptools/unicode_utils.py | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES.txt b/CHANGES.txt index c7f68ab4..11298b57 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -2,6 +2,12 @@ CHANGES ======= +19.4.2 +------ + +* Issue #486: Correct TypeError when getfilesystemencoding + returns None. + 19.4.1 ------ diff --git a/setuptools/unicode_utils.py b/setuptools/unicode_utils.py index 6eee6351..ffab3e24 100644 --- a/setuptools/unicode_utils.py +++ b/setuptools/unicode_utils.py @@ -25,7 +25,7 @@ def filesys_decode(path): if isinstance(path, six.text_type): return path - fs_enc = sys.getfilesystemencoding() + fs_enc = sys.getfilesystemencoding() or 'utf-8' candidates = fs_enc, 'utf-8' for enc in candidates: -- cgit v1.2.1 From d0bd7a5612088e5da516c0b183c2b8a04a0e5306 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 23 Jan 2016 20:57:04 -0500 Subject: Relicense the package as MIT license. Drop licensing as PSF and Zope as neither of those licenses grant authority for use outside their respective projects. Vendored projects are licensed under their respective licenses, currently MIT for six and Apache v2 for packaging. Fixes #132. --- setup.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/setup.py b/setup.py index dfb578a1..c7cd364b 100755 --- a/setup.py +++ b/setup.py @@ -75,7 +75,6 @@ setup_params = dict( "Python packages", author="Python Packaging Authority", author_email="distutils-sig@python.org", - license="PSF or ZPL", long_description=long_description, keywords="CPAN PyPI distutils eggs package management", url="https://bitbucket.org/pypa/setuptools", @@ -134,8 +133,7 @@ setup_params = dict( classifiers=textwrap.dedent(""" Development Status :: 5 - Production/Stable Intended Audience :: Developers - License :: OSI Approved :: Python Software Foundation License - License :: OSI Approved :: Zope Public License + License :: OSI Approved :: MIT License Operating System :: OS Independent Programming Language :: Python :: 2.6 Programming Language :: Python :: 2.7 -- cgit v1.2.1 From 589a2c0c319ba39ebcce7a64c36dc11aefd0ebc0 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 23 Jan 2016 21:01:32 -0500 Subject: Update changelog. --- CHANGES.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.txt b/CHANGES.txt index 11298b57..8177e5bf 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -7,6 +7,7 @@ CHANGES * Issue #486: Correct TypeError when getfilesystemencoding returns None. +* Issue #139: Clarified the license as MIT. 19.4.1 ------ -- cgit v1.2.1 From 5505c6a063f59d0025103a392be1efd067dc1781 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 23 Jan 2016 21:26:06 -0500 Subject: Update changelog --- CHANGES.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 8177e5bf..0fbfc26d 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -2,12 +2,14 @@ CHANGES ======= -19.4.2 ------- +19.5 +---- * Issue #486: Correct TypeError when getfilesystemencoding returns None. * Issue #139: Clarified the license as MIT. +* Pull Request #169: Removed special handling of command + spec in scripts for Jython. 19.4.1 ------ -- cgit v1.2.1 From 520cf79afe622d6537c2f036f686350eb6722f04 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 23 Jan 2016 21:26:24 -0500 Subject: Bumped to 19.5 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setuptools/version.py b/setuptools/version.py index 3ee13bc9..59c45529 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '19.4.1' +__version__ = '19.5' -- cgit v1.2.1 From d7b2598ff6d4709ec56be71ca80533ccb31a90ce Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 23 Jan 2016 21:26:26 -0500 Subject: Added tag 19.5 for changeset 0a68cbab7258 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index f3337a20..dac6f5e3 100644 --- a/.hgtags +++ b/.hgtags @@ -237,3 +237,4 @@ cc41477ecf92f221c113736fac2830bf8079d40c 19.0 32bba9bf8cce8350b560a7591c9ef5884a194211 19.3 f47f3671508b015e9bb735603d3a0a6ec6a77b01 19.4 0bda3291ac725750b899b4ba3e4b6765e7645daa 19.4.1 +0a68cbab72580a6f8d3bf9c45206669eefcd256b 19.5 -- cgit v1.2.1 From 3b7b733ca9f2e3193426682ae6357b3f29307aa2 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 23 Jan 2016 21:28:03 -0500 Subject: Bumped to 19.6 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setuptools/version.py b/setuptools/version.py index 59c45529..74a70a41 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '19.5' +__version__ = '19.6' -- cgit v1.2.1 From e7f9dab06dc2515fe11e7f31ea948eed5e141470 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 24 Jan 2016 10:07:40 -0500 Subject: Add 'launch' hook, based on pip.utils.setuptools_build --- CHANGES.txt | 15 +++++++++++++++ setuptools/launch.py | 28 ++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 setuptools/launch.py diff --git a/CHANGES.txt b/CHANGES.txt index 0fbfc26d..c82ec5a5 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -2,6 +2,21 @@ CHANGES ======= +19.6 +---- + +* Added a new entry script ``setuptools.launch``, + implementing the shim found in + ``pip.util.setuptools_build``. Use this command to launch + distutils-only packages under setuptools in the same way that + pip does, causing the setuptools monkeypatching of distutils + to be invoked prior to invoking a script. Useful for debugging + or otherwise installing a distutils-only package under + setuptools when pip isn't available or otherwise does not + expose the desired functionality. For example:: + + $ python -m setuptools.launch setup.py develop + 19.5 ---- diff --git a/setuptools/launch.py b/setuptools/launch.py new file mode 100644 index 00000000..68cce681 --- /dev/null +++ b/setuptools/launch.py @@ -0,0 +1,28 @@ +""" +Launch the Python script on the command line after +setuptools is bootstrapped via import. +""" + +# Note that setuptools gets imported implicitly by the +# invocation of this script using python -m setuptools.launch + +import tokenize +import sys + + +def load(): + """ + Load the script in sys.argv[1] and run it as if it had + been invoked naturally. + """ + globals()['__file__'] = sys.argv[1] + sys.argv[:] = sys.argv[1:] + + open_ = getattr(tokenize, 'open', open) + script = open_(__file__).read() + norm_script = script.replace('\\r\\n', '\\n') + return compile(norm_script, __file__, 'exec') + + +if __name__ == '__main__': + exec(load()) -- cgit v1.2.1 From 57d450a4e0485c8c9db04a5b6d02615c3798f418 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 24 Jan 2016 11:49:11 -0500 Subject: Also hide Cython when hiding setuptools, as setuptools will have imported Cython and Cython references the distutils.Extension. Fixes #488. --- CHANGES.txt | 3 +++ setuptools/sandbox.py | 6 +++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGES.txt b/CHANGES.txt index c82ec5a5..28d2ef63 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -16,6 +16,9 @@ CHANGES expose the desired functionality. For example:: $ python -m setuptools.launch setup.py develop +* Issue #488: Fix dual manifestation of Extension class in + extension packages installed as dependencies when Cython + is present. 19.5 ---- diff --git a/setuptools/sandbox.py b/setuptools/sandbox.py index 668bcac7..23e296b1 100755 --- a/setuptools/sandbox.py +++ b/setuptools/sandbox.py @@ -207,8 +207,12 @@ def _needs_hiding(mod_name): True >>> _needs_hiding('distutils') True + >>> _needs_hiding('os') + False + >>> _needs_hiding('Cython') + True """ - pattern = re.compile('(setuptools|pkg_resources|distutils)(\.|$)') + pattern = re.compile('(setuptools|pkg_resources|distutils|Cython)(\.|$)') return bool(pattern.match(mod_name)) -- cgit v1.2.1 From 41b2ead9e312dbf88f86121c5eab1736972b352b Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 24 Jan 2016 12:04:35 -0500 Subject: Added tag 19.6b1 for changeset 34121bf49b1a --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index dac6f5e3..d6741a60 100644 --- a/.hgtags +++ b/.hgtags @@ -238,3 +238,4 @@ cc41477ecf92f221c113736fac2830bf8079d40c 19.0 f47f3671508b015e9bb735603d3a0a6ec6a77b01 19.4 0bda3291ac725750b899b4ba3e4b6765e7645daa 19.4.1 0a68cbab72580a6f8d3bf9c45206669eefcd256b 19.5 +34121bf49b1a7ac77da7f7c75105c8a920218dd7 19.6b1 -- cgit v1.2.1 From c697d2a55a6c52564e1de9e066ebefacb15de4af Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 24 Jan 2016 19:52:16 -0500 Subject: Added tag 19.6 for changeset 3c2332e4ec72 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index d6741a60..4f9c3a8f 100644 --- a/.hgtags +++ b/.hgtags @@ -239,3 +239,4 @@ f47f3671508b015e9bb735603d3a0a6ec6a77b01 19.4 0bda3291ac725750b899b4ba3e4b6765e7645daa 19.4.1 0a68cbab72580a6f8d3bf9c45206669eefcd256b 19.5 34121bf49b1a7ac77da7f7c75105c8a920218dd7 19.6b1 +3c2332e4ec72717bf17321473e5c3ad6e5778903 19.6 -- cgit v1.2.1 From bdd0e2d6a9bc38ae1c8b035364b7b23da0845233 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 24 Jan 2016 19:53:32 -0500 Subject: Bumped to 19.7 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setuptools/version.py b/setuptools/version.py index 74a70a41..2e0bba87 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '19.6' +__version__ = '19.7' -- cgit v1.2.1 From 634b0aefca69d135dd5226a44fac4c44a47c328d Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Mon, 25 Jan 2016 21:15:02 -0500 Subject: Rather than re-use globals of setuptools.launch, build a unique namespace in which to launch the script. Prevents imports from occuring relative to 'setuptools' on Python 2. Ref #490. --- setuptools/launch.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/setuptools/launch.py b/setuptools/launch.py index 68cce681..06e15e1e 100644 --- a/setuptools/launch.py +++ b/setuptools/launch.py @@ -10,19 +10,26 @@ import tokenize import sys -def load(): +def run(): """ - Load the script in sys.argv[1] and run it as if it had + Run the script in sys.argv[1] as if it had been invoked naturally. """ - globals()['__file__'] = sys.argv[1] + __builtins__ + script_name = sys.argv[1] + namespace = dict( + __file__ = script_name, + __name__ = '__main__', + __doc__ = None, + ) sys.argv[:] = sys.argv[1:] open_ = getattr(tokenize, 'open', open) - script = open_(__file__).read() + script = open_(script_name).read() norm_script = script.replace('\\r\\n', '\\n') - return compile(norm_script, __file__, 'exec') + code = compile(norm_script, script_name, 'exec') + exec(code, namespace) if __name__ == '__main__': - exec(load()) + run() -- cgit v1.2.1 From e01792ec62653b00b6d1c25e1ca0d10d22c1b6b9 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 26 Jan 2016 14:30:34 -0500 Subject: Combine redundant imports of future functionality --- pkg_resources/__init__.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/pkg_resources/__init__.py b/pkg_resources/__init__.py index 3ecf4c64..2ba5ca42 100644 --- a/pkg_resources/__init__.py +++ b/pkg_resources/__init__.py @@ -46,7 +46,7 @@ except ImportError: import imp as _imp from pkg_resources.extern import six -from pkg_resources.extern.six.moves import urllib, map +from pkg_resources.extern.six.moves import urllib, map, filter # capture these to bypass sandboxing from os import utime @@ -77,9 +77,6 @@ __import__('pkg_resources.extern.packaging.version') __import__('pkg_resources.extern.packaging.specifiers') -filter = six.moves.filter -map = six.moves.map - if (3, 0) < sys.version_info < (3, 3): msg = ( "Support for Python 3.0-3.2 has been dropped. Future versions " -- cgit v1.2.1 From 397d759e48bc93597c535c2335c9da37178721a5 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 26 Jan 2016 14:34:31 -0500 Subject: Pull up DefaultProvider registration into a classmethod. --- pkg_resources/__init__.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/pkg_resources/__init__.py b/pkg_resources/__init__.py index 2ba5ca42..b4f910c6 100644 --- a/pkg_resources/__init__.py +++ b/pkg_resources/__init__.py @@ -1725,10 +1725,14 @@ class DefaultProvider(EggProvider): with open(path, 'rb') as stream: return stream.read() -register_loader_type(type(None), DefaultProvider) + @classmethod + def _register(cls): + register_loader_type(type(None), cls) -if importlib_machinery is not None: - register_loader_type(importlib_machinery.SourceFileLoader, DefaultProvider) + if importlib_machinery is not None: + register_loader_type(importlib_machinery.SourceFileLoader, cls) + +DefaultProvider._register() class EmptyProvider(NullProvider): -- cgit v1.2.1 From 66b3a623dd256def923ddde303b8c95592d0223b Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 26 Jan 2016 14:42:03 -0500 Subject: Adapt resolution of classes from importlib.machinery. Restores compatibility for PyPy3 where importlib.machinery exists but FileFinder and SourceFileLoader aren't implemented. --- pkg_resources/__init__.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/pkg_resources/__init__.py b/pkg_resources/__init__.py index b4f910c6..f15becbb 100644 --- a/pkg_resources/__init__.py +++ b/pkg_resources/__init__.py @@ -1727,10 +1727,9 @@ class DefaultProvider(EggProvider): @classmethod def _register(cls): - register_loader_type(type(None), cls) - - if importlib_machinery is not None: - register_loader_type(importlib_machinery.SourceFileLoader, cls) + loader_cls = getattr(importlib_machinery, 'SourceFileLoader', + type(None)) + register_loader_type(loader_cls, cls) DefaultProvider._register() @@ -2138,7 +2137,7 @@ def find_on_path(importer, path_item, only=False): break register_finder(pkgutil.ImpImporter, find_on_path) -if importlib_machinery is not None: +if hasattr(importlib_machinery, 'FileFinder'): register_finder(importlib_machinery.FileFinder, find_on_path) _declare_state('dict', _namespace_handlers={}) @@ -2255,7 +2254,7 @@ def file_ns_handler(importer, path_item, packageName, module): register_namespace_handler(pkgutil.ImpImporter, file_ns_handler) register_namespace_handler(zipimport.zipimporter, file_ns_handler) -if importlib_machinery is not None: +if hasattr(importlib_machinery, 'FileFinder'): register_namespace_handler(importlib_machinery.FileFinder, file_ns_handler) -- cgit v1.2.1 From 8a3d7feb9b044c9a51664eb3a91677240ed9ccf6 Mon Sep 17 00:00:00 2001 From: Matt Iversen Date: Fri, 29 Jan 2016 00:45:29 +1100 Subject: Test on pypy3 --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 54d9c395..6304d5e7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,6 +6,7 @@ python: - 3.4 - 3.5 - pypy + - pypy3 env: - "" - LC_ALL=C LC_CTYPE=C -- cgit v1.2.1 From e2081731f4c41a1461c76c262ed020321c71549b Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Thu, 28 Jan 2016 10:00:04 -0500 Subject: Update changelog --- CHANGES.txt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index 28d2ef63..90ae01a9 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -2,6 +2,15 @@ CHANGES ======= +19.6.1 +------ + +* Restore compatibility for PyPy 3 compatibility lost in + 19.4.1 addressing Issue #487. +* ``setuptools.launch`` shim now loads scripts in a new + namespace, avoiding getting relative imports from + the setuptools package on Python 2. + 19.6 ---- @@ -16,6 +25,7 @@ CHANGES expose the desired functionality. For example:: $ python -m setuptools.launch setup.py develop + * Issue #488: Fix dual manifestation of Extension class in extension packages installed as dependencies when Cython is present. -- cgit v1.2.1 From d6df1b3444cb487484ff8202cff121b147c0e1d5 Mon Sep 17 00:00:00 2001 From: Matthew Iversen Date: Fri, 29 Jan 2016 05:13:36 +1100 Subject: Allow failures with pypy3 for now --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index 6304d5e7..ae14639a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,6 +7,9 @@ python: - 3.5 - pypy - pypy3 +matrix: + allow_failures: + - python: pypy3 env: - "" - LC_ALL=C LC_CTYPE=C -- cgit v1.2.1 From 7b4bb264a3f44b18db85d623e23451379518e12a Mon Sep 17 00:00:00 2001 From: Matthew Iversen Date: Fri, 29 Jan 2016 05:15:41 +1100 Subject: Bumped to 19.6.1 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setuptools/version.py b/setuptools/version.py index 2e0bba87..41300aee 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '19.7' +__version__ = '19.6.1' -- cgit v1.2.1 From 0ed59a4c02f32cd23699b95cc3c38775a19f7840 Mon Sep 17 00:00:00 2001 From: Matthew Iversen Date: Fri, 29 Jan 2016 05:16:00 +1100 Subject: Added tag 19.6.1 for changeset 35d9179d0439 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 4f9c3a8f..2fd2cd33 100644 --- a/.hgtags +++ b/.hgtags @@ -240,3 +240,4 @@ f47f3671508b015e9bb735603d3a0a6ec6a77b01 19.4 0a68cbab72580a6f8d3bf9c45206669eefcd256b 19.5 34121bf49b1a7ac77da7f7c75105c8a920218dd7 19.6b1 3c2332e4ec72717bf17321473e5c3ad6e5778903 19.6 +35d9179d04390aada66eceae9ceb7b9274f67646 19.6.1 -- cgit v1.2.1 From eca386ea886913f115a4a4456702a838515a7e7e Mon Sep 17 00:00:00 2001 From: Matthew Iversen Date: Fri, 29 Jan 2016 05:19:57 +1100 Subject: Bumped to 19.6.2 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setuptools/version.py b/setuptools/version.py index 41300aee..89a23e8b 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '19.6.1' +__version__ = '19.6.2' -- cgit v1.2.1 From d16b24ef68298295224f078c96fcbf732aa0dacc Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 31 Jan 2016 04:24:04 -0500 Subject: Extract function _rebuild_mod_path --- pkg_resources/__init__.py | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/pkg_resources/__init__.py b/pkg_resources/__init__.py index f15becbb..3398a56b 100644 --- a/pkg_resources/__init__.py +++ b/pkg_resources/__init__.py @@ -2183,18 +2183,24 @@ def _handle_ns(packageName, path_item): path = module.__path__ path.append(subpath) loader.load_module(packageName) + _rebuild_mod_path(path, packageName, module) + return subpath - # Rebuild mod.__path__ ensuring that all entries are ordered - # corresponding to their sys.path order - sys_path= [(p and _normalize_cached(p) or p) for p in sys.path] - def sort_key(p): - parts = p.split(os.sep) - parts = parts[:-(packageName.count('.') + 1)] - return sys_path.index(_normalize_cached(os.sep.join(parts))) - path.sort(key=sort_key) - module.__path__[:] = [_normalize_cached(p) for p in path] - return subpath +def _rebuild_mod_path(orig_path, package_name, module): + """ + Rebuild module.__path__ ensuring that all entries are ordered + corresponding to their sys.path order + """ + sys_path= [(p and _normalize_cached(p) or p) for p in sys.path] + def sort_key(p): + parts = p.split(os.sep) + parts = parts[:-(package_name.count('.') + 1)] + return sys_path.index(_normalize_cached(os.sep.join(parts))) + + orig_path.sort(key=sort_key) + module.__path__[:] = [_normalize_cached(p) for p in orig_path] + def declare_namespace(packageName): """Declare that package 'packageName' is a namespace package""" -- cgit v1.2.1 From c8a0d2d70aedf13382c6e0a506c04d449851ec45 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 31 Jan 2016 04:28:06 -0500 Subject: Rename inner function and add docstring --- pkg_resources/__init__.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/pkg_resources/__init__.py b/pkg_resources/__init__.py index 3398a56b..70658062 100644 --- a/pkg_resources/__init__.py +++ b/pkg_resources/__init__.py @@ -2192,13 +2192,16 @@ def _rebuild_mod_path(orig_path, package_name, module): Rebuild module.__path__ ensuring that all entries are ordered corresponding to their sys.path order """ - sys_path= [(p and _normalize_cached(p) or p) for p in sys.path] - def sort_key(p): + sys_path = [(p and _normalize_cached(p) or p) for p in sys.path] + def position_in_sys_path(p): + """ + Return the ordinal of the path based on its position in sys.path + """ parts = p.split(os.sep) parts = parts[:-(package_name.count('.') + 1)] return sys_path.index(_normalize_cached(os.sep.join(parts))) - orig_path.sort(key=sort_key) + orig_path.sort(key=position_in_sys_path) module.__path__[:] = [_normalize_cached(p) for p in orig_path] -- cgit v1.2.1 From 94e1f4c266b7fdde993c5fde05f87dcc0afd186e Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 31 Jan 2016 04:46:53 -0500 Subject: Normalize all paths, not excluding ''. Fixes #491. --- pkg_resources/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg_resources/__init__.py b/pkg_resources/__init__.py index 70658062..7ba23bf5 100644 --- a/pkg_resources/__init__.py +++ b/pkg_resources/__init__.py @@ -2192,7 +2192,7 @@ def _rebuild_mod_path(orig_path, package_name, module): Rebuild module.__path__ ensuring that all entries are ordered corresponding to their sys.path order """ - sys_path = [(p and _normalize_cached(p) or p) for p in sys.path] + sys_path = [_normalize_cached(p) for p in sys.path] def position_in_sys_path(p): """ Return the ordinal of the path based on its position in sys.path -- cgit v1.2.1 From 584a30b2a7dd601ee46ff9746d9084e3a223ecc8 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 31 Jan 2016 04:50:26 -0500 Subject: Update changelog --- CHANGES.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index 90ae01a9..a1589974 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -2,6 +2,13 @@ CHANGES ======= +19.6.2 +------ + +* Issue #491: Correct regression incurred in 19.4 where + a double-namespace package installed using pip would + cause a TypeError. + 19.6.1 ------ -- cgit v1.2.1 From 15d072b8ff76fa2c1e0895041a3ba736d0db048e Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 31 Jan 2016 04:50:55 -0500 Subject: Added tag 19.6.2 for changeset d2782cbb2f15 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 2fd2cd33..11c94515 100644 --- a/.hgtags +++ b/.hgtags @@ -241,3 +241,4 @@ f47f3671508b015e9bb735603d3a0a6ec6a77b01 19.4 34121bf49b1a7ac77da7f7c75105c8a920218dd7 19.6b1 3c2332e4ec72717bf17321473e5c3ad6e5778903 19.6 35d9179d04390aada66eceae9ceb7b9274f67646 19.6.1 +d2782cbb2f15ca6831ab9426fbf8d4d6ca60db8a 19.6.2 -- cgit v1.2.1 From 783fe0bbcec577fcca5f5fbc247c2b0b86697721 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 31 Jan 2016 04:52:13 -0500 Subject: Bumped to 19.6.3 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setuptools/version.py b/setuptools/version.py index 89a23e8b..9228cbfb 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '19.6.2' +__version__ = '19.6.3' -- cgit v1.2.1 From 0dcee791dfdcfacddaaec79b29f30a347a147413 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 31 Jan 2016 21:35:13 -0500 Subject: Extract variable for template string --- pkg_resources/__init__.py | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/pkg_resources/__init__.py b/pkg_resources/__init__.py index 7ba23bf5..4fdc5f91 100644 --- a/pkg_resources/__init__.py +++ b/pkg_resources/__init__.py @@ -1174,22 +1174,23 @@ class ResourceManager: old_exc = sys.exc_info()[1] cache_path = self.extraction_path or get_default_cache() - err = ExtractionError("""Can't extract file(s) to egg cache + 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: - %s + %s -The Python egg cache directory is currently set to: + The Python egg cache directory is currently set to: - %s + %s -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. -""" % (old_exc, 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. + """).lstrip() + err = ExtractionError(tmpl % (old_exc, cache_path)) err.manager = self err.cache_path = cache_path err.original_error = old_exc -- cgit v1.2.1 From f9bd9b9f5df54ef5a0bf8d16c3a889ab8c640580 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 31 Jan 2016 21:36:23 -0500 Subject: Use new style string formatting --- pkg_resources/__init__.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg_resources/__init__.py b/pkg_resources/__init__.py index 4fdc5f91..d04cd347 100644 --- a/pkg_resources/__init__.py +++ b/pkg_resources/__init__.py @@ -1180,17 +1180,17 @@ class ResourceManager: The following error occurred while trying to extract file(s) to the Python egg cache: - %s + {old_exc} The Python egg cache directory is currently set to: - %s + {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. """).lstrip() - err = ExtractionError(tmpl % (old_exc, cache_path)) + err = ExtractionError(tmpl.format(**locals())) err.manager = self err.cache_path = cache_path err.original_error = old_exc -- cgit v1.2.1 From 3ae46c30225eb46e1f5aada1a19e88b79f04dc72 Mon Sep 17 00:00:00 2001 From: Julien Cigar Date: Wed, 3 Feb 2016 10:25:07 +0100 Subject: FreeBSD: Add root certificate from ca_root_nss. On FreeBSD root certificates from certificate authorities included in the Mozilla NSS library are provided by the ca_root_nss package: jcigar@frodon:~/ > pkg info -l ca_root_nss-3.21 ca_root_nss-3.21: /usr/local/etc/ssl/cert.pem.sample /usr/local/openssl/cert.pem.sample /usr/local/share/certs/ca-root-nss.crt /usr/local/share/licenses/ca_root_nss-3.21/LICENSE /usr/local/share/licenses/ca_root_nss-3.21/MPL /usr/local/share/licenses/ca_root_nss-3.21/catalog.mk On some machines there is no symbolic link (/etc/ssl/cert.pem) installed --- setuptools/ssl_support.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setuptools/ssl_support.py b/setuptools/ssl_support.py index 511d2fa8..657197cf 100644 --- a/setuptools/ssl_support.py +++ b/setuptools/ssl_support.py @@ -25,6 +25,7 @@ cert_paths = """ /usr/local/share/certs/ca-root.crt /etc/ssl/cert.pem /System/Library/OpenSSL/certs/cert.pem +/usr/local/share/certs/ca-root-nss.crt """.strip().split() -- cgit v1.2.1 From 725bf101f83f4a8f1bd3e11704664481d102775d Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 3 Feb 2016 08:20:09 -0500 Subject: Update changelog --- CHANGES.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGES.txt b/CHANGES.txt index a1589974..50f1f8f1 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -2,6 +2,12 @@ CHANGES ======= +19.7 +---- + +* `Off-project PR `_: + For FreeBSD, also honor root certificates from ca_root_nss. + 19.6.2 ------ -- cgit v1.2.1 From 9221fdd1e7f04d257d5cf8af98e8f94bd73a4fec Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 3 Feb 2016 08:20:24 -0500 Subject: Bumped to 19.7 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setuptools/version.py b/setuptools/version.py index 9228cbfb..2e0bba87 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '19.6.3' +__version__ = '19.7' -- cgit v1.2.1 From 0b07812cf5aeb88602502e8338cfbc660bc94ffe Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 3 Feb 2016 08:20:28 -0500 Subject: Added tag 19.7 for changeset c6e619ce910d --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 11c94515..0fa346ab 100644 --- a/.hgtags +++ b/.hgtags @@ -242,3 +242,4 @@ f47f3671508b015e9bb735603d3a0a6ec6a77b01 19.4 3c2332e4ec72717bf17321473e5c3ad6e5778903 19.6 35d9179d04390aada66eceae9ceb7b9274f67646 19.6.1 d2782cbb2f15ca6831ab9426fbf8d4d6ca60db8a 19.6.2 +c6e619ce910d1650cc2433f94e5594964085f973 19.7 -- cgit v1.2.1 From 53bef9f89286363756bc8efbbba243486897969a Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 3 Feb 2016 08:22:13 -0500 Subject: Bumped to 19.8 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setuptools/version.py b/setuptools/version.py index 2e0bba87..5d042851 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '19.7' +__version__ = '19.8' -- cgit v1.2.1 From e3d7334022838f8153a06b0105c6b8f4a32762a2 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 3 Feb 2016 09:02:34 -0500 Subject: Rewrite setup/teardown methods as pytest fixtures, encapsulating concepts for clarity. Incidentally, this also fixes #231. --- pkg_resources/tests/test_resources.py | 94 +++++++++++++++++++---------------- 1 file changed, 52 insertions(+), 42 deletions(-) diff --git a/pkg_resources/tests/test_resources.py b/pkg_resources/tests/test_resources.py index 6f68bf77..49acd036 100644 --- a/pkg_resources/tests/test_resources.py +++ b/pkg_resources/tests/test_resources.py @@ -610,35 +610,41 @@ class TestParsing: class TestNamespaces: - def setup_method(self, method): - self._ns_pkgs = pkg_resources._namespace_packages.copy() - - # Further, test case where the temp dir is a symlink, where applicable - # See #231 - if hasattr(os, 'symlink'): - real_tmpdir = tempfile.mkdtemp(prefix="real-tests-setuptools-") - tmpdir_base, tmpdir_name = os.path.split(real_tmpdir) - tmpdir = os.path.join(tmpdir_base, tmpdir_name[5:]) - os.symlink(real_tmpdir, tmpdir) - self._real_tmpdir = real_tmpdir - self._tmpdir = tmpdir - else: - tmpdir = tempfile.mkdtemp(prefix="tests-setuptools-") - self._real_tmpdir = self._tmpdir = tmpdir - - os.makedirs(os.path.join(self._tmpdir, "site-pkgs")) - self._prev_sys_path = sys.path[:] - sys.path.append(os.path.join(self._tmpdir, "site-pkgs")) - - def teardown_method(self, method): - shutil.rmtree(self._real_tmpdir) - if os.path.islink(self._tmpdir): - os.unlink(self._tmpdir) - - pkg_resources._namespace_packages = self._ns_pkgs.copy() - sys.path = self._prev_sys_path[:] - - def test_two_levels_deep(self): + @pytest.yield_fixture + def symlinked_tmpdir(self, tmpdir): + """ + Where available, return the tempdir as a symlink, + which as revealed in #231 is more fragile than + a natural tempdir. + """ + if not hasattr(os, 'symlink'): + return str(tmpdir) + + link_name = str(tmpdir) + '-linked' + os.symlink(str(tmpdir), link_name) + try: + yield type(tmpdir)(link_name) + finally: + os.unlink(link_name) + + @pytest.yield_fixture(autouse=True) + def patched_path(self, tmpdir): + """ + Patch sys.path to include the 'site-pkgs' dir. Also + restore pkg_resources._namespace_packages to its + former state. + """ + saved_ns_pkgs = pkg_resources._namespace_packages.copy() + saved_sys_path = sys.path[:] + site_pkgs = tmpdir.mkdir('site-pkgs') + sys.path.append(str(site_pkgs)) + try: + yield + finally: + pkg_resources._namespace_packages = saved_ns_pkgs + sys.path = saved_sys_path + + def test_two_levels_deep(self, symlinked_tmpdir): """ Test nested namespace packages Create namespace packages in the following tree : @@ -647,16 +653,18 @@ class TestNamespaces: Check both are in the _namespace_packages dict and that their __path__ is correct """ - sys.path.append(os.path.join(self._tmpdir, "site-pkgs2")) - os.makedirs(os.path.join(self._tmpdir, "site-pkgs", "pkg1", "pkg2")) - os.makedirs(os.path.join(self._tmpdir, "site-pkgs2", "pkg1", "pkg2")) + real_tmpdir = str(symlinked_tmpdir.realpath()) + tmpdir = str(symlinked_tmpdir) + sys.path.append(os.path.join(tmpdir, "site-pkgs2")) + os.makedirs(os.path.join(tmpdir, "site-pkgs", "pkg1", "pkg2")) + os.makedirs(os.path.join(tmpdir, "site-pkgs2", "pkg1", "pkg2")) ns_str = "__import__('pkg_resources').declare_namespace(__name__)\n" for site in ["site-pkgs", "site-pkgs2"]: - pkg1_init = open(os.path.join(self._tmpdir, site, + pkg1_init = open(os.path.join(tmpdir, site, "pkg1", "__init__.py"), "w") pkg1_init.write(ns_str) pkg1_init.close() - pkg2_init = open(os.path.join(self._tmpdir, site, + pkg2_init = open(os.path.join(tmpdir, site, "pkg1", "pkg2", "__init__.py"), "w") pkg2_init.write(ns_str) pkg2_init.close() @@ -669,12 +677,12 @@ class TestNamespaces: assert pkg_resources._namespace_packages["pkg1"] == ["pkg1.pkg2"] # check the __path__ attribute contains both paths expected = [ - os.path.join(self._real_tmpdir, "site-pkgs", "pkg1", "pkg2"), - os.path.join(self._real_tmpdir, "site-pkgs2", "pkg1", "pkg2"), + os.path.join(real_tmpdir, "site-pkgs", "pkg1", "pkg2"), + os.path.join(real_tmpdir, "site-pkgs2", "pkg1", "pkg2"), ] assert pkg1.pkg2.__path__ == expected - def test_path_order(self): + def test_path_order(self, symlinked_tmpdir): """ Test that if multiple versions of the same namespace package subpackage are on different sys.path entries, that only the one earliest on @@ -684,6 +692,8 @@ class TestNamespaces: Regression test for https://bitbucket.org/pypa/setuptools/issues/207 """ + real_tmpdir = str(symlinked_tmpdir.realpath()) + tmpdir = str(symlinked_tmpdir) site_pkgs = ["site-pkgs", "site-pkgs2", "site-pkgs3"] ns_str = "__import__('pkg_resources').declare_namespace(__name__)\n" @@ -691,19 +701,19 @@ class TestNamespaces: for idx, site in enumerate(site_pkgs): if idx > 0: - sys.path.append(os.path.join(self._tmpdir, site)) - os.makedirs(os.path.join(self._tmpdir, site, "nspkg", "subpkg")) - with open(os.path.join(self._tmpdir, site, "nspkg", + sys.path.append(os.path.join(tmpdir, site)) + os.makedirs(os.path.join(tmpdir, site, "nspkg", "subpkg")) + with open(os.path.join(tmpdir, site, "nspkg", "__init__.py"), "w") as f: f.write(ns_str) - with open(os.path.join(self._tmpdir, site, "nspkg", "subpkg", + with open(os.path.join(tmpdir, site, "nspkg", "subpkg", "__init__.py"), "w") as f: f.write(vers_str % (idx + 1)) import nspkg.subpkg import nspkg - assert nspkg.__path__ == [os.path.join(self._real_tmpdir, site, + assert nspkg.__path__ == [os.path.join(real_tmpdir, site, "nspkg") for site in site_pkgs] assert nspkg.subpkg.__version__ == 1 -- cgit v1.2.1 From 397879392e928a873953bddd978dd87292211e62 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 3 Feb 2016 10:06:00 -0500 Subject: Use py.path objects for cleaner setup --- pkg_resources/tests/test_resources.py | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/pkg_resources/tests/test_resources.py b/pkg_resources/tests/test_resources.py index 49acd036..00f0307d 100644 --- a/pkg_resources/tests/test_resources.py +++ b/pkg_resources/tests/test_resources.py @@ -653,21 +653,17 @@ class TestNamespaces: Check both are in the _namespace_packages dict and that their __path__ is correct """ - real_tmpdir = str(symlinked_tmpdir.realpath()) - tmpdir = str(symlinked_tmpdir) - sys.path.append(os.path.join(tmpdir, "site-pkgs2")) - os.makedirs(os.path.join(tmpdir, "site-pkgs", "pkg1", "pkg2")) - os.makedirs(os.path.join(tmpdir, "site-pkgs2", "pkg1", "pkg2")) + real_tmpdir = symlinked_tmpdir.realpath() + tmpdir = symlinked_tmpdir + sys.path.append(str(tmpdir / 'site-pkgs2')) + site_dirs = tmpdir / 'site-pkgs', tmpdir / 'site-pkgs2' ns_str = "__import__('pkg_resources').declare_namespace(__name__)\n" - for site in ["site-pkgs", "site-pkgs2"]: - pkg1_init = open(os.path.join(tmpdir, site, - "pkg1", "__init__.py"), "w") - pkg1_init.write(ns_str) - pkg1_init.close() - pkg2_init = open(os.path.join(tmpdir, site, - "pkg1", "pkg2", "__init__.py"), "w") - pkg2_init.write(ns_str) - pkg2_init.close() + for site in site_dirs: + pkg1 = site / 'pkg1' + pkg2 = pkg1 / 'pkg2' + pkg2.ensure_dir() + (pkg1 / '__init__.py').write_text(ns_str, encoding='utf-8') + (pkg2 / '__init__.py').write_text(ns_str, encoding='utf-8') import pkg1 assert "pkg1" in pkg_resources._namespace_packages # attempt to import pkg2 from site-pkgs2 @@ -677,8 +673,8 @@ class TestNamespaces: assert pkg_resources._namespace_packages["pkg1"] == ["pkg1.pkg2"] # check the __path__ attribute contains both paths expected = [ - os.path.join(real_tmpdir, "site-pkgs", "pkg1", "pkg2"), - os.path.join(real_tmpdir, "site-pkgs2", "pkg1", "pkg2"), + str(real_tmpdir / "site-pkgs" / "pkg1" / "pkg2"), + str(real_tmpdir / "site-pkgs2" / "pkg1" / "pkg2"), ] assert pkg1.pkg2.__path__ == expected -- cgit v1.2.1 From 656a5f3b9c4f289c28e2810ce10ca71b571d6a2c Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 3 Feb 2016 10:13:36 -0500 Subject: Extract variable for readability --- pkg_resources/tests/test_resources.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pkg_resources/tests/test_resources.py b/pkg_resources/tests/test_resources.py index 00f0307d..c6ab6d0e 100644 --- a/pkg_resources/tests/test_resources.py +++ b/pkg_resources/tests/test_resources.py @@ -709,7 +709,9 @@ class TestNamespaces: import nspkg.subpkg import nspkg - assert nspkg.__path__ == [os.path.join(real_tmpdir, site, - "nspkg") - for site in site_pkgs] + expected = [ + os.path.join(real_tmpdir, site, "nspkg") + for site in site_pkgs + ] + assert nspkg.__path__ == expected assert nspkg.subpkg.__version__ == 1 -- cgit v1.2.1 From 3ff6789b02e2543cb352c8c9f89ceda5c61ca74e Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 3 Feb 2016 10:16:32 -0500 Subject: Use py.path objects for cleaner setup --- pkg_resources/tests/test_resources.py | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/pkg_resources/tests/test_resources.py b/pkg_resources/tests/test_resources.py index c6ab6d0e..553eecb4 100644 --- a/pkg_resources/tests/test_resources.py +++ b/pkg_resources/tests/test_resources.py @@ -688,30 +688,30 @@ class TestNamespaces: Regression test for https://bitbucket.org/pypa/setuptools/issues/207 """ - real_tmpdir = str(symlinked_tmpdir.realpath()) - tmpdir = str(symlinked_tmpdir) - site_pkgs = ["site-pkgs", "site-pkgs2", "site-pkgs3"] + tmpdir = symlinked_tmpdir + site_dirs = ( + tmpdir / "site-pkgs", + tmpdir / "site-pkgs2", + tmpdir / "site-pkgs3", + ) ns_str = "__import__('pkg_resources').declare_namespace(__name__)\n" vers_str = "__version__ = %r" - for idx, site in enumerate(site_pkgs): + for idx, site in enumerate(site_dirs): if idx > 0: - sys.path.append(os.path.join(tmpdir, site)) - os.makedirs(os.path.join(tmpdir, site, "nspkg", "subpkg")) - with open(os.path.join(tmpdir, site, "nspkg", - "__init__.py"), "w") as f: - f.write(ns_str) - - with open(os.path.join(tmpdir, site, "nspkg", "subpkg", - "__init__.py"), "w") as f: - f.write(vers_str % (idx + 1)) + sys.path.append(str(site)) + nspkg = site / 'nspkg' + subpkg = nspkg / 'subpkg' + subpkg.ensure_dir() + (nspkg / '__init__.py').write_text(ns_str, encoding='utf-8') + (subpkg / '__init__.py').write_text(vers_str % (idx + 1), encoding='utf-8') import nspkg.subpkg import nspkg expected = [ - os.path.join(real_tmpdir, site, "nspkg") - for site in site_pkgs + str(site.realpath() / 'nspkg') + for site in site_dirs ] assert nspkg.__path__ == expected assert nspkg.subpkg.__version__ == 1 -- cgit v1.2.1 From a9a38182f64da197bd52efdf3c63d68448c80942 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 3 Feb 2016 10:17:48 -0500 Subject: Use consistent numbering for clarity. --- pkg_resources/tests/test_resources.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg_resources/tests/test_resources.py b/pkg_resources/tests/test_resources.py index 553eecb4..5b3ba546 100644 --- a/pkg_resources/tests/test_resources.py +++ b/pkg_resources/tests/test_resources.py @@ -698,14 +698,14 @@ class TestNamespaces: ns_str = "__import__('pkg_resources').declare_namespace(__name__)\n" vers_str = "__version__ = %r" - for idx, site in enumerate(site_dirs): - if idx > 0: + for number, site in enumerate(site_dirs, 1): + if number > 1: sys.path.append(str(site)) nspkg = site / 'nspkg' subpkg = nspkg / 'subpkg' subpkg.ensure_dir() (nspkg / '__init__.py').write_text(ns_str, encoding='utf-8') - (subpkg / '__init__.py').write_text(vers_str % (idx + 1), encoding='utf-8') + (subpkg / '__init__.py').write_text(vers_str % number, encoding='utf-8') import nspkg.subpkg import nspkg -- cgit v1.2.1 From 20413e816e9c0809c97598b0a758120be6460f90 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 3 Feb 2016 10:20:29 -0500 Subject: Extract ns_str as class attribute --- pkg_resources/tests/test_resources.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pkg_resources/tests/test_resources.py b/pkg_resources/tests/test_resources.py index 5b3ba546..e25fbc78 100644 --- a/pkg_resources/tests/test_resources.py +++ b/pkg_resources/tests/test_resources.py @@ -610,6 +610,8 @@ class TestParsing: class TestNamespaces: + ns_str = "__import__('pkg_resources').declare_namespace(__name__)\n" + @pytest.yield_fixture def symlinked_tmpdir(self, tmpdir): """ @@ -657,13 +659,12 @@ class TestNamespaces: tmpdir = symlinked_tmpdir sys.path.append(str(tmpdir / 'site-pkgs2')) site_dirs = tmpdir / 'site-pkgs', tmpdir / 'site-pkgs2' - ns_str = "__import__('pkg_resources').declare_namespace(__name__)\n" for site in site_dirs: pkg1 = site / 'pkg1' pkg2 = pkg1 / 'pkg2' pkg2.ensure_dir() - (pkg1 / '__init__.py').write_text(ns_str, encoding='utf-8') - (pkg2 / '__init__.py').write_text(ns_str, encoding='utf-8') + (pkg1 / '__init__.py').write_text(self.ns_str, encoding='utf-8') + (pkg2 / '__init__.py').write_text(self.ns_str, encoding='utf-8') import pkg1 assert "pkg1" in pkg_resources._namespace_packages # attempt to import pkg2 from site-pkgs2 @@ -695,7 +696,6 @@ class TestNamespaces: tmpdir / "site-pkgs3", ) - ns_str = "__import__('pkg_resources').declare_namespace(__name__)\n" vers_str = "__version__ = %r" for number, site in enumerate(site_dirs, 1): @@ -704,7 +704,7 @@ class TestNamespaces: nspkg = site / 'nspkg' subpkg = nspkg / 'subpkg' subpkg.ensure_dir() - (nspkg / '__init__.py').write_text(ns_str, encoding='utf-8') + (nspkg / '__init__.py').write_text(self.ns_str, encoding='utf-8') (subpkg / '__init__.py').write_text(vers_str % number, encoding='utf-8') import nspkg.subpkg -- cgit v1.2.1 From 8954900a7c88831cf96679f404c2e02e16cefda0 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 3 Feb 2016 10:22:24 -0500 Subject: Remove unused imports --- pkg_resources/tests/test_resources.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/pkg_resources/tests/test_resources.py b/pkg_resources/tests/test_resources.py index e25fbc78..542795cf 100644 --- a/pkg_resources/tests/test_resources.py +++ b/pkg_resources/tests/test_resources.py @@ -1,7 +1,5 @@ import os import sys -import tempfile -import shutil import string from pkg_resources.extern.six.moves import map -- cgit v1.2.1 From 0e689bb35e8af9f079f6985a11c80268575f786e Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 7 Feb 2016 09:25:06 -0500 Subject: Backout changeset 1ae2a75724bbba56373784f185a7f235ed0f24a4 --- setuptools/command/install_egg_info.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setuptools/command/install_egg_info.py b/setuptools/command/install_egg_info.py index fd0f118b..992709f1 100755 --- a/setuptools/command/install_egg_info.py +++ b/setuptools/command/install_egg_info.py @@ -27,7 +27,7 @@ class install_egg_info(Command): ).egg_name() + '.egg-info' self.source = ei_cmd.egg_info self.target = os.path.join(self.install_dir, basename) - self.outputs = [self.target] + self.outputs = [] def run(self): self.run_command('egg_info') -- cgit v1.2.1 From 64378483fd433d4c7ca6a50c588b9bcb297de392 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 7 Feb 2016 09:31:49 -0500 Subject: Bumped to 20.0 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setuptools/version.py b/setuptools/version.py index 5d042851..b4d85e51 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '19.8' +__version__ = '20.0' -- cgit v1.2.1 From bc9ec216eb133fd0b593dfd2661878f9c020bc7a Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 7 Feb 2016 09:38:18 -0500 Subject: Fix syntax errors on Python 2 --- pkg_resources/tests/test_resources.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg_resources/tests/test_resources.py b/pkg_resources/tests/test_resources.py index 542795cf..efaf8db4 100644 --- a/pkg_resources/tests/test_resources.py +++ b/pkg_resources/tests/test_resources.py @@ -618,7 +618,8 @@ class TestNamespaces: a natural tempdir. """ if not hasattr(os, 'symlink'): - return str(tmpdir) + yield str(tmpdir) + return link_name = str(tmpdir) + '-linked' os.symlink(str(tmpdir), link_name) -- cgit v1.2.1 From b8d92af19e26efa9bf50c2d3e63618b0a6f09fa5 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 7 Feb 2016 09:38:50 -0500 Subject: Fix failing tests on Python 2 --- pkg_resources/tests/test_resources.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkg_resources/tests/test_resources.py b/pkg_resources/tests/test_resources.py index efaf8db4..f2afdf95 100644 --- a/pkg_resources/tests/test_resources.py +++ b/pkg_resources/tests/test_resources.py @@ -1,3 +1,5 @@ +from __future__ import unicode_literals + import os import sys import string -- cgit v1.2.1 From f15fef5e8c96e2d20ed2007fa7cacd9ef61c9313 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 7 Feb 2016 09:40:56 -0500 Subject: Added tag 20.0 for changeset 2a60daeff0cd --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 0fa346ab..678b2e36 100644 --- a/.hgtags +++ b/.hgtags @@ -243,3 +243,4 @@ f47f3671508b015e9bb735603d3a0a6ec6a77b01 19.4 35d9179d04390aada66eceae9ceb7b9274f67646 19.6.1 d2782cbb2f15ca6831ab9426fbf8d4d6ca60db8a 19.6.2 c6e619ce910d1650cc2433f94e5594964085f973 19.7 +2a60daeff0cdb039b20b2058aaad7dae7bcd2c1c 20.0 -- cgit v1.2.1 From 5375ca253fb968b9351658de2abc738f758071ec Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 7 Feb 2016 09:42:10 -0500 Subject: Bumped to 20.1 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setuptools/version.py b/setuptools/version.py index b4d85e51..0e828f12 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '20.0' +__version__ = '20.1' -- cgit v1.2.1 From 0975916c1436759b5e373733561142caf708def4 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Thu, 11 Feb 2016 23:29:17 -0500 Subject: Replace upload docs with a reference to distutils docs, as setuptools no longer provides an upload command. --- docs/setuptools.txt | 51 +++------------------------------------------------ 1 file changed, 3 insertions(+), 48 deletions(-) diff --git a/docs/setuptools.txt b/docs/setuptools.txt index d6a62de8..064acd5f 100644 --- a/docs/setuptools.txt +++ b/docs/setuptools.txt @@ -2328,54 +2328,9 @@ available: ``upload`` - Upload source and/or egg distributions to PyPI =========================================================== -PyPI now supports uploading project files for redistribution; uploaded files -are easily found by EasyInstall, even if you don't have download links on your -project's home page. - -Although Python 2.5 will support uploading all types of distributions to PyPI, -setuptools only supports source distributions and eggs. (This is partly -because PyPI's upload support is currently broken for various other file -types.) To upload files, you must include the ``upload`` command *after* the -``sdist`` or ``bdist_egg`` commands on the setup command line. For example:: - - setup.py bdist_egg upload # create an egg and upload it - setup.py sdist upload # create a source distro and upload it - setup.py sdist bdist_egg upload # create and upload both - -Note that to upload files for a project, the corresponding version must already -be registered with PyPI, using the distutils ``register`` command. It's -usually a good idea to include the ``register`` command at the start of the -command line, so that any registration problems can be found and fixed before -building and uploading the distributions, e.g.:: - - setup.py register sdist bdist_egg upload - -This will update PyPI's listing for your project's current version. - -Note, by the way, that the metadata in your ``setup()`` call determines what -will be listed in PyPI for your package. Try to fill out as much of it as -possible, as it will save you a lot of trouble manually adding and updating -your PyPI listings. Just put it in ``setup.py`` and use the ``register`` -command to keep PyPI up to date. - -The ``upload`` command has a few options worth noting: - -``--sign, -s`` - Sign each uploaded file using GPG (GNU Privacy Guard). The ``gpg`` program - must be available for execution on the system ``PATH``. - -``--identity=NAME, -i NAME`` - Specify the identity or key name for GPG to use when signing. The value of - this option will be passed through the ``--local-user`` option of the - ``gpg`` program. - -``--show-response`` - Display the full response text from server; this is useful for debugging - PyPI problems. - -``--repository=URL, -r URL`` - The URL of the repository to upload to. Defaults to - https://pypi.python.org/pypi (i.e., the main PyPI installation). +The ``upload`` command is implemented and `documented +`_ +in distutils. .. _upload_docs: -- cgit v1.2.1 From 5367a7399762a9098ea689c7cdcb54fb9748dd66 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Thu, 11 Feb 2016 23:47:28 -0500 Subject: Override upload command to load passwords from keyring when available and not otherwise specified. --- CHANGES.txt | 8 ++++++++ docs/setuptools.txt | 16 ++++++++++++++++ setuptools/command/__init__.py | 2 +- setuptools/command/upload.py | 23 +++++++++++++++++++++++ 4 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 setuptools/command/upload.py diff --git a/CHANGES.txt b/CHANGES.txt index 9089b4b8..a7a70ab7 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -2,6 +2,14 @@ CHANGES ======= +20.1 +---- + +Added support for using passwords from keyring in the upload +command. See `the upload docs +`_ +for details. + 20.0 ---- diff --git a/docs/setuptools.txt b/docs/setuptools.txt index 064acd5f..610a0e61 100644 --- a/docs/setuptools.txt +++ b/docs/setuptools.txt @@ -2332,6 +2332,22 @@ The ``upload`` command is implemented and `documented `_ in distutils. +Setuptools augments the ``upload`` command with support +for `keyring `_, +allowing the password to be stored in a secure +location and not in plaintext in the .pypirc file. To use +keyring, first install keyring and set the password for +the relevant repository, e.g.:: + + python -m keyring set + Password for '' in '': ******** + +Then, in .pypirc, set the repository configuration as normal, +but omit the password. Thereafter, uploads will use the +password from the keyring. + +New in 20.1: Added keyring support. + .. _upload_docs: ``upload_docs`` - Upload package documentation to PyPI diff --git a/setuptools/command/__init__.py b/setuptools/command/__init__.py index f6dbc39c..3fb2f6df 100644 --- a/setuptools/command/__init__.py +++ b/setuptools/command/__init__.py @@ -2,7 +2,7 @@ __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', + 'register', 'bdist_wininst', 'upload_docs', 'upload', ] from distutils.command.bdist import bdist diff --git a/setuptools/command/upload.py b/setuptools/command/upload.py new file mode 100644 index 00000000..08c20ba8 --- /dev/null +++ b/setuptools/command/upload.py @@ -0,0 +1,23 @@ +from distutils.command import upload as orig + + +class upload(orig.upload): + """ + Override default upload behavior to look up password + in the keyring if available. + """ + + def finalize_options(self): + orig.upload.finalize_options(self) + self.password or self._load_password_from_keyring() + + def _load_password_from_keyring(self): + """ + Attempt to load password from keyring. Suppress Exceptions. + """ + try: + keyring = __import__('keyring') + self.password = keyring.get_password(self.repository, + self.username) + except Exception: + pass -- cgit v1.2.1 From b70dc2865f85659d18a3b1e5445eda40c18f1479 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Thu, 11 Feb 2016 23:49:12 -0500 Subject: Added tag 20.1 for changeset 06c9d3ffae80 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 678b2e36..4fa766d3 100644 --- a/.hgtags +++ b/.hgtags @@ -244,3 +244,4 @@ f47f3671508b015e9bb735603d3a0a6ec6a77b01 19.4 d2782cbb2f15ca6831ab9426fbf8d4d6ca60db8a 19.6.2 c6e619ce910d1650cc2433f94e5594964085f973 19.7 2a60daeff0cdb039b20b2058aaad7dae7bcd2c1c 20.0 +06c9d3ffae80d7f5786c0a454d040d253d47fc03 20.1 -- cgit v1.2.1 From fdc4a82ac68ac18c10151546bc660f56dca131ab Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Thu, 11 Feb 2016 23:51:09 -0500 Subject: Bumped to 20.2 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setuptools/version.py b/setuptools/version.py index 0e828f12..425e19d9 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '20.1' +__version__ = '20.2' -- cgit v1.2.1 From 1e0ecae918c4c43f29b139b0dffa9d73b208e13b Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 12 Feb 2016 11:07:19 -0500 Subject: Remove unused import --- setuptools/command/upload_docs.py | 1 - 1 file changed, 1 deletion(-) diff --git a/setuptools/command/upload_docs.py b/setuptools/command/upload_docs.py index ca35a3ce..0a57d5d3 100644 --- a/setuptools/command/upload_docs.py +++ b/setuptools/command/upload_docs.py @@ -13,7 +13,6 @@ import os import socket import zipfile import tempfile -import sys import shutil from setuptools.extern import six -- cgit v1.2.1 From 076e6b32c38a5bd6141bf533ff87eb23e54eca67 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 12 Feb 2016 11:10:53 -0500 Subject: Upload_docs should also resolve passwords from keyring same as upload command. --- CHANGES.txt | 8 +++++++- setuptools/command/upload_docs.py | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index a7a70ab7..504281da 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -2,10 +2,16 @@ CHANGES ======= +20.1.1 +------ + +* Update ``upload_docs`` command to also honor keyring + for password resolution. + 20.1 ---- -Added support for using passwords from keyring in the upload +* Added support for using passwords from keyring in the upload command. See `the upload docs `_ for details. diff --git a/setuptools/command/upload_docs.py b/setuptools/command/upload_docs.py index 0a57d5d3..f887b47e 100644 --- a/setuptools/command/upload_docs.py +++ b/setuptools/command/upload_docs.py @@ -8,7 +8,6 @@ PyPI's pythonhosted.org). from base64 import standard_b64encode from distutils import log from distutils.errors import DistutilsOptionError -from distutils.command.upload import upload import os import socket import zipfile @@ -19,6 +18,7 @@ from setuptools.extern import six from setuptools.extern.six.moves import http_client, urllib from pkg_resources import iter_entry_points +from .upload import upload errors = 'surrogateescape' if six.PY3 else 'strict' -- cgit v1.2.1 From f8b1293c408bbb652bec3f2ae6e5b4f33f3ca55e Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 12 Feb 2016 11:11:07 -0500 Subject: Bumped to 20.1.1 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setuptools/version.py b/setuptools/version.py index 425e19d9..44947284 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '20.2' +__version__ = '20.1.1' -- cgit v1.2.1 From 3a209fa2a09a19f0ba5ee9b708475de8b00dd54f Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 12 Feb 2016 11:11:08 -0500 Subject: Added tag 20.1.1 for changeset 919a40f18431 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 4fa766d3..e2bfe097 100644 --- a/.hgtags +++ b/.hgtags @@ -245,3 +245,4 @@ d2782cbb2f15ca6831ab9426fbf8d4d6ca60db8a 19.6.2 c6e619ce910d1650cc2433f94e5594964085f973 19.7 2a60daeff0cdb039b20b2058aaad7dae7bcd2c1c 20.0 06c9d3ffae80d7f5786c0a454d040d253d47fc03 20.1 +919a40f1843131249f98104c73f3aee3fc835e67 20.1.1 -- cgit v1.2.1 From 236b0499acc167551df9553f7d20e8a5d0c010e0 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 12 Feb 2016 11:13:37 -0500 Subject: Bumped to 20.1.2 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setuptools/version.py b/setuptools/version.py index 44947284..4211fc44 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '20.1.1' +__version__ = '20.1.2' -- cgit v1.2.1 From 8ccd428cd2a733891bffce13e017774ea82bd8d2 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 12 Feb 2016 11:15:03 -0500 Subject: Correct syntax in changelog --- CHANGES.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 504281da..75b13e46 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -12,9 +12,9 @@ CHANGES ---- * Added support for using passwords from keyring in the upload -command. See `the upload docs -`_ -for details. + command. See `the upload docs + `_ + for details. 20.0 ---- -- cgit v1.2.1