From 41f634812f1ee6b734e7d5fb25486b66ab351d0a Mon Sep 17 00:00:00 2001 From: matej Date: Tue, 18 Nov 2014 14:38:56 +0100 Subject: Different treatment of --user option to easy_install (refs #285) --- setuptools/command/easy_install.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 2e00b996..d0bae2b2 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -148,12 +148,9 @@ class easy_install(Command): create_index = PackageIndex def initialize_options(self): - if site.ENABLE_USER_SITE: - whereami = os.path.abspath(__file__) - self.user = whereami.startswith(site.USER_SITE) - else: - self.user = 0 - + # the --user option seemst to be an opt-in one, + # so the default should be False. + self.user = 0 self.zip_ok = self.local_snapshots_ok = None self.install_dir = self.script_dir = self.exclude_scripts = None self.index_url = None -- cgit v1.2.1 From 9d6a6e5927ae0e67164383e419f3145fc154467e Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 4 Jan 2015 11:35:16 -0500 Subject: Use except/as, now supported by Python 2.6 --- setuptools/command/easy_install.py | 12 ++++-------- setuptools/command/sdist.py | 3 ++- setuptools/command/upload_docs.py | 3 +-- setuptools/dist.py | 3 +-- setuptools/msvc9_support.py | 3 +-- setuptools/package_index.py | 15 +++++---------- setuptools/sandbox.py | 3 +-- setuptools/tests/test_packageindex.py | 12 ++++-------- setuptools/tests/test_sdist.py | 12 ++++-------- 9 files changed, 23 insertions(+), 43 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 1a2f56ae..02ce7636 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -698,13 +698,11 @@ Please make the appropriate changes for your system and try again. distros = WorkingSet([]).resolve( [requirement], self.local_index, self.easy_install ) - except DistributionNotFound: - e = sys.exc_info()[1] + except DistributionNotFound as e: raise DistutilsError( "Could not find required distribution %s" % e.args ) - except VersionConflict: - e = sys.exc_info()[1] + except VersionConflict as e: raise DistutilsError( "Installed distribution %s conflicts with requirement %s" % e.args @@ -1044,8 +1042,7 @@ See the setuptools documentation for the "develop" command for more info. ) try: run_setup(setup_script, args) - except SystemExit: - v = sys.exc_info()[1] + except SystemExit as v: raise DistutilsError("Setup script exited with %s" % (v.args[0],)) def build_and_install(self, setup_script, setup_base): @@ -1889,8 +1886,7 @@ def chmod(path, mode): log.debug("changing mode of %s to %o", path, mode) try: _chmod(path, mode) - except os.error: - e = sys.exc_info()[1] + except os.error as e: log.debug("chmod failed: %s", e) diff --git a/setuptools/command/sdist.py b/setuptools/command/sdist.py index 3d33df80..851a1775 100755 --- a/setuptools/command/sdist.py +++ b/setuptools/command/sdist.py @@ -70,7 +70,8 @@ class sdist(orig.sdist): try: orig.sdist.read_template(self) except: - sys.exc_info()[2].tb_next.tb_frame.f_locals['template'].close() + _, _, tb = sys.exc_info() + tb.tb_next.tb_frame.f_locals['template'].close() raise # Beginning with Python 2.7.2, 3.1.4, and 3.2.1, this leaky file handle diff --git a/setuptools/command/upload_docs.py b/setuptools/command/upload_docs.py index cd6c300c..001ee936 100644 --- a/setuptools/command/upload_docs.py +++ b/setuptools/command/upload_docs.py @@ -169,8 +169,7 @@ class upload_docs(upload): conn.putheader('Authorization', auth) conn.endheaders() conn.send(body) - except socket.error: - e = sys.exc_info()[1] + except socket.error as e: self.announce(str(e), log.ERROR) return diff --git a/setuptools/dist.py b/setuptools/dist.py index eb146444..1917a610 100644 --- a/setuptools/dist.py +++ b/setuptools/dist.py @@ -131,8 +131,7 @@ def check_entry_points(dist, attr, value): """Verify that entry_points map is parseable""" try: pkg_resources.EntryPoint.parse_map(value) - except ValueError: - e = sys.exc_info()[1] + except ValueError as e: raise DistutilsSetupError(e) def check_test_suite(dist, attr, value): diff --git a/setuptools/msvc9_support.py b/setuptools/msvc9_support.py index d0be70e2..e76d70f0 100644 --- a/setuptools/msvc9_support.py +++ b/setuptools/msvc9_support.py @@ -50,8 +50,7 @@ def find_vcvarsall(version): def query_vcvarsall(version, *args, **kwargs): try: return unpatched['query_vcvarsall'](version, *args, **kwargs) - except distutils.errors.DistutilsPlatformError: - exc = sys.exc_info()[1] + except distutils.errors.DistutilsPlatformError as exc: if exc and "vcvarsall.bat" in exc.args[0]: message = 'Microsoft Visual C++ %0.1f is required (%s).' % (version, exc.args[0]) if int(version) == 9: diff --git a/setuptools/package_index.py b/setuptools/package_index.py index 58572ce6..5ed19130 100755 --- a/setuptools/package_index.py +++ b/setuptools/package_index.py @@ -699,25 +699,21 @@ class PackageIndex(Environment): return local_open(url) try: return open_with_auth(url, self.opener) - except (ValueError, httplib.InvalidURL): - v = sys.exc_info()[1] + except (ValueError, httplib.InvalidURL) as v: msg = ' '.join([str(arg) for arg in v.args]) if warning: self.warn(warning, msg) else: raise DistutilsError('%s %s' % (url, msg)) - except urllib2.HTTPError: - v = sys.exc_info()[1] + except urllib2.HTTPError as v: return v - except urllib2.URLError: - v = sys.exc_info()[1] + except urllib2.URLError as v: if warning: self.warn(warning, v.reason) else: raise DistutilsError("Download error for %s: %s" % (url, v.reason)) - except httplib.BadStatusLine: - v = sys.exc_info()[1] + except httplib.BadStatusLine as v: if warning: self.warn(warning, v.line) else: @@ -726,8 +722,7 @@ class PackageIndex(Environment): 'down, %s' % (url, v.line) ) - except httplib.HTTPException: - v = sys.exc_info()[1] + except httplib.HTTPException as v: if warning: self.warn(warning, v) else: diff --git a/setuptools/sandbox.py b/setuptools/sandbox.py index b90d1e1b..7971f42c 100755 --- a/setuptools/sandbox.py +++ b/setuptools/sandbox.py @@ -199,8 +199,7 @@ def run_setup(setup_script, args): ns = dict(__file__=setup_script, __name__='__main__') _execfile(setup_script, ns) DirectorySandbox(setup_dir).run(runner) - except SystemExit: - v = sys.exc_info()[1] + except SystemExit as v: if v.args and v.args[0]: raise # Normal exit, just return diff --git a/setuptools/tests/test_packageindex.py b/setuptools/tests/test_packageindex.py index 3e9d1d84..dcd90d6f 100644 --- a/setuptools/tests/test_packageindex.py +++ b/setuptools/tests/test_packageindex.py @@ -15,8 +15,7 @@ class TestPackageIndex: url = 'http://127.0.0.1:0/nonesuch/test_package_index' try: v = index.open_url(url) - except Exception: - v = sys.exc_info()[1] + except Exception as v: assert url in str(v) else: assert isinstance(v, HTTPError) @@ -32,8 +31,7 @@ class TestPackageIndex: url = 'url:%20https://svn.plone.org/svn/collective/inquant.contentmirror.plone/trunk' try: v = index.open_url(url) - except Exception: - v = sys.exc_info()[1] + except Exception as v: assert url in str(v) else: assert isinstance(v, HTTPError) @@ -50,8 +48,7 @@ class TestPackageIndex: url = 'http://example.com' try: v = index.open_url(url) - except Exception: - v = sys.exc_info()[1] + except Exception as v: assert 'line' in str(v) else: raise AssertionError('Should have raise here!') @@ -68,8 +65,7 @@ class TestPackageIndex: url = 'http://http://svn.pythonpaste.org/Paste/wphp/trunk' try: index.open_url(url) - except distutils.errors.DistutilsError: - error = sys.exc_info()[1] + except distutils.errors.DistutilsError as error: msg = unicode(error) assert 'nonnumeric port' in msg or 'getaddrinfo failed' in msg or 'Name or service not known' in msg return diff --git a/setuptools/tests/test_sdist.py b/setuptools/tests/test_sdist.py index 943a5dee..68f83ca7 100644 --- a/setuptools/tests/test_sdist.py +++ b/setuptools/tests/test_sdist.py @@ -174,8 +174,7 @@ class TestSdistTest: # The manifest should be UTF-8 encoded try: u_contents = contents.decode('UTF-8') - except UnicodeDecodeError: - e = sys.exc_info()[1] + except UnicodeDecodeError as e: self.fail(e) # The manifest should contain the UTF-8 filename @@ -217,8 +216,7 @@ class TestSdistTest: # The manifest should be UTF-8 encoded try: contents.decode('UTF-8') - except UnicodeDecodeError: - e = sys.exc_info()[1] + except UnicodeDecodeError as e: self.fail(e) # The manifest should contain the UTF-8 filename @@ -258,8 +256,7 @@ class TestSdistTest: # The manifest should be UTF-8 encoded try: contents.decode('UTF-8') - except UnicodeDecodeError: - e = sys.exc_info()[1] + except UnicodeDecodeError as e: self.fail(e) # The Latin-1 filename should have been skipped @@ -328,8 +325,7 @@ class TestSdistTest: with quiet(): try: cmd.read_manifest() - except UnicodeDecodeError: - e = sys.exc_info()[1] + except UnicodeDecodeError as e: self.fail(e) # The Latin-1 filename should have been skipped -- cgit v1.2.1 From 3593a64ed6755876702ce362e1dfc87849c0952b Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 4 Jan 2015 12:09:27 -0500 Subject: Skip integration tests when one of the packages under test is already installed, as the installation will fail in that case. --- setuptools/tests/test_integration.py | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'setuptools') diff --git a/setuptools/tests/test_integration.py b/setuptools/tests/test_integration.py index 3a6abeaa..92a27080 100644 --- a/setuptools/tests/test_integration.py +++ b/setuptools/tests/test_integration.py @@ -14,6 +14,17 @@ from setuptools.command import easy_install as easy_install_pkg from setuptools.dist import Distribution +def setup_module(module): + packages = 'stevedore', 'virtualenvwrapper', 'pbr', 'novaclient' + for pkg in packages: + try: + __import__(pkg) + tmpl = "Integration tests cannot run when {pkg} is installed" + pytest.skip(tmpl.format(**locals())) + except ImportError: + pass + + @pytest.fixture def install_context(request, tmpdir, monkeypatch): """Fixture to set up temporary installation directory. -- cgit v1.2.1 From fba8ee7abecb12726293438e8af19d7c3fa54bb8 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 4 Jan 2015 12:22:53 -0500 Subject: Remove try/except/fail - Exceptions are failures by default. --- setuptools/tests/test_easy_install.py | 12 +++--------- setuptools/tests/test_sandbox.py | 6 ++---- setuptools/tests/test_sdist.py | 20 ++++---------------- 3 files changed, 9 insertions(+), 29 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py index 04271178..7baa989a 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -250,8 +250,6 @@ class TestUserInstallTest: with contexts.quiet(): with self.patched_setup_context(): run_setup(test_setup_py, ['install']) - except SandboxViolation: - self.fail('Installation caused SandboxViolation') except IndexError: # Test fails in some cases due to bugs in Python # See https://bitbucket.org/pypa/setuptools/issue/201 @@ -353,13 +351,9 @@ class TestSetupRequires: test_pkg = create_setup_requires_package(temp_dir) test_setup_py = os.path.join(test_pkg, 'setup.py') 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') + # Don't even need to install the package, just + # running the setup.py at all is sufficient + run_setup(test_setup_py, ['--name']) lines = stdout.readlines() assert len(lines) > 0 diff --git a/setuptools/tests/test_sandbox.py b/setuptools/tests/test_sandbox.py index 6e5ce04a..cadc4812 100644 --- a/setuptools/tests/test_sandbox.py +++ b/setuptools/tests/test_sandbox.py @@ -33,10 +33,8 @@ class TestSandbox: target = os.path.join(gen_py, 'test_write') sandbox = DirectorySandbox(str(tmpdir)) try: - try: - sandbox.run(self._file_writer(target)) - except SandboxViolation: - self.fail("Could not create gen_py file due to SandboxViolation") + # attempt to create gen_py file + sandbox.run(self._file_writer(target)) finally: if os.path.exists(target): os.remove(target) diff --git a/setuptools/tests/test_sdist.py b/setuptools/tests/test_sdist.py index 68f83ca7..d3494d7a 100644 --- a/setuptools/tests/test_sdist.py +++ b/setuptools/tests/test_sdist.py @@ -172,10 +172,7 @@ class TestSdistTest: manifest.close() # The manifest should be UTF-8 encoded - try: - u_contents = contents.decode('UTF-8') - except UnicodeDecodeError as e: - self.fail(e) + u_contents = contents.decode('UTF-8') # The manifest should contain the UTF-8 filename if PY2: @@ -214,10 +211,7 @@ class TestSdistTest: manifest.close() # The manifest should be UTF-8 encoded - try: - contents.decode('UTF-8') - except UnicodeDecodeError as e: - self.fail(e) + contents.decode('UTF-8') # The manifest should contain the UTF-8 filename assert posix(filename) in contents @@ -254,10 +248,7 @@ class TestSdistTest: manifest.close() # The manifest should be UTF-8 encoded - try: - contents.decode('UTF-8') - except UnicodeDecodeError as e: - self.fail(e) + contents.decode('UTF-8') # The Latin-1 filename should have been skipped assert posix(filename) not in contents @@ -323,10 +314,7 @@ class TestSdistTest: # Re-read manifest cmd.filelist.files = [] with quiet(): - try: - cmd.read_manifest() - except UnicodeDecodeError as e: - self.fail(e) + cmd.read_manifest() # The Latin-1 filename should have been skipped filename = filename.decode('latin-1') -- cgit v1.2.1 From 23d5e4a81a61c5e6617fa69fd0b2bc440fa20c45 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 4 Jan 2015 13:25:28 -0500 Subject: Test the report method --- setuptools/command/easy_install.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 02ce7636..d05f4c65 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -703,10 +703,7 @@ Please make the appropriate changes for your system and try again. "Could not find required distribution %s" % e.args ) except VersionConflict as e: - raise DistutilsError( - "Installed distribution %s conflicts with requirement %s" - % e.args - ) + raise DistutilsError(e.report()) if self.always_copy or self.always_copy_from: # Force all the relevant distros to be copied or activated for dist in distros: -- cgit v1.2.1 From 3e33c18af2c26a9b01383647157f4c1da275f67f Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 4 Jan 2015 14:36:52 -0500 Subject: Bumped to 11.2 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index 1b1703fd..a6fd3e36 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '11.1' +__version__ = '11.2' -- cgit v1.2.1 From 76dd319a776b3fb7bc7836eb18429ab407379ea9 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 4 Jan 2015 15:35:24 -0500 Subject: Reuse list2cmdline for argument quoting. --- setuptools/command/easy_install.py | 32 ++------------------------------ 1 file changed, 2 insertions(+), 30 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index d05f4c65..c68fe757 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -35,6 +35,7 @@ import warnings import site import struct import contextlib +import subprocess from setuptools import Command from setuptools.sandbox import run_setup @@ -1825,36 +1826,7 @@ def is_sh(executable): def nt_quote_arg(arg): """Quote a command line argument according to Windows parsing rules""" - - result = [] - needquote = False - nb = 0 - - needquote = (" " in arg) or ("\t" in arg) - if needquote: - result.append('"') - - for c in arg: - if c == '\\': - nb += 1 - elif c == '"': - # double preceding backslashes, then add a \" - result.append('\\' * (nb * 2) + '\\"') - nb = 0 - else: - if nb: - result.append('\\' * nb) - nb = 0 - result.append(c) - - if nb: - result.append('\\' * nb) - - if needquote: - result.append('\\' * nb) # double the trailing backslashes - result.append('"') - - return ''.join(result) + return subprocess.list2cmdline([arg]) def is_python_script(script_text, filename): -- cgit v1.2.1 From 4108a12a41f3c413f2ea5e8ede3075d67067cba5 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 4 Jan 2015 15:49:50 -0500 Subject: Extract method for getting script args --- setuptools/command/easy_install.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index c68fe757..4e05d670 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -1904,15 +1904,19 @@ class ScriptWriter(object): """ Yield write_script() argument tuples for a distribution's entrypoints """ - gen_class = cls.get_writer(wininst) - spec = str(dist.as_requirement()) + writer = cls.get_writer(wininst) header = get_script_header("", executable, wininst) + return cls._gen_args(dist, writer, header) + + @classmethod + def _gen_args(cls, dist, writer, header): + spec = str(dist.as_requirement()) for type_ in 'console', 'gui': group = type_ + '_scripts' for name, ep in dist.get_entry_map(group).items(): - script_text = gen_class.template % locals() - for res in gen_class._get_script_args(type_, name, header, - script_text): + script_text = writer.template % locals() + for res in writer._get_script_args(type_, name, header, + script_text): yield res @classmethod -- cgit v1.2.1 From d7cb597b9697e11d3f13e46d6af787ffc82571d5 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 4 Jan 2015 15:56:19 -0500 Subject: No need to pass the writer - just invoke it directly. --- setuptools/command/easy_install.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 4e05d670..d5d518de 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -1906,16 +1906,16 @@ class ScriptWriter(object): """ writer = cls.get_writer(wininst) header = get_script_header("", executable, wininst) - return cls._gen_args(dist, writer, header) + return writer._gen_args(dist, header) @classmethod - def _gen_args(cls, dist, writer, header): + def _gen_args(cls, dist, header): spec = str(dist.as_requirement()) for type_ in 'console', 'gui': group = type_ + '_scripts' for name, ep in dist.get_entry_map(group).items(): - script_text = writer.template % locals() - for res in writer._get_script_args(type_, name, header, + script_text = cls.template % locals() + for res in cls._get_script_args(type_, name, header, script_text): yield res -- cgit v1.2.1 From aabff23148950b34d1f956e7d5a63c6cd098662e Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 4 Jan 2015 15:59:22 -0500 Subject: Move trailing comment --- setuptools/command/easy_install.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index d5d518de..e52b4736 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -918,7 +918,8 @@ Please make the appropriate changes for your system and try again. f.write('%s: %s\n' % (k.replace('_', '-').title(), v)) f.close() script_dir = os.path.join(_egg_info, 'scripts') - self.delete_blockers( # delete entry-point scripts to avoid duping + # delete entry-point scripts to avoid duping + self.delete_blockers( [os.path.join(script_dir, args[0]) for args in get_script_args(dist)] ) -- cgit v1.2.1 From 2170df350911390a4a9a205763475dc7a7a2fb54 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 4 Jan 2015 16:21:11 -0500 Subject: Move decision logic about windows/header generation closer to install_scripts, as it doesn't appear to be used elsewhere. --- setuptools/command/easy_install.py | 15 +++++++++------ setuptools/command/install_scripts.py | 10 ++++++---- setuptools/tests/test_easy_install.py | 6 +++--- 3 files changed, 18 insertions(+), 13 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index e52b4736..d8d11d50 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -745,7 +745,7 @@ Please make the appropriate changes for your system and try again. def install_wrapper_scripts(self, dist): if not self.exclude_scripts: - for args in get_script_args(dist): + for args in ScriptWriter._gen_args(dist): self.write_script(*args) def install_script(self, dist, script_name, script_text, dev_path=None): @@ -921,7 +921,7 @@ Please make the appropriate changes for your system and try again. # delete entry-point scripts to avoid duping self.delete_blockers( [os.path.join(script_dir, args[0]) for args in - get_script_args(dist)] + ScriptWriter._gen_args(dist)] ) # Build .egg file from tmpdir bdist_egg.make_zipfile( @@ -1902,15 +1902,18 @@ class ScriptWriter(object): @classmethod def get_script_args(cls, dist, executable=sys_executable, wininst=False): - """ - Yield write_script() argument tuples for a distribution's entrypoints - """ + # for backward compatibility writer = cls.get_writer(wininst) header = get_script_header("", executable, wininst) return writer._gen_args(dist, header) @classmethod - def _gen_args(cls, dist, header): + def _gen_args(cls, dist, header=None): + """ + Yield write_script() argument tuples for a distribution's entrypoints + """ + if header is None: + header = get_script_header("", sys_executable) spec = str(dist.as_requirement()) for type_ in 'console', 'gui': group = type_ + '_scripts' diff --git a/setuptools/command/install_scripts.py b/setuptools/command/install_scripts.py index eb79fa3c..eb5ed0f2 100755 --- a/setuptools/command/install_scripts.py +++ b/setuptools/command/install_scripts.py @@ -13,9 +13,9 @@ class install_scripts(orig.install_scripts): self.no_ep = False def run(self): - from setuptools.command.easy_install import get_script_args - from setuptools.command.easy_install import sys_executable - + from setuptools.command.easy_install import ( + ScriptWriter, sys_executable, get_script_header, + ) self.run_command("egg_info") if self.distribution.scripts: orig.install_scripts.run(self) # run first to set up self.outfiles @@ -35,7 +35,9 @@ class install_scripts(orig.install_scripts): is_wininst = getattr( self.get_finalized_command("bdist_wininst"), '_is_running', False ) - for args in get_script_args(dist, executable, is_wininst): + writer = ScriptWriter.get_writer(force_windows=is_wininst) + header = get_script_header("", executable, wininst=is_wininst) + for args in writer._gen_args(dist, header): self.write_script(*args) def write_script(self, script_name, contents, mode="t", *ignored): diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py index 7baa989a..bc94b0c4 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -22,8 +22,8 @@ from setuptools import compat from setuptools.compat import StringIO, BytesIO, urlparse from setuptools.sandbox import run_setup, SandboxViolation from setuptools.command.easy_install import ( - easy_install, fix_jython_executable, get_script_args, nt_quote_arg, - get_script_header, is_sh, + easy_install, fix_jython_executable, nt_quote_arg, + get_script_header, is_sh, ScriptWriter, ) from setuptools.command.easy_install import PthDistributions from setuptools.command import easy_install as easy_install_pkg @@ -83,7 +83,7 @@ class TestEasyInstallTest: def test_get_script_args(self): dist = FakeDist() - args = next(get_script_args(dist)) + args = next(ScriptWriter._gen_args(dist)) name, script = itertools.islice(args, 2) assert script == WANTED -- cgit v1.2.1 From ef9c3db451e2f24fc8821287e79a1ef48e0c5cf5 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 4 Jan 2015 16:43:55 -0500 Subject: Move get_script_header into ScriptWriter --- setuptools/command/easy_install.py | 50 ++++++++++++++++++----------------- setuptools/command/install_scripts.py | 4 ++- 2 files changed, 29 insertions(+), 25 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index d8d11d50..c2928c77 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -1593,30 +1593,8 @@ def _first_line_re(): def get_script_header(script_text, executable=sys_executable, wininst=False): - """Create a #! line, getting options (if any) from script_text""" - first = (script_text + '\n').splitlines()[0] - match = _first_line_re().match(first) - options = '' - if match: - options = match.group(1) or '' - if options: - options = ' ' + options - if wininst: - executable = "python.exe" - else: - executable = nt_quote_arg(executable) - hdr = "#!%(executable)s%(options)s\n" % locals() - if not isascii(hdr): - # Non-ascii path to sys.executable, use -x to prevent warnings - if options: - if options.strip().startswith('-'): - options = ' -x' + options.strip()[1:] - # else: punt, we can't do it, let the warning happen anyway - else: - options = ' -x' - executable = fix_jython_executable(executable, options) - hdr = "#!%(executable)s%(options)s\n" % locals() - return hdr + executable = "python.exe" if wininst else nt_quote_arg(executable) + return ScriptWriter.get_header(script_text, executable) def auto_chmod(func, arg, exc): @@ -1903,6 +1881,7 @@ class ScriptWriter(object): @classmethod def get_script_args(cls, dist, executable=sys_executable, wininst=False): # for backward compatibility + warnings.warn("Use _gen_args", DeprecationWarning) writer = cls.get_writer(wininst) header = get_script_header("", executable, wininst) return writer._gen_args(dist, header) @@ -1934,6 +1913,29 @@ class ScriptWriter(object): # Simply write the stub with no extension. yield (name, header + script_text) + @classmethod + def get_header(cls, script_text, executable): + """Create a #! line, getting options (if any) from script_text""" + first = (script_text + '\n').splitlines()[0] + match = _first_line_re().match(first) + options = '' + if match: + options = match.group(1) or '' + if options: + options = ' ' + options + hdr = "#!%(executable)s%(options)s\n" % locals() + if not isascii(hdr): + # Non-ascii path to sys.executable, use -x to prevent warnings + if options: + if options.strip().startswith('-'): + options = ' -x' + options.strip()[1:] + # else: punt, we can't do it, let the warning happen anyway + else: + options = ' -x' + executable = fix_jython_executable(executable, options) + hdr = "#!%(executable)s%(options)s\n" % locals() + return hdr + class WindowsScriptWriter(ScriptWriter): @classmethod diff --git a/setuptools/command/install_scripts.py b/setuptools/command/install_scripts.py index eb5ed0f2..de74145f 100755 --- a/setuptools/command/install_scripts.py +++ b/setuptools/command/install_scripts.py @@ -35,8 +35,10 @@ class install_scripts(orig.install_scripts): is_wininst = getattr( self.get_finalized_command("bdist_wininst"), '_is_running', False ) + if is_wininst: + executable = "python.exe" writer = ScriptWriter.get_writer(force_windows=is_wininst) - header = get_script_header("", executable, wininst=is_wininst) + header = get_script_header("", executable) for args in writer._gen_args(dist, header): self.write_script(*args) -- cgit v1.2.1 From db3ee08fdba76c74e3f25ae7d7f56117e68223b0 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 4 Jan 2015 16:44:19 -0500 Subject: Remove unused imports --- setuptools/tests/test_easy_install.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py index bc94b0c4..b42d2c07 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -20,7 +20,7 @@ import mock from setuptools import sandbox from setuptools import compat from setuptools.compat import StringIO, BytesIO, urlparse -from setuptools.sandbox import run_setup, SandboxViolation +from setuptools.sandbox import run_setup from setuptools.command.easy_install import ( easy_install, fix_jython_executable, nt_quote_arg, get_script_header, is_sh, ScriptWriter, @@ -28,7 +28,7 @@ from setuptools.command.easy_install import ( from setuptools.command.easy_install import PthDistributions from setuptools.command import easy_install as easy_install_pkg from setuptools.dist import Distribution -from pkg_resources import working_set, VersionConflict +from pkg_resources import working_set from pkg_resources import Distribution as PRDistribution import setuptools.tests.server import pkg_resources -- cgit v1.2.1 From 390e64c37fb7dcb57b8e6062192e4c4375be8b78 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 4 Jan 2015 16:56:23 -0500 Subject: Moved get_script_header into ScriptWriter class --- setuptools/command/easy_install.py | 11 ++++++----- setuptools/tests/test_easy_install.py | 28 ++++++++++++++++++---------- 2 files changed, 24 insertions(+), 15 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index c2928c77..bf648384 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -1592,11 +1592,6 @@ def _first_line_re(): return re.compile(first_line_re.pattern.decode()) -def get_script_header(script_text, executable=sys_executable, wininst=False): - executable = "python.exe" if wininst else nt_quote_arg(executable) - return ScriptWriter.get_header(script_text, executable) - - def auto_chmod(func, arg, exc): if func is os.remove and os.name == 'nt': chmod(arg, stat.S_IWRITE) @@ -1886,6 +1881,11 @@ class ScriptWriter(object): header = get_script_header("", executable, wininst) return writer._gen_args(dist, header) + @classmethod + def get_script_header(cls, script_text, executable=sys_executable, wininst=False): + executable = "python.exe" if wininst else nt_quote_arg(executable) + return cls.get_header(script_text, executable) + @classmethod def _gen_args(cls, dist, header=None): """ @@ -2016,6 +2016,7 @@ class WindowsExecutableLauncherWriter(WindowsScriptWriter): # for backward-compatibility get_script_args = ScriptWriter.get_script_args +get_script_header = ScriptWriter.get_script_header def get_win_launcher(type): diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py index b42d2c07..5d1068ea 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -23,7 +23,7 @@ from setuptools.compat import StringIO, BytesIO, urlparse from setuptools.sandbox import run_setup from setuptools.command.easy_install import ( easy_install, fix_jython_executable, nt_quote_arg, - get_script_header, is_sh, ScriptWriter, + is_sh, ScriptWriter, ) from setuptools.command.easy_install import PthDistributions from setuptools.command import easy_install as easy_install_pkg @@ -425,15 +425,22 @@ class TestScriptHeader: ) def test_get_script_header(self): expected = '#!%s\n' % nt_quote_arg(os.path.normpath(sys.executable)) - assert get_script_header('#!/usr/local/bin/python') == expected + actual = ScriptWriter.get_script_header('#!/usr/local/bin/python') + assert actual == expected + expected = '#!%s -x\n' % nt_quote_arg(os.path.normpath(sys.executable)) - assert get_script_header('#!/usr/bin/python -x') == expected - candidate = get_script_header('#!/usr/bin/python', + actual = ScriptWriter.get_script_header('#!/usr/bin/python -x') + assert actual == expected + + actual = ScriptWriter.get_script_header('#!/usr/bin/python', executable=self.non_ascii_exe) - assert candidate == '#!%s -x\n' % self.non_ascii_exe - candidate = get_script_header('#!/usr/bin/python', + expected = '#!%s -x\n' % self.non_ascii_exe + assert actual == expected + + actual = ScriptWriter.get_script_header('#!/usr/bin/python', executable=self.exe_with_spaces) - assert candidate == '#!"%s"\n' % self.exe_with_spaces + expected = '#!"%s"\n' % self.exe_with_spaces + assert actual == expected @pytest.mark.xfail( compat.PY3 and os.environ.get("LC_CTYPE") in ("C", "POSIX"), @@ -453,7 +460,8 @@ class TestScriptHeader: f.write(header) exe = str(exe) - header = get_script_header('#!/usr/local/bin/python', executable=exe) + header = ScriptWriter.get_script_header('#!/usr/local/bin/python', + executable=exe) assert header == '#!/usr/bin/env %s\n' % exe expect_out = 'stdout' if sys.version_info < (2,7) else 'stderr' @@ -461,14 +469,14 @@ class TestScriptHeader: with contexts.quiet() as (stdout, stderr): # When options are included, generate a broken shebang line # with a warning emitted - candidate = get_script_header('#!/usr/bin/python -x', + candidate = ScriptWriter.get_script_header('#!/usr/bin/python -x', executable=exe) 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 = get_script_header('#!/usr/bin/python', + candidate = 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] -- cgit v1.2.1 From c3beddd034239005c98f7285a2936c513c5a81be Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 4 Jan 2015 17:12:37 -0500 Subject: Deprecate and remove usage of easy_install.get_script_header. --- setuptools/command/easy_install.py | 12 ++++++++---- setuptools/command/install_scripts.py | 4 ++-- 2 files changed, 10 insertions(+), 6 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index bf648384..9eb74159 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -754,7 +754,7 @@ Please make the appropriate changes for your system and try again. is_script = is_python_script(script_text, script_name) if is_script: - script_text = (get_script_header(script_text) + + script_text = (ScriptWriter.get_header(script_text) + self._load_template(dev_path) % locals()) self.write_script(script_name, _to_ascii(script_text), 'b') @@ -1878,11 +1878,13 @@ class ScriptWriter(object): # for backward compatibility warnings.warn("Use _gen_args", DeprecationWarning) writer = cls.get_writer(wininst) - header = get_script_header("", executable, wininst) + header = cls.get_script_header("", executable, wininst) return writer._gen_args(dist, header) @classmethod def get_script_header(cls, script_text, executable=sys_executable, wininst=False): + # for backward compatibility + warnings.warn("Use get_header", DeprecationWarning) executable = "python.exe" if wininst else nt_quote_arg(executable) return cls.get_header(script_text, executable) @@ -1892,7 +1894,7 @@ class ScriptWriter(object): Yield write_script() argument tuples for a distribution's entrypoints """ if header is None: - header = get_script_header("", sys_executable) + header = cls.get_header() spec = str(dist.as_requirement()) for type_ in 'console', 'gui': group = type_ + '_scripts' @@ -1914,8 +1916,10 @@ class ScriptWriter(object): yield (name, header + script_text) @classmethod - def get_header(cls, script_text, executable): + def get_header(cls, script_text="", executable=None): """Create a #! line, getting options (if any) from script_text""" + if executable is None: + executable = nt_quote_arg(sys_executable) first = (script_text + '\n').splitlines()[0] match = _first_line_re().match(first) options = '' diff --git a/setuptools/command/install_scripts.py b/setuptools/command/install_scripts.py index de74145f..138e4ea2 100755 --- a/setuptools/command/install_scripts.py +++ b/setuptools/command/install_scripts.py @@ -14,7 +14,7 @@ class install_scripts(orig.install_scripts): def run(self): from setuptools.command.easy_install import ( - ScriptWriter, sys_executable, get_script_header, + ScriptWriter, sys_executable, nt_quote_arg, ) self.run_command("egg_info") if self.distribution.scripts: @@ -38,7 +38,7 @@ class install_scripts(orig.install_scripts): if is_wininst: executable = "python.exe" writer = ScriptWriter.get_writer(force_windows=is_wininst) - header = get_script_header("", executable) + header = ScriptWriter.get_header("", nt_quote_arg(executable)) for args in writer._gen_args(dist, header): self.write_script(*args) -- cgit v1.2.1 From 261d57232c74954468688a76aab2caea80ed42fc Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 4 Jan 2015 17:14:11 -0500 Subject: Rename _gen_args to get_args (for consistency). --- setuptools/command/easy_install.py | 10 +++++----- setuptools/command/install_scripts.py | 2 +- setuptools/tests/test_easy_install.py | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 9eb74159..5c50dbe2 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -745,7 +745,7 @@ Please make the appropriate changes for your system and try again. def install_wrapper_scripts(self, dist): if not self.exclude_scripts: - for args in ScriptWriter._gen_args(dist): + for args in ScriptWriter.get_args(dist): self.write_script(*args) def install_script(self, dist, script_name, script_text, dev_path=None): @@ -921,7 +921,7 @@ Please make the appropriate changes for your system and try again. # delete entry-point scripts to avoid duping self.delete_blockers( [os.path.join(script_dir, args[0]) for args in - ScriptWriter._gen_args(dist)] + ScriptWriter.get_args(dist)] ) # Build .egg file from tmpdir bdist_egg.make_zipfile( @@ -1876,10 +1876,10 @@ class ScriptWriter(object): @classmethod def get_script_args(cls, dist, executable=sys_executable, wininst=False): # for backward compatibility - warnings.warn("Use _gen_args", DeprecationWarning) + warnings.warn("Use get_args", DeprecationWarning) writer = cls.get_writer(wininst) header = cls.get_script_header("", executable, wininst) - return writer._gen_args(dist, header) + return writer.get_args(dist, header) @classmethod def get_script_header(cls, script_text, executable=sys_executable, wininst=False): @@ -1889,7 +1889,7 @@ class ScriptWriter(object): return cls.get_header(script_text, executable) @classmethod - def _gen_args(cls, dist, header=None): + def get_args(cls, dist, header=None): """ Yield write_script() argument tuples for a distribution's entrypoints """ diff --git a/setuptools/command/install_scripts.py b/setuptools/command/install_scripts.py index 138e4ea2..1717e1cf 100755 --- a/setuptools/command/install_scripts.py +++ b/setuptools/command/install_scripts.py @@ -39,7 +39,7 @@ class install_scripts(orig.install_scripts): executable = "python.exe" writer = ScriptWriter.get_writer(force_windows=is_wininst) header = ScriptWriter.get_header("", nt_quote_arg(executable)) - for args in writer._gen_args(dist, header): + for args in writer.get_args(dist, header): self.write_script(*args) def write_script(self, script_name, contents, mode="t", *ignored): diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py index 5d1068ea..f919ae20 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -83,7 +83,7 @@ class TestEasyInstallTest: def test_get_script_args(self): dist = FakeDist() - args = next(ScriptWriter._gen_args(dist)) + args = next(ScriptWriter.get_args(dist)) name, script = itertools.islice(args, 2) assert script == WANTED -- cgit v1.2.1 From 3c78eb2348dff5d493d0cd5a34aef812db8385ef Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 4 Jan 2015 17:20:15 -0500 Subject: Extract method for parsing options. --- setuptools/command/easy_install.py | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 5c50dbe2..6ec96564 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -1920,13 +1920,9 @@ class ScriptWriter(object): """Create a #! line, getting options (if any) from script_text""" if executable is None: executable = nt_quote_arg(sys_executable) - first = (script_text + '\n').splitlines()[0] - match = _first_line_re().match(first) - options = '' - if match: - options = match.group(1) or '' - if options: - options = ' ' + options + + options = cls._extract_options(script_text) + hdr = "#!%(executable)s%(options)s\n" % locals() if not isascii(hdr): # Non-ascii path to sys.executable, use -x to prevent warnings @@ -1940,6 +1936,20 @@ class ScriptWriter(object): hdr = "#!%(executable)s%(options)s\n" % locals() return hdr + @classmethod + def _extract_options(cls, orig_script): + """ + Extract any options from the first line of the script. + """ + first = (orig_script + '\n').splitlines()[0] + match = _first_line_re().match(first) + options = '' + if match: + options = match.group(1) or '' + if options: + options = ' ' + options + return options + class WindowsScriptWriter(ScriptWriter): @classmethod -- cgit v1.2.1 From efba85513b5c11ddbddf785906b5b4e9b596771a Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 4 Jan 2015 17:49:21 -0500 Subject: Extract method for handling non-ascii exe. Strip out excess whitespace from option handling. --- setuptools/command/easy_install.py | 37 +++++++++++++++++++---------------- setuptools/tests/test_easy_install.py | 4 ++-- 2 files changed, 22 insertions(+), 19 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 6ec96564..61e242d6 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -1922,19 +1922,11 @@ class ScriptWriter(object): executable = nt_quote_arg(sys_executable) options = cls._extract_options(script_text) + options = cls._handle_non_ascii_exe(executable, options) + tmpl = '#!{executable} {options}\n' if options else '#!{executable}\n' - hdr = "#!%(executable)s%(options)s\n" % locals() - if not isascii(hdr): - # Non-ascii path to sys.executable, use -x to prevent warnings - if options: - if options.strip().startswith('-'): - options = ' -x' + options.strip()[1:] - # else: punt, we can't do it, let the warning happen anyway - else: - options = ' -x' executable = fix_jython_executable(executable, options) - hdr = "#!%(executable)s%(options)s\n" % locals() - return hdr + return tmpl.format(**locals()) @classmethod def _extract_options(cls, orig_script): @@ -1943,12 +1935,23 @@ class ScriptWriter(object): """ first = (orig_script + '\n').splitlines()[0] match = _first_line_re().match(first) - options = '' - if match: - options = match.group(1) or '' - if options: - options = ' ' + options - return options + options = match.group(1) or '' if match else '' + return options.strip() + + @classmethod + def _handle_non_ascii_exe(cls, executable, options): + if isascii(executable): + return options + + # Non-ascii path to sys.executable, use -x to prevent warnings + if not options: + return '-x' + + if not options.strip().startswith('-'): + # punt, we can't do it, let the warning happen anyway + return options + + return '-x' + options.strip()[1:] class WindowsScriptWriter(ScriptWriter): diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py index f919ae20..86870866 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -428,7 +428,7 @@ class TestScriptHeader: actual = ScriptWriter.get_script_header('#!/usr/local/bin/python') assert actual == expected - expected = '#!%s -x\n' % nt_quote_arg(os.path.normpath(sys.executable)) + expected = '#!%s -x\n' % nt_quote_arg(os.path.normpath(sys.executable)) actual = ScriptWriter.get_script_header('#!/usr/bin/python -x') assert actual == expected @@ -471,7 +471,7 @@ class TestScriptHeader: # with a warning emitted candidate = ScriptWriter.get_script_header('#!/usr/bin/python -x', executable=exe) - assert candidate == '#!%s -x\n' % exe + assert candidate == '#!%s -x\n' % exe output = locals()[expect_out] assert 'Unable to adapt shebang line' in output.getvalue() -- cgit v1.2.1 From bd9d38030cee59eb0e2ef9c8fb98fda5b1ff470f Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 4 Jan 2015 21:18:09 -0500 Subject: Added new class CommandSpec, which will be used for abstracting the command handling for script headers. --- setuptools/command/easy_install.py | 95 ++++++++++++++++++++++++++++++++++---- 1 file changed, 87 insertions(+), 8 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 61e242d6..bb0d8694 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -60,10 +60,6 @@ import pkg_resources warnings.filterwarnings("default", category=pkg_resources.PEP440Warning) -sys_executable = os.environ.get('__PYVENV_LAUNCHER__', - os.path.normpath(sys.executable)) - - __all__ = [ 'samefile', 'easy_install', 'PthDistributions', 'extract_wininst_cfg', 'main', 'get_exe_prefixes', @@ -1855,6 +1851,88 @@ def fix_jython_executable(executable, options): return executable +class CommandSpec(list): + """ + A command spec for a #! header, specified as a list of arguments akin to + those passed to Popen. + """ + + options = [] + _default = os.path.normpath(sys.executable) + launcher = os.environ.get('__PYVENV_LAUNCHER__', _default) + + @classmethod + def from_environment(cls): + return cls.from_string(cls.launcher) + + @classmethod + def from_string(cls, string): + """ + Construct a command spec from a simple string, assumed to represent + the full name to an executable. + """ + return cls._for_jython(string) or cls([string]) + + def install_options(self, script_text): + self.options.extend(self._extract_options(script_text)) + cmdline = subprocess.list2cmdline(self) + if not isascii(cmdline): + self.options[:0] = ['-x'] + + @staticmethod + def _extract_options(orig_script): + """ + Extract any options from the first line of the script. + """ + first = (orig_script + '\n').splitlines()[0] + match = _first_line_re().match(first) + options = match.group(1) or '' if match else '' + return options.strip() + + def as_header(self): + return self._render(self + list(self.options)) + + @staticmethod + def _render(items): + cmdline = subprocess.list2cmdline(items) + return '#!' + cmdline + '\n' + + +class JythonCommandSpec(CommandSpec): + @classmethod + def from_string(cls, string): + """ + On Jython, construct an instance of this class. + On platforms other than Jython, return None. + """ + needs_jython_spec = ( + sys.platform.startswith('java') + and + __import__('java').lang.System.getProperty('os.name') != 'Linux' + ) + return cls([string]) if needs_jython_spec else None + + 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 @@ -1874,17 +1952,19 @@ class ScriptWriter(object): """).lstrip() @classmethod - def get_script_args(cls, dist, executable=sys_executable, wininst=False): + def get_script_args(cls, dist, executable=None, wininst=False): # for backward compatibility warnings.warn("Use get_args", DeprecationWarning) + executable = executable or CommandSpec.launcher writer = cls.get_writer(wininst) header = cls.get_script_header("", executable, wininst) return writer.get_args(dist, header) @classmethod - def get_script_header(cls, script_text, executable=sys_executable, wininst=False): + def get_script_header(cls, script_text, executable=None, wininst=False): # for backward compatibility warnings.warn("Use get_header", DeprecationWarning) + executable = executable or CommandSpec.launcher executable = "python.exe" if wininst else nt_quote_arg(executable) return cls.get_header(script_text, executable) @@ -1918,8 +1998,7 @@ class ScriptWriter(object): @classmethod def get_header(cls, script_text="", executable=None): """Create a #! line, getting options (if any) from script_text""" - if executable is None: - executable = nt_quote_arg(sys_executable) + executable = executable or nt_quote_arg(CommandSpec.launcher) options = cls._extract_options(script_text) options = cls._handle_non_ascii_exe(executable, options) -- cgit v1.2.1 From 3ababa264dc404e9f8eae01045a4531b0b5bd692 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 4 Jan 2015 21:31:05 -0500 Subject: Update install_scripts to use CommandSpec for generating script headers. --- setuptools/command/easy_install.py | 13 +++++++++++++ setuptools/command/install_scripts.py | 12 +++++------- 2 files changed, 18 insertions(+), 7 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index bb0d8694..5667864b 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -1861,6 +1861,19 @@ class CommandSpec(list): _default = os.path.normpath(sys.executable) launcher = os.environ.get('__PYVENV_LAUNCHER__', _default) + @classmethod + def from_param(cls, param): + """ + Construct a CommandSpec from a parameter to build_scripts, which may + be None. + """ + if isinstance(param, cls): + return param + if param is None: + return cls.from_environment() + # otherwise, assume it's a string. + return cls.from_string(param) + @classmethod def from_environment(cls): return cls.from_string(cls.launcher) diff --git a/setuptools/command/install_scripts.py b/setuptools/command/install_scripts.py index 1717e1cf..722b0566 100755 --- a/setuptools/command/install_scripts.py +++ b/setuptools/command/install_scripts.py @@ -13,9 +13,8 @@ class install_scripts(orig.install_scripts): self.no_ep = False def run(self): - from setuptools.command.easy_install import ( - ScriptWriter, sys_executable, nt_quote_arg, - ) + from setuptools.command.easy_install import ScriptWriter, CommandSpec + self.run_command("egg_info") if self.distribution.scripts: orig.install_scripts.run(self) # run first to set up self.outfiles @@ -31,15 +30,14 @@ class install_scripts(orig.install_scripts): ei_cmd.egg_name, ei_cmd.egg_version, ) bs_cmd = self.get_finalized_command('build_scripts') - executable = getattr(bs_cmd, 'executable', sys_executable) + cmd = CommandSpec.from_param(getattr(bs_cmd, 'executable', None)) is_wininst = getattr( self.get_finalized_command("bdist_wininst"), '_is_running', False ) if is_wininst: - executable = "python.exe" + cmd = CommandSpec.from_string("python.exe") writer = ScriptWriter.get_writer(force_windows=is_wininst) - header = ScriptWriter.get_header("", nt_quote_arg(executable)) - for args in writer.get_args(dist, header): + for args in writer.get_args(dist, cmd.as_header()): self.write_script(*args) def write_script(self, script_name, contents, mode="t", *ignored): -- cgit v1.2.1 From 254c2f03c69fd6ae34e70c1f89cb7ccbc4b5fed3 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 4 Jan 2015 21:44:38 -0500 Subject: Use CommandSpec in get_script_header --- setuptools/command/easy_install.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 5667864b..f075200c 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -36,6 +36,7 @@ import site import struct import contextlib import subprocess +import shlex from setuptools import Command from setuptools.sandbox import run_setup @@ -1884,10 +1885,10 @@ class CommandSpec(list): Construct a command spec from a simple string, assumed to represent the full name to an executable. """ - return cls._for_jython(string) or cls([string]) + return JythonCommandSpec.from_string(string) or cls([string]) def install_options(self, script_text): - self.options.extend(self._extract_options(script_text)) + self.options = shlex.split(self._extract_options(script_text)) cmdline = subprocess.list2cmdline(self) if not isascii(cmdline): self.options[:0] = ['-x'] @@ -1977,9 +1978,11 @@ class ScriptWriter(object): def get_script_header(cls, script_text, executable=None, wininst=False): # for backward compatibility warnings.warn("Use get_header", DeprecationWarning) - executable = executable or CommandSpec.launcher - executable = "python.exe" if wininst else nt_quote_arg(executable) - return cls.get_header(script_text, executable) + if wininst: + executable = "python.exe" + cmd = CommandSpec.from_param(executable) + cmd.install_options(script_text) + return cmd.as_header() @classmethod def get_args(cls, dist, header=None): -- cgit v1.2.1 From 126d971737a7b0fc89b0b84c2b48f6fd139df729 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 4 Jan 2015 21:53:03 -0500 Subject: Use CommandSpec in ScriptWriter, removing now unused methods. --- setuptools/command/easy_install.py | 36 +++--------------------------------- 1 file changed, 3 insertions(+), 33 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index f075200c..7f8a9800 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -2014,39 +2014,9 @@ class ScriptWriter(object): @classmethod def get_header(cls, script_text="", executable=None): """Create a #! line, getting options (if any) from script_text""" - executable = executable or nt_quote_arg(CommandSpec.launcher) - - options = cls._extract_options(script_text) - options = cls._handle_non_ascii_exe(executable, options) - tmpl = '#!{executable} {options}\n' if options else '#!{executable}\n' - - executable = fix_jython_executable(executable, options) - return tmpl.format(**locals()) - - @classmethod - def _extract_options(cls, orig_script): - """ - Extract any options from the first line of the script. - """ - first = (orig_script + '\n').splitlines()[0] - match = _first_line_re().match(first) - options = match.group(1) or '' if match else '' - return options.strip() - - @classmethod - def _handle_non_ascii_exe(cls, executable, options): - if isascii(executable): - return options - - # Non-ascii path to sys.executable, use -x to prevent warnings - if not options: - return '-x' - - if not options.strip().startswith('-'): - # punt, we can't do it, let the warning happen anyway - return options - - return '-x' + options.strip()[1:] + cmd = CommandSpec.from_param(executable) + cmd.install_options(script_text) + return cmd.as_header() class WindowsScriptWriter(ScriptWriter): -- cgit v1.2.1 From ab6887a55394c77982212c058c59addeb77736f7 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 4 Jan 2015 22:02:56 -0500 Subject: Remove redundant line --- setuptools/command/easy_install.py | 1 - 1 file changed, 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 7f8a9800..0b24c8e3 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -1969,7 +1969,6 @@ class ScriptWriter(object): def get_script_args(cls, dist, executable=None, wininst=False): # for backward compatibility warnings.warn("Use get_args", DeprecationWarning) - executable = executable or CommandSpec.launcher writer = cls.get_writer(wininst) header = cls.get_script_header("", executable, wininst) return writer.get_args(dist, header) -- cgit v1.2.1 From 6ab7d6dbb13e0ef1f44bf0461f3ffdb06f07b3b2 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 4 Jan 2015 22:11:08 -0500 Subject: Add test demonstrating how a custom launch command spec that could be passed as the script executable. --- setuptools/tests/test_easy_install.py | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py index 86870866..3a8ddbfb 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -23,7 +23,7 @@ from setuptools.compat import StringIO, BytesIO, urlparse from setuptools.sandbox import run_setup from setuptools.command.easy_install import ( easy_install, fix_jython_executable, nt_quote_arg, - is_sh, ScriptWriter, + is_sh, ScriptWriter, CommandSpec, ) from setuptools.command.easy_install import PthDistributions from setuptools.command import easy_install as easy_install_pkg @@ -481,3 +481,21 @@ class TestScriptHeader: 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): + """ + Show how a custom CommandSpec could be used to specify a #! executable + which takes parameters. + """ + cmd = CommandSpec(['/usr/bin/env', 'python3']) + assert cmd.as_header() == '#!/usr/bin/env python3\n' + + def test_from_param_for_CommandSpec_is_passthrough(self): + """ + from_param should return an instance of a CommandSpec + """ + cmd = CommandSpec(['python']) + cmd_new = CommandSpec.from_param(cmd) + assert cmd is cmd_new -- cgit v1.2.1 From 4356a2dc99a74be0d970f63e045eba40f463695d Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 4 Jan 2015 22:22:44 -0500 Subject: Allow CommandSpec to be constructed simply from a list. --- setuptools/command/easy_install.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 0b24c8e3..fb953dbb 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -1870,6 +1870,8 @@ class CommandSpec(list): """ if isinstance(param, cls): return param + if isinstance(param, list): + return cls(param) if param is None: return cls.from_environment() # otherwise, assume it's a string. -- cgit v1.2.1 From 0ad48553589fc68faeb7a5fc2f76da128249ac86 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 4 Jan 2015 22:29:37 -0500 Subject: Add test capturing expectation around sys.executable having spaces in the name. --- setuptools/command/easy_install.py | 9 ++++++--- setuptools/tests/test_easy_install.py | 6 ++++++ 2 files changed, 12 insertions(+), 3 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index fb953dbb..54a3bc3a 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -1859,8 +1859,11 @@ class CommandSpec(list): """ options = [] - _default = os.path.normpath(sys.executable) - launcher = os.environ.get('__PYVENV_LAUNCHER__', _default) + + @classmethod + def _sys_executable(cls): + _default = os.path.normpath(sys.executable) + return os.environ.get('__PYVENV_LAUNCHER__', _default) @classmethod def from_param(cls, param): @@ -1879,7 +1882,7 @@ class CommandSpec(list): @classmethod def from_environment(cls): - return cls.from_string(cls.launcher) + return cls.from_string(cls._sys_executable()) @classmethod def from_string(cls, string): diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py index 3a8ddbfb..e1f06788 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -499,3 +499,9 @@ class TestCommandSpec: cmd = CommandSpec(['python']) cmd_new = CommandSpec.from_param(cmd) assert cmd is cmd_new + + def test_from_environment_with_spaces_in_executable(self): + with mock.patch('sys.executable', TestScriptHeader.exe_with_spaces): + cmd = CommandSpec.from_environment() + assert len(cmd) == 1 + assert cmd.as_header().startswith('#!"') -- cgit v1.2.1 From 3b68368e30aa51d4a7f96053501c604a8cb6fe42 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 4 Jan 2015 22:44:28 -0500 Subject: Change the way string values are interpreted from build.executable - now they must be quoted or otherwise escaped suitable for parsing by shlex.split. --- setuptools/command/easy_install.py | 9 +++++---- setuptools/tests/test_easy_install.py | 9 +++++++++ 2 files changed, 14 insertions(+), 4 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 54a3bc3a..340b1fac 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -1882,15 +1882,16 @@ class CommandSpec(list): @classmethod def from_environment(cls): - return cls.from_string(cls._sys_executable()) + return cls.from_string('"' + cls._sys_executable() + '"') @classmethod def from_string(cls, string): """ - Construct a command spec from a simple string, assumed to represent - the full name to an executable. + Construct a command spec from a simple string representing a command + line parseable by shlex.split. """ - return JythonCommandSpec.from_string(string) or cls([string]) + items = shlex.split(string) + return JythonCommandSpec.from_string(string) or cls(items) def install_options(self, script_text): self.options = shlex.split(self._extract_options(script_text)) diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py index e1f06788..a3d5b0a9 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -505,3 +505,12 @@ class TestCommandSpec: cmd = CommandSpec.from_environment() assert len(cmd) == 1 assert cmd.as_header().startswith('#!"') + + def test_from_simple_string_uses_shlex(self): + """ + In order to support `executable = /usr/bin/env my-python`, make sure + from_param invokes shlex on that input. + """ + cmd = CommandSpec.from_param('/usr/bin/env my-python') + assert len(cmd) == 2 + assert '"' not in cmd.as_header() -- cgit v1.2.1 From b2c646684986070b34b92aef52d2f57391c99626 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 4 Jan 2015 22:45:56 -0500 Subject: Fix failing test (now that expectation is different). --- setuptools/tests/test_easy_install.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py index a3d5b0a9..72b040e1 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -438,7 +438,7 @@ class TestScriptHeader: assert actual == expected actual = ScriptWriter.get_script_header('#!/usr/bin/python', - executable=self.exe_with_spaces) + executable='"'+self.exe_with_spaces+'"') expected = '#!"%s"\n' % self.exe_with_spaces assert actual == expected -- cgit v1.2.1 From b38ede5b91f82c552f1d79a0346ea5f24b0b7d1a Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Mon, 5 Jan 2015 13:03:59 -0500 Subject: Bumped to 11.3 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index a6fd3e36..b1a75f41 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '11.2' +__version__ = '11.3' -- cgit v1.2.1 From 92a553d3adeb431cdf92b136ac9ccc3f2ef98bf1 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Mon, 5 Jan 2015 14:21:41 -0500 Subject: Add EntryPoint.resolve and deprecate most usage of EntryPoint.load. Removed EntryPoint._load. --- setuptools/command/test.py | 2 +- setuptools/dist.py | 2 +- setuptools/tests/test_sdist.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/test.py b/setuptools/command/test.py index 2bf5cb16..42689f70 100644 --- a/setuptools/command/test.py +++ b/setuptools/command/test.py @@ -172,4 +172,4 @@ class test(Command): if val is None: return parsed = EntryPoint.parse("x=" + val) - return parsed._load()() + return parsed.resolve()() diff --git a/setuptools/dist.py b/setuptools/dist.py index 1917a610..bc29b131 100644 --- a/setuptools/dist.py +++ b/setuptools/dist.py @@ -434,7 +434,7 @@ class Distribution(_Distribution): for ep in pkg_resources.iter_entry_points('distutils.commands'): if ep.name not in self.cmdclass: # don't require extras as the commands won't be invoked - cmdclass = ep._load() + cmdclass = ep.resolve() self.cmdclass[ep.name] = cmdclass return _Distribution.print_commands(self) diff --git a/setuptools/tests/test_sdist.py b/setuptools/tests/test_sdist.py index d3494d7a..9013b505 100644 --- a/setuptools/tests/test_sdist.py +++ b/setuptools/tests/test_sdist.py @@ -415,5 +415,5 @@ def test_default_revctrl(): """ ep_def = 'svn_cvs = setuptools.command.sdist:_default_revctrl' ep = pkg_resources.EntryPoint.parse(ep_def) - res = ep._load() + res = ep.resolve() assert hasattr(res, '__iter__') -- cgit v1.2.1 From 6fe9a6147ff850b64ffc241f65c2411f53fb34c4 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Mon, 5 Jan 2015 14:24:10 -0500 Subject: Bumped to 11.4 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index b1a75f41..cef537ae 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '11.3' +__version__ = '11.4' -- cgit v1.2.1 From 37c72186f7cd585a0ceab8d11c3baede009ca961 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 6 Jan 2015 10:11:49 -0500 Subject: Bumped to 11.3.1 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index cef537ae..6e50490a 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '11.4' +__version__ = '11.3.1' -- cgit v1.2.1 From a8f60a73238ae67e0c5a04e437fd9f4edf08bbd6 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 6 Jan 2015 10:12:28 -0500 Subject: Bumped to 11.3.2 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index 6e50490a..1e71f92d 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '11.3.1' +__version__ = '11.3.2' -- cgit v1.2.1 From 74637dd638a30c153d9af60688078c7e12d810d3 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 14 Jan 2015 21:23:57 -0500 Subject: Extract Exception saving behavior. --- setuptools/sandbox.py | 70 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 45 insertions(+), 25 deletions(-) (limited to 'setuptools') diff --git a/setuptools/sandbox.py b/setuptools/sandbox.py index 7971f42c..37d89a2a 100755 --- a/setuptools/sandbox.py +++ b/setuptools/sandbox.py @@ -92,6 +92,37 @@ def pushd(target): os.chdir(saved) +class ExceptionSaver: + """ + A Context Manager that will save an exception, serialized, and restore it + later. + """ + def __enter__(self): + return self + + def __exit__(self, type, exc, tb): + if not exc: + return + + # dump the exception + self.saved_type = pickle.dumps(type) + self.saved_exc = pickle.dumps(exc) + self.tb = tb + + # suppress the exception + return True + + def resume(self): + "restore and re-raise any exception" + + if 'saved_exc' not in vars(self): + return + + type = pickle.loads(self.saved_type) + exc = pickle.loads(self.saved_exc) + compat.reraise(type, exc, self.tb) + + @contextlib.contextmanager def save_modules(): """ @@ -101,31 +132,20 @@ def save_modules(): outside the context. """ saved = sys.modules.copy() - try: - try: - yield saved - except: - # dump any exception - class_, exc, tb = sys.exc_info() - saved_cls = pickle.dumps(class_) - saved_exc = pickle.dumps(exc) - raise - finally: - sys.modules.update(saved) - # remove any modules imported since - del_modules = ( - mod_name for mod_name in sys.modules - if mod_name not in saved - # exclude any encodings modules. See #285 - and not mod_name.startswith('encodings.') - ) - _clear_modules(del_modules) - except: - # reload and re-raise any exception, using restored modules - class_, exc, tb = sys.exc_info() - new_cls = pickle.loads(saved_cls) - new_exc = pickle.loads(saved_exc) - compat.reraise(new_cls, new_exc, tb) + with ExceptionSaver() as saved_exc: + yield saved + + sys.modules.update(saved) + # remove any modules imported since + del_modules = ( + mod_name for mod_name in sys.modules + if mod_name not in saved + # exclude any encodings modules. See #285 + and not mod_name.startswith('encodings.') + ) + _clear_modules(del_modules) + + saved_exc.resume() def _clear_modules(module_names): -- cgit v1.2.1 From 19c95d3ef6dba78bf6431b6b13d000bc19e84cd6 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 14 Jan 2015 21:24:17 -0500 Subject: Remove unused import --- setuptools/tests/test_sandbox.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_sandbox.py b/setuptools/tests/test_sandbox.py index cadc4812..9a2a6b7b 100644 --- a/setuptools/tests/test_sandbox.py +++ b/setuptools/tests/test_sandbox.py @@ -7,7 +7,7 @@ import pytest import pkg_resources import setuptools.sandbox -from setuptools.sandbox import DirectorySandbox, SandboxViolation +from setuptools.sandbox import DirectorySandbox class TestSandbox: -- cgit v1.2.1 From c10a38e97daf7aad2167b3b444be8542dccc652e Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 14 Jan 2015 21:32:39 -0500 Subject: Add tests for new ExceptionSaver --- setuptools/tests/test_sandbox.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'setuptools') diff --git a/setuptools/tests/test_sandbox.py b/setuptools/tests/test_sandbox.py index 9a2a6b7b..33fb3329 100644 --- a/setuptools/tests/test_sandbox.py +++ b/setuptools/tests/test_sandbox.py @@ -54,3 +54,31 @@ class TestSandbox: with setup_py.open('wb') as stream: stream.write(b'"degenerate script"\r\n') setuptools.sandbox._execfile(str(setup_py), globals()) + + +class TestExceptionSaver: + def test_exception_trapped(self): + with setuptools.sandbox.ExceptionSaver(): + raise ValueError("details") + + def test_exception_resumed(self): + with setuptools.sandbox.ExceptionSaver() as saved_exc: + raise ValueError("details") + + with pytest.raises(ValueError) as caught: + saved_exc.resume() + + assert isinstance(caught.value, ValueError) + assert str(caught.value) == 'details' + + def test_exception_reconstructed(self): + orig_exc = ValueError("details") + + with setuptools.sandbox.ExceptionSaver() as saved_exc: + raise orig_exc + + with pytest.raises(ValueError) as caught: + saved_exc.resume() + + assert isinstance(caught.value, ValueError) + assert caught.value is not orig_exc -- cgit v1.2.1 From a33a5ba6ed5be3affc10fd0e789799b7490d2053 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 14 Jan 2015 21:38:25 -0500 Subject: Adding test for non-exceptional condition. --- setuptools/tests/test_sandbox.py | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'setuptools') diff --git a/setuptools/tests/test_sandbox.py b/setuptools/tests/test_sandbox.py index 33fb3329..1340cecf 100644 --- a/setuptools/tests/test_sandbox.py +++ b/setuptools/tests/test_sandbox.py @@ -82,3 +82,9 @@ class TestExceptionSaver: assert isinstance(caught.value, ValueError) assert caught.value is not orig_exc + + def test_no_exception_passes_quietly(self): + with setuptools.sandbox.ExceptionSaver() as saved_exc: + pass + + saved_exc.resume() -- cgit v1.2.1 From 9948d3c8a7880cbc13012e8a3fedda130614601d Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 14 Jan 2015 21:40:02 -0500 Subject: Make attributes private and remove redundant naming. --- setuptools/sandbox.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'setuptools') diff --git a/setuptools/sandbox.py b/setuptools/sandbox.py index 37d89a2a..0847ef41 100755 --- a/setuptools/sandbox.py +++ b/setuptools/sandbox.py @@ -105,9 +105,9 @@ class ExceptionSaver: return # dump the exception - self.saved_type = pickle.dumps(type) - self.saved_exc = pickle.dumps(exc) - self.tb = tb + self._type = pickle.dumps(type) + self._exc = pickle.dumps(exc) + self._tb = tb # suppress the exception return True @@ -115,12 +115,12 @@ class ExceptionSaver: def resume(self): "restore and re-raise any exception" - if 'saved_exc' not in vars(self): + if '_exc' not in vars(self): return - type = pickle.loads(self.saved_type) - exc = pickle.loads(self.saved_exc) - compat.reraise(type, exc, self.tb) + type = pickle.loads(self._type) + exc = pickle.loads(self._exc) + compat.reraise(type, exc, self._tb) @contextlib.contextmanager -- cgit v1.2.1 From 9c3d6750cbef8e0673e4123aa39149e28a8a098e Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 14 Jan 2015 21:49:12 -0500 Subject: Add test capturing failure when the Exception is not pickleable. Ref #329. --- setuptools/tests/test_sandbox.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'setuptools') diff --git a/setuptools/tests/test_sandbox.py b/setuptools/tests/test_sandbox.py index 1340cecf..6e1e9e1c 100644 --- a/setuptools/tests/test_sandbox.py +++ b/setuptools/tests/test_sandbox.py @@ -88,3 +88,15 @@ class TestExceptionSaver: pass saved_exc.resume() + + def test_unpickleable_exception(self): + class CantPickleThis(Exception): + "This Exception is unpickleable because it's not in globals" + + with setuptools.sandbox.ExceptionSaver() as saved_exc: + raise CantPickleThis('detail') + + with pytest.raises(setuptools.sandbox.UnpickleableException) as caught: + saved_exc.resume() + + assert str(caught.value) == "CantPickleThis('detail',)" -- cgit v1.2.1 From 9cf04f13f2ff72a7befa15f8f4835d2c662508e6 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 14 Jan 2015 22:06:09 -0500 Subject: Wrap unpickleable exceptions in another class. Fixes #329. --- setuptools/sandbox.py | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) (limited to 'setuptools') diff --git a/setuptools/sandbox.py b/setuptools/sandbox.py index 0847ef41..83283ca3 100755 --- a/setuptools/sandbox.py +++ b/setuptools/sandbox.py @@ -92,6 +92,22 @@ def pushd(target): os.chdir(saved) +class UnpickleableException(Exception): + """ + An exception representing another Exception that could not be pickled. + """ + @classmethod + def dump(cls, type, exc): + """ + Always return a dumped (pickled) type and exc. If exc can't be pickled, + wrap it in UnpickleableException first. + """ + try: + return pickle.dumps(type), pickle.dumps(exc) + except Exception: + return cls.dump(cls, cls(repr(exc))) + + class ExceptionSaver: """ A Context Manager that will save an exception, serialized, and restore it @@ -105,8 +121,7 @@ class ExceptionSaver: return # dump the exception - self._type = pickle.dumps(type) - self._exc = pickle.dumps(exc) + self._saved = UnpickleableException.dump(type, exc) self._tb = tb # suppress the exception @@ -115,11 +130,10 @@ class ExceptionSaver: def resume(self): "restore and re-raise any exception" - if '_exc' not in vars(self): + if '_saved' not in vars(self): return - type = pickle.loads(self._type) - exc = pickle.loads(self._exc) + type, exc = map(pickle.loads, self._saved) compat.reraise(type, exc, self._tb) -- cgit v1.2.1 From 72d5cc0b9ea095437bf2796298dd3658624c081e Mon Sep 17 00:00:00 2001 From: Slavek Kabrda Date: Fri, 9 Jan 2015 09:40:48 +0000 Subject: Access os.environ[key], not os.environ['key'] --- setuptools/tests/contexts.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/tests/contexts.py b/setuptools/tests/contexts.py index d06a333f..4a461765 100644 --- a/setuptools/tests/contexts.py +++ b/setuptools/tests/contexts.py @@ -27,7 +27,7 @@ def environment(**replacements): to clear the values. """ saved = dict( - (key, os.environ['key']) + (key, os.environ[key]) for key in replacements if key in os.environ ) -- cgit v1.2.1 From cde1eb84bd1813ff4425fe6f05cbdeba8e410c13 Mon Sep 17 00:00:00 2001 From: Arfrever Frehtes Taifersar Arahesis Date: Thu, 15 Jan 2015 23:25:04 +0100 Subject: Use unittest.mock from standard library instead of external mock with Python >=3.3. --- setuptools/tests/fixtures.py | 5 ++++- setuptools/tests/test_easy_install.py | 5 ++++- setuptools/tests/test_msvc9compiler.py | 5 ++++- 3 files changed, 12 insertions(+), 3 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/fixtures.py b/setuptools/tests/fixtures.py index 0b1eaf5f..c70c38cb 100644 --- a/setuptools/tests/fixtures.py +++ b/setuptools/tests/fixtures.py @@ -1,4 +1,7 @@ -import mock +try: + from unittest import mock +except ImportError: + import mock import pytest from . import contexts diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py index 72b040e1..689860c3 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -15,7 +15,10 @@ import logging import itertools import pytest -import mock +try: + from unittest import mock +except ImportError: + import mock from setuptools import sandbox from setuptools import compat diff --git a/setuptools/tests/test_msvc9compiler.py b/setuptools/tests/test_msvc9compiler.py index a0820fff..e54e7a6e 100644 --- a/setuptools/tests/test_msvc9compiler.py +++ b/setuptools/tests/test_msvc9compiler.py @@ -7,7 +7,10 @@ import contextlib import distutils.errors import pytest -import mock +try: + from unittest import mock +except ImportError: + import mock from . import contexts -- cgit v1.2.1 From 1cd6c9a1f6840ff82217a9e7059b8ec7049f3a32 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Thu, 15 Jan 2015 19:41:04 -0500 Subject: Skip integration tests when SSL is broken. Ref #317. --- setuptools/tests/test_integration.py | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'setuptools') diff --git a/setuptools/tests/test_integration.py b/setuptools/tests/test_integration.py index 92a27080..90bb4313 100644 --- a/setuptools/tests/test_integration.py +++ b/setuptools/tests/test_integration.py @@ -12,6 +12,7 @@ import pytest from setuptools.command.easy_install import easy_install from setuptools.command import easy_install as easy_install_pkg from setuptools.dist import Distribution +from setuptools.compat import urlopen def setup_module(module): @@ -24,6 +25,11 @@ def setup_module(module): except ImportError: pass + try: + urlopen('https://pypi.python.org/pypi') + except Exception as exc: + pytest.skip(reason=str(exc)) + @pytest.fixture def install_context(request, tmpdir, monkeypatch): -- cgit v1.2.1 From 3558c1a03584064e9bb86d3886009902eec6832d Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Thu, 15 Jan 2015 19:53:25 -0500 Subject: Have mock_install_dir actually yield the file name. Ref #317. --- setuptools/tests/test_msvc9compiler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_msvc9compiler.py b/setuptools/tests/test_msvc9compiler.py index e54e7a6e..82c4d521 100644 --- a/setuptools/tests/test_msvc9compiler.py +++ b/setuptools/tests/test_msvc9compiler.py @@ -173,4 +173,4 @@ class TestModulePatch: vcvarsall = os.path.join(result, 'vcvarsall.bat') with open(vcvarsall, 'w'): pass - yield + yield vcvarsall -- cgit v1.2.1 From 903de3abdd20a96051cedad2f0f4287a3a4b11b5 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Thu, 15 Jan 2015 20:48:10 -0500 Subject: Just the path is expected --- setuptools/tests/test_msvc9compiler.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_msvc9compiler.py b/setuptools/tests/test_msvc9compiler.py index 82c4d521..0790e3d2 100644 --- a/setuptools/tests/test_msvc9compiler.py +++ b/setuptools/tests/test_msvc9compiler.py @@ -113,7 +113,8 @@ class TestModulePatch: Ensure user's settings are preferred. """ result = distutils.msvc9compiler.find_vcvarsall(9.0) - assert user_preferred_setting == result + expected = os.path.join(user_preferred_setting, 'vcvarsall.bat') + assert expected == result @pytest.yield_fixture def local_machine_setting(self): @@ -134,7 +135,8 @@ class TestModulePatch: Ensure machine setting is honored if user settings are not present. """ result = distutils.msvc9compiler.find_vcvarsall(9.0) - assert local_machine_setting == result + expected = os.path.join(local_machine_setting, 'vcvarsall.bat') + assert expected == result @pytest.yield_fixture def x64_preferred_setting(self): @@ -160,7 +162,8 @@ class TestModulePatch: Ensure 64-bit system key is preferred. """ result = distutils.msvc9compiler.find_vcvarsall(9.0) - assert x64_preferred_setting == result + expected = os.path.join(x64_preferred_setting, 'vcvarsall.bat') + assert expected == result @staticmethod @contextlib.contextmanager @@ -173,4 +176,4 @@ class TestModulePatch: vcvarsall = os.path.join(result, 'vcvarsall.bat') with open(vcvarsall, 'w'): pass - yield vcvarsall + yield result -- cgit v1.2.1 From 07dac60e9e33d9d74232eab325a3a8ad6a05e50d Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Thu, 15 Jan 2015 19:57:21 -0500 Subject: Remove unused import --- setuptools/msvc9_support.py | 2 -- 1 file changed, 2 deletions(-) (limited to 'setuptools') diff --git a/setuptools/msvc9_support.py b/setuptools/msvc9_support.py index e76d70f0..2e4032b1 100644 --- a/setuptools/msvc9_support.py +++ b/setuptools/msvc9_support.py @@ -1,5 +1,3 @@ -import sys - try: import distutils.msvc9compiler except ImportError: -- cgit v1.2.1 From 64f09ab5fb6c9c0a0344e50388022ee6e2e85d85 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Thu, 15 Jan 2015 20:28:02 -0500 Subject: Extract variables --- setuptools/msvc9_support.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'setuptools') diff --git a/setuptools/msvc9_support.py b/setuptools/msvc9_support.py index 2e4032b1..a69c7474 100644 --- a/setuptools/msvc9_support.py +++ b/setuptools/msvc9_support.py @@ -27,13 +27,15 @@ def patch_for_specialized_compiler(): def find_vcvarsall(version): Reg = distutils.msvc9compiler.Reg VC_BASE = r'Software\%sMicrosoft\DevDiv\VCForPython\%0.1f' + key = VC_BASE % ('', version) try: # Per-user installs register the compiler path here - productdir = Reg.get_value(VC_BASE % ('', version), "installdir") + productdir = Reg.get_value(key, "installdir") except KeyError: try: # All-user installs on a 64-bit system register here - productdir = Reg.get_value(VC_BASE % ('Wow6432Node\\', version), "installdir") + key = VC_BASE % ('Wow6432Node\\', version) + productdir = Reg.get_value(key, "installdir") except KeyError: productdir = None -- cgit v1.2.1 From 21ebac859dff95cb593180f7fffdf74d8a5e5275 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Thu, 15 Jan 2015 21:09:57 -0500 Subject: Fix failing test by reverting to author's original intent. Ref #317 --- setuptools/tests/test_msvc9compiler.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_msvc9compiler.py b/setuptools/tests/test_msvc9compiler.py index 0790e3d2..09e0460c 100644 --- a/setuptools/tests/test_msvc9compiler.py +++ b/setuptools/tests/test_msvc9compiler.py @@ -142,7 +142,7 @@ class TestModulePatch: def x64_preferred_setting(self): """ Set up environment with 64-bit and 32-bit system settings configured - and yield the 64-bit location. + and yield the canonical location. """ with self.mock_install_dir() as x32_dir: with self.mock_install_dir() as x64_dir: @@ -155,7 +155,7 @@ class TestModulePatch: }, ) with reg: - yield x64_dir + yield x32_dir def test_ensure_64_bit_preferred(self, x64_preferred_setting): """ -- cgit v1.2.1 From 921fc3e28378598912d69d3f2a6ebdd090ed3e4e Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 16 Jan 2015 15:33:09 -0500 Subject: Renamed .get_writer to .best and removed boolean argument. --- setuptools/command/easy_install.py | 25 +++++++++++++++++++------ setuptools/command/install_scripts.py | 11 ++++++----- 2 files changed, 25 insertions(+), 11 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 340b1fac..b61ab034 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -742,7 +742,7 @@ Please make the appropriate changes for your system and try again. def install_wrapper_scripts(self, dist): if not self.exclude_scripts: - for args in ScriptWriter.get_args(dist): + for args in ScriptWriter.best().get_args(dist): self.write_script(*args) def install_script(self, dist, script_name, script_text, dev_path=None): @@ -1975,7 +1975,7 @@ class ScriptWriter(object): def get_script_args(cls, dist, executable=None, wininst=False): # for backward compatibility warnings.warn("Use get_args", DeprecationWarning) - writer = cls.get_writer(wininst) + writer = (WindowsScriptWriter if wininst else ScriptWriter).best() header = cls.get_script_header("", executable, wininst) return writer.get_args(dist, header) @@ -2007,9 +2007,16 @@ class ScriptWriter(object): @classmethod def get_writer(cls, force_windows): - if force_windows or sys.platform == 'win32': - return WindowsScriptWriter.get_writer() - return cls + # for backward compatibility + warnings.warn("Use best", DeprecationWarning) + return WindowsScriptWriter.best() if force_windows else cls.best() + + @classmethod + def best(cls): + """ + Select the best ScriptWriter for this environment. + """ + return WindowsScriptWriter.best() if sys.platform == 'win32' else cls @classmethod def _get_script_args(cls, type_, name, header, script_text): @@ -2027,8 +2034,14 @@ class ScriptWriter(object): class WindowsScriptWriter(ScriptWriter): @classmethod def get_writer(cls): + # for backward compatibility + warnings.warn("Use best", DeprecationWarning) + return cls.best() + + @classmethod + def best(cls): """ - Get a script writer suitable for Windows + Select the best ScriptWriter suitable for Windows """ writer_lookup = dict( executable=WindowsExecutableLauncherWriter, diff --git a/setuptools/command/install_scripts.py b/setuptools/command/install_scripts.py index 722b0566..ad89c5fd 100755 --- a/setuptools/command/install_scripts.py +++ b/setuptools/command/install_scripts.py @@ -13,7 +13,7 @@ class install_scripts(orig.install_scripts): self.no_ep = False def run(self): - from setuptools.command.easy_install import ScriptWriter, CommandSpec + import setuptools.command.easy_install as ei self.run_command("egg_info") if self.distribution.scripts: @@ -30,14 +30,15 @@ class install_scripts(orig.install_scripts): ei_cmd.egg_name, ei_cmd.egg_version, ) bs_cmd = self.get_finalized_command('build_scripts') - cmd = CommandSpec.from_param(getattr(bs_cmd, 'executable', None)) + cmd = ei.CommandSpec.from_param(getattr(bs_cmd, 'executable', None)) is_wininst = getattr( self.get_finalized_command("bdist_wininst"), '_is_running', False ) + writer = ei.ScriptWriter if is_wininst: - cmd = CommandSpec.from_string("python.exe") - writer = ScriptWriter.get_writer(force_windows=is_wininst) - for args in writer.get_args(dist, cmd.as_header()): + cmd = ei.CommandSpec.from_string("python.exe") + writer = ei.WindowsScriptWriter + for args in writer.best().get_args(dist, cmd.as_header()): self.write_script(*args) def write_script(self, script_name, contents, mode="t", *ignored): -- cgit v1.2.1 From 2e8bbf46b8fba71b22d20e69224d86e4750726c0 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 16 Jan 2015 16:38:28 -0500 Subject: Bumped to 12.0 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index 1e71f92d..f4e58d46 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '11.3.2' +__version__ = '12.0' -- cgit v1.2.1 From cda3ccf5c2b87212ca53b91fb782e2b858686dd3 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 16 Jan 2015 16:39:06 -0500 Subject: Bumped to 12.1 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index f4e58d46..9e9002b4 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '12.0' +__version__ = '12.1' -- cgit v1.2.1 From 072653066beade0dc5fde02c26e747002ab80baa Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 16 Jan 2015 17:22:22 -0500 Subject: Restore setuptools.command.easy_install.sys_executable for pbr compatibility. --- setuptools/command/easy_install.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index b61ab034..adb18140 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -56,7 +56,6 @@ from pkg_resources import ( ) import pkg_resources - # Turn on PEP440Warnings warnings.filterwarnings("default", category=pkg_resources.PEP440Warning) @@ -1917,6 +1916,9 @@ class CommandSpec(list): cmdline = subprocess.list2cmdline(items) return '#!' + cmdline + '\n' +# For pbr compat; will be removed in a future version. +sys_executable = CommandSpec._sys_executable() + class JythonCommandSpec(CommandSpec): @classmethod @@ -2238,4 +2240,3 @@ def _patch_usage(): yield finally: distutils.core.gen_usage = saved - -- cgit v1.2.1 From 085191a65831a18f81bd654d2171bcb7b0b3381a Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 16 Jan 2015 17:37:36 -0500 Subject: Bumped to 12.0.1 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index 9e9002b4..06db60e2 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '12.1' +__version__ = '12.0.1' -- cgit v1.2.1 From 57fb24d60656bc99192c9768ff04dd78de9ef695 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 16 Jan 2015 17:38:07 -0500 Subject: Bumped to 12.0.2 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index 06db60e2..dd108765 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '12.0.1' +__version__ = '12.0.2' -- cgit v1.2.1 From fd7fb7ade0fc879e24543f13c39b00de073004bc Mon Sep 17 00:00:00 2001 From: Arfrever Frehtes Taifersar Arahesis Date: Sat, 17 Jan 2015 21:41:55 +0100 Subject: Fix "AttributeError: 'TarFile' object has no attribute '__exit__'" with Python 3.1. --- setuptools/tests/py26compat.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/tests/py26compat.py b/setuptools/tests/py26compat.py index c53b4809..c5680881 100644 --- a/setuptools/tests/py26compat.py +++ b/setuptools/tests/py26compat.py @@ -8,4 +8,7 @@ def _tarfile_open_ex(*args, **kwargs): """ return contextlib.closing(tarfile.open(*args, **kwargs)) -tarfile_open = _tarfile_open_ex if sys.version_info < (2,7) else tarfile.open +if sys.version_info[:2] < (2, 7) or (3, 0) <= sys.version_info[:2] < (3, 2): + tarfile_open = _tarfile_open_ex +else: + tarfile_open = tarfile.open -- cgit v1.2.1 From 49a3b4c156062e4212ed59e2061a178577196fb6 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 18 Jan 2015 15:51:42 -0500 Subject: Remove unintended shebang. Fixes #333. --- setuptools/tests/test_easy_install.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py index 689860c3..5e36044d 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -1,4 +1,4 @@ -#! -*- coding: utf-8 -*- +# -*- coding: utf-8 -*- """Easy install Tests """ -- cgit v1.2.1 From f2685d1d9311fa2603ea069d4ed13a74624c8f8c Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 18 Jan 2015 19:22:59 -0500 Subject: Extract messages as class attributes for nicer indentation. --- setuptools/command/easy_install.py | 161 ++++++++++++++++++++----------------- 1 file changed, 88 insertions(+), 73 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index adb18140..fcd96bea 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -445,43 +445,49 @@ class easy_install(Command): self.pth_file = None # and don't create a .pth file self.install_dir = instdir - def cant_write_to_target(self): - template = """can't create or remove files in install directory + __cant_write_msg = textwrap.dedent(""" + can't create or remove files in install directory -The following error occurred while trying to add or remove files in the -installation directory: + The following error occurred while trying to add or remove files in the + installation directory: - %s + %s -The installation directory you specified (via --install-dir, --prefix, or -the distutils default setting) was: + The installation directory you specified (via --install-dir, --prefix, or + the distutils default setting) was: - %s -""" - msg = template % (sys.exc_info()[1], self.install_dir,) + %s + """).lstrip() - if not os.path.exists(self.install_dir): - msg += """ -This directory does not currently exist. Please create it and try again, or -choose a different installation directory (using the -d or --install-dir -option). -""" - else: - msg += """ -Perhaps your account does not have write access to this directory? If the -installation directory is a system-owned directory, you may need to sign in -as the administrator or "root" account. If you do not have administrative -access to this machine, you may wish to choose a different installation -directory, preferably one that is listed in your PYTHONPATH environment -variable. + __not_exists_id = textwrap.dedent(""" + This directory does not currently exist. Please create it and try again, or + choose a different installation directory (using the -d or --install-dir + option). + """).lstrip() -For information on other options, you may wish to consult the -documentation at: + __access_msg = textwrap.dedent(""" + Perhaps your account does not have write access to this directory? If the + installation directory is a system-owned directory, you may need to sign in + as the administrator or "root" account. If you do not have administrative + access to this machine, you may wish to choose a different installation + directory, preferably one that is listed in your PYTHONPATH environment + variable. - https://pythonhosted.org/setuptools/easy_install.html + For information on other options, you may wish to consult the + documentation at: -Please make the appropriate changes for your system and try again. -""" + https://pythonhosted.org/setuptools/easy_install.html + + Please make the appropriate changes for your system and try again. + """).lstrip() + + def cant_write_to_target(self): + msg = self._cant_write_msg % (sys.exc_info()[1], self.install_dir,) + + if not os.path.exists(self.install_dir): + msg += '\n' + self.__not_exists_id + else: + msg += '\n' + self.__access_msg raise DistutilsError(msg) def check_pth_processing(self): @@ -979,46 +985,52 @@ Please make the appropriate changes for your system and try again. f.write('\n'.join(locals()[name]) + '\n') f.close() + __mv_warning = textwrap.dedent(""" + Because this distribution was installed --multi-version, before you can + import modules from this package in an application, you will need to + 'import pkg_resources' and then use a 'require()' call similar to one of + these examples, in order to select the desired version: + + pkg_resources.require("%(name)s") # latest installed version + pkg_resources.require("%(name)s==%(version)s") # this exact version + pkg_resources.require("%(name)s>=%(version)s") # this version or higher + """).lstrip() + + __id_warning = textwrap.dedent(""" + Note also that the installation directory must be on sys.path at runtime for + this to work. (e.g. by being the application's script directory, by being on + PYTHONPATH, or by being added to sys.path by your code.) + """) + def installation_report(self, req, dist, what="Installed"): """Helpful installation message for display to package users""" msg = "\n%(what)s %(eggloc)s%(extras)s" if self.multi_version and not self.no_report: - msg += """ - -Because this distribution was installed --multi-version, before you can -import modules from this package in an application, you will need to -'import pkg_resources' and then use a 'require()' call similar to one of -these examples, in order to select the desired version: - - pkg_resources.require("%(name)s") # latest installed version - pkg_resources.require("%(name)s==%(version)s") # this exact version - pkg_resources.require("%(name)s>=%(version)s") # this version or higher -""" + msg += '\n' + self.__mv_warning if self.install_dir not in map(normalize_path, sys.path): - msg += """ + msg += '\n' + self.__id_warning -Note also that the installation directory must be on sys.path at runtime for -this to work. (e.g. by being the application's script directory, by being on -PYTHONPATH, or by being added to sys.path by your code.) -""" eggloc = dist.location name = dist.project_name version = dist.version extras = '' # TODO: self.report_extras(req, dist) return msg % locals() - def report_editable(self, spec, setup_script): - dirname = os.path.dirname(setup_script) - python = sys.executable - return """\nExtracted editable version of %(spec)s to %(dirname)s + __editable_msg = textwrap.dedent(""" + Extracted editable version of %(spec)s to %(dirname)s -If it uses setuptools in its setup script, you can activate it in -"development" mode by going to that directory and running:: + If it uses setuptools in its setup script, you can activate it in + "development" mode by going to that directory and running:: - %(python)s setup.py develop + %(python)s setup.py develop -See the setuptools documentation for the "develop" command for more info. -""" % locals() + See the setuptools documentation for the "develop" command for more info. + """).lstrip() + + def report_editable(self, spec, setup_script): + dirname = os.path.dirname(setup_script) + python = sys.executable + return '\n' + self.__editable_msg % locals() def run_setup(self, setup_script, setup_base, args): sys.modules.setdefault('distutils.command.bdist_egg', bdist_egg) @@ -1169,35 +1181,38 @@ See the setuptools documentation for the "develop" command for more info. finally: log.set_verbosity(self.verbose) # restore original verbosity - def no_default_version_msg(self): - template = """bad install directory or PYTHONPATH + __no_default_msg = textwrap.dedent(""" + bad install directory or PYTHONPATH -You are attempting to install a package to a directory that is not -on PYTHONPATH and which Python does not read ".pth" files from. The -installation directory you specified (via --install-dir, --prefix, or -the distutils default setting) was: + You are attempting to install a package to a directory that is not + on PYTHONPATH and which Python does not read ".pth" files from. The + installation directory you specified (via --install-dir, --prefix, or + the distutils default setting) was: - %s + %s -and your PYTHONPATH environment variable currently contains: + and your PYTHONPATH environment variable currently contains: - %r + %r -Here are some of your options for correcting the problem: + Here are some of your options for correcting the problem: -* You can choose a different installation directory, i.e., one that is - on PYTHONPATH or supports .pth files + * You can choose a different installation directory, i.e., one that is + on PYTHONPATH or supports .pth files -* You can add the installation directory to the PYTHONPATH environment - variable. (It must then also be on PYTHONPATH whenever you run - Python and want to use the package(s) you are installing.) + * You can add the installation directory to the PYTHONPATH environment + variable. (It must then also be on PYTHONPATH whenever you run + Python and want to use the package(s) you are installing.) -* You can set up the installation directory to support ".pth" files by - using one of the approaches described here: + * You can set up the installation directory to support ".pth" files by + using one of the approaches described here: - https://pythonhosted.org/setuptools/easy_install.html#custom-installation-locations + https://pythonhosted.org/setuptools/easy_install.html#custom-installation-locations -Please make the appropriate changes for your system and try again.""" + Please make the appropriate changes for your system and try again.""").lstrip() + + def no_default_version_msg(self): + template = self.__no_default_msg return template % (self.install_dir, os.environ.get('PYTHONPATH', '')) def install_site_py(self): -- cgit v1.2.1 From 7cf2343ad9f5b77992422598d27d1f70e9473db0 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 18 Jan 2015 19:45:22 -0500 Subject: Extract variable for bdist_wininst command --- setuptools/command/install_scripts.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/install_scripts.py b/setuptools/command/install_scripts.py index ad89c5fd..cad524ec 100755 --- a/setuptools/command/install_scripts.py +++ b/setuptools/command/install_scripts.py @@ -31,9 +31,8 @@ class install_scripts(orig.install_scripts): ) bs_cmd = self.get_finalized_command('build_scripts') cmd = ei.CommandSpec.from_param(getattr(bs_cmd, 'executable', None)) - is_wininst = getattr( - self.get_finalized_command("bdist_wininst"), '_is_running', False - ) + bw_cmd = self.get_finalized_command("bdist_wininst") + is_wininst = getattr(bw_cmd, '_is_running', False) writer = ei.ScriptWriter if is_wininst: cmd = ei.CommandSpec.from_string("python.exe") -- cgit v1.2.1 From 0d32bf350dce5cf21c821b9216799fa53550c5c1 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 18 Jan 2015 19:46:46 -0500 Subject: Extract variable for exec_param --- setuptools/command/install_scripts.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/command/install_scripts.py b/setuptools/command/install_scripts.py index cad524ec..f85f4520 100755 --- a/setuptools/command/install_scripts.py +++ b/setuptools/command/install_scripts.py @@ -30,7 +30,8 @@ class install_scripts(orig.install_scripts): ei_cmd.egg_name, ei_cmd.egg_version, ) bs_cmd = self.get_finalized_command('build_scripts') - cmd = ei.CommandSpec.from_param(getattr(bs_cmd, 'executable', None)) + exec_param = getattr(bs_cmd, 'executable', None) + cmd = ei.CommandSpec.from_param(exec_param) bw_cmd = self.get_finalized_command("bdist_wininst") is_wininst = getattr(bw_cmd, '_is_running', False) writer = ei.ScriptWriter -- cgit v1.2.1 From 0a0f7d5816fa7e42fd787d4923265adc965e1360 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 18 Jan 2015 19:54:01 -0500 Subject: Defer resolution of the CommandSpec and do it exactly once. --- setuptools/command/install_scripts.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/install_scripts.py b/setuptools/command/install_scripts.py index f85f4520..af079fbb 100755 --- a/setuptools/command/install_scripts.py +++ b/setuptools/command/install_scripts.py @@ -31,13 +31,13 @@ class install_scripts(orig.install_scripts): ) bs_cmd = self.get_finalized_command('build_scripts') exec_param = getattr(bs_cmd, 'executable', None) - cmd = ei.CommandSpec.from_param(exec_param) bw_cmd = self.get_finalized_command("bdist_wininst") is_wininst = getattr(bw_cmd, '_is_running', False) writer = ei.ScriptWriter if is_wininst: - cmd = ei.CommandSpec.from_string("python.exe") + exec_param = "python.exe" writer = ei.WindowsScriptWriter + cmd = ei.CommandSpec.from_param(exec_param) for args in writer.best().get_args(dist, cmd.as_header()): self.write_script(*args) -- cgit v1.2.1 From 97f96e8cd4d1938095101f26a28f17d6a3f97435 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 18 Jan 2015 19:55:09 -0500 Subject: Extract writer resolution as a variable --- setuptools/command/install_scripts.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/command/install_scripts.py b/setuptools/command/install_scripts.py index af079fbb..8d251ee7 100755 --- a/setuptools/command/install_scripts.py +++ b/setuptools/command/install_scripts.py @@ -37,8 +37,10 @@ class install_scripts(orig.install_scripts): if is_wininst: exec_param = "python.exe" writer = ei.WindowsScriptWriter + # resolve the writer to the environment + writer = writer.best() cmd = ei.CommandSpec.from_param(exec_param) - for args in writer.best().get_args(dist, cmd.as_header()): + for args in writer.get_args(dist, cmd.as_header()): self.write_script(*args) def write_script(self, script_name, contents, mode="t", *ignored): -- cgit v1.2.1 From 43ffa78752de38190b2480b68d9ad908cf1b7fa5 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 18 Jan 2015 19:57:02 -0500 Subject: Allow the CommandSpec class to be resolved by the writer. --- setuptools/command/easy_install.py | 2 ++ setuptools/command/install_scripts.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index fcd96bea..9d25a139 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -1988,6 +1988,8 @@ class ScriptWriter(object): ) """).lstrip() + command_spec_class = CommandSpec + @classmethod def get_script_args(cls, dist, executable=None, wininst=False): # for backward compatibility diff --git a/setuptools/command/install_scripts.py b/setuptools/command/install_scripts.py index 8d251ee7..9d4ac420 100755 --- a/setuptools/command/install_scripts.py +++ b/setuptools/command/install_scripts.py @@ -39,7 +39,7 @@ class install_scripts(orig.install_scripts): writer = ei.WindowsScriptWriter # resolve the writer to the environment writer = writer.best() - cmd = ei.CommandSpec.from_param(exec_param) + cmd = writer.command_spec_cls.from_param(exec_param) for args in writer.get_args(dist, cmd.as_header()): self.write_script(*args) -- cgit v1.2.1 From 659e2bd057382e4819f38c2c77ff3b7783d63c6b Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 18 Jan 2015 20:11:29 -0500 Subject: Adding test capturing failure where sys.executable loses backslashes on Windows. Ref #331. --- setuptools/tests/test_easy_install.py | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'setuptools') diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py index 5e36044d..91461364 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -517,3 +517,11 @@ class TestCommandSpec: cmd = CommandSpec.from_param('/usr/bin/env my-python') assert len(cmd) == 2 assert '"' not in cmd.as_header() + + def test_sys_executable(self): + """ + CommandSpec.from_string(sys.executable) should contain just that param. + """ + cmd = CommandSpec.from_string(sys.executable) + assert len(cmd) == 1 + assert cmd[0] == sys.executable -- cgit v1.2.1 From 246a5982a37f38c70012326577278582f0b01ef2 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 18 Jan 2015 20:17:12 -0500 Subject: Use the command spec as resolved by the best ScriptWriter. --- setuptools/tests/test_easy_install.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py index 91461364..cbbe99db 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -522,6 +522,7 @@ class TestCommandSpec: """ CommandSpec.from_string(sys.executable) should contain just that param. """ - cmd = CommandSpec.from_string(sys.executable) + writer = ScriptWriter.best() + cmd = writer.command_spec_class.from_string(sys.executable) assert len(cmd) == 1 assert cmd[0] == sys.executable -- cgit v1.2.1 From 8711abcb4bac42e771647718e6994c6847e0383a Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 18 Jan 2015 20:18:38 -0500 Subject: Also use command_spec_class in ScriptWriter. --- setuptools/command/easy_install.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 9d25a139..137193f1 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -2004,7 +2004,7 @@ class ScriptWriter(object): warnings.warn("Use get_header", DeprecationWarning) if wininst: executable = "python.exe" - cmd = CommandSpec.from_param(executable) + cmd = cls.command_spec_class.from_param(executable) cmd.install_options(script_text) return cmd.as_header() @@ -2045,7 +2045,7 @@ class ScriptWriter(object): @classmethod def get_header(cls, script_text="", executable=None): """Create a #! line, getting options (if any) from script_text""" - cmd = CommandSpec.from_param(executable) + cmd = cls.command_spec_class.from_param(executable) cmd.install_options(script_text) return cmd.as_header() -- cgit v1.2.1 From 27ffea086d37a26dbac2ebbd8b1e0edb4c8a803e Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 18 Jan 2015 20:27:56 -0500 Subject: Use non-posix semantics in a WindowsCommandSpec and use that class in the Windows script writers. Fixes #331. --- setuptools/command/easy_install.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 137193f1..541666ce 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -1873,6 +1873,7 @@ class CommandSpec(list): """ options = [] + split_args = dict() @classmethod def _sys_executable(cls): @@ -1904,7 +1905,7 @@ class CommandSpec(list): Construct a command spec from a simple string representing a command line parseable by shlex.split. """ - items = shlex.split(string) + items = shlex.split(string, **cls.split_args) return JythonCommandSpec.from_string(string) or cls(items) def install_options(self, script_text): @@ -1935,6 +1936,10 @@ class CommandSpec(list): sys_executable = CommandSpec._sys_executable() +class WindowsCommandSpec(CommandSpec): + split_args = dict(posix=False) + + class JythonCommandSpec(CommandSpec): @classmethod def from_string(cls, string): @@ -2051,6 +2056,8 @@ class ScriptWriter(object): class WindowsScriptWriter(ScriptWriter): + command_spec_class = WindowsCommandSpec + @classmethod def get_writer(cls): # for backward compatibility -- cgit v1.2.1 From c1f5cdb9d49d2dc6872c1c51a94dbcc95526666a Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 18 Jan 2015 20:35:36 -0500 Subject: Bumped to 12.0.3 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index dd108765..410c5970 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '12.0.2' +__version__ = '12.0.3' -- cgit v1.2.1 From e584d52bc8080aa0e1dfec9514068bfef175b7fd Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 18 Jan 2015 20:46:32 -0500 Subject: Correct command reference. --- setuptools/command/install_scripts.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/command/install_scripts.py b/setuptools/command/install_scripts.py index 9d4ac420..20c2cce9 100755 --- a/setuptools/command/install_scripts.py +++ b/setuptools/command/install_scripts.py @@ -39,7 +39,7 @@ class install_scripts(orig.install_scripts): writer = ei.WindowsScriptWriter # resolve the writer to the environment writer = writer.best() - cmd = writer.command_spec_cls.from_param(exec_param) + cmd = writer.command_spec_class.from_param(exec_param) for args in writer.get_args(dist, cmd.as_header()): self.write_script(*args) -- cgit v1.2.1 From c808d232427ed8072b3b46b9e1c03df9d4cf9f76 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 18 Jan 2015 20:49:13 -0500 Subject: Bumped to 12.0.4 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index 410c5970..2527f6f7 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '12.0.3' +__version__ = '12.0.4' -- cgit v1.2.1 From ad794c2809cc2ad0a48a14129dca82996f14af28 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 20 Jan 2015 20:33:29 -0500 Subject: Use a .best classmethod to resolve JythonCommandSpec when relevant. --- setuptools/command/easy_install.py | 35 ++++++++++++++++++++++------------- setuptools/command/install_scripts.py | 2 +- 2 files changed, 23 insertions(+), 14 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index dda183c8..9978c132 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -1875,6 +1875,13 @@ class CommandSpec(list): options = [] split_args = dict() + @classmethod + def best(cls): + """ + Choose the best CommandSpec class based on environmental conditions. + """ + return cls if not JythonCommandSpec.relevant() else JythonCommandSpec + @classmethod def _sys_executable(cls): _default = os.path.normpath(sys.executable) @@ -1897,9 +1904,7 @@ class CommandSpec(list): @classmethod def from_environment(cls): - string = '"' + cls._sys_executable() + '"' - jython_spec = JythonCommandSpec.from_string(string) - return jython_spec or cls([cls._sys_executable()]) + return cls([cls._sys_executable()]) @classmethod def from_string(cls, string): @@ -1908,7 +1913,7 @@ class CommandSpec(list): line parseable by shlex.split. """ items = shlex.split(string, **cls.split_args) - return JythonCommandSpec.from_string(string) or cls(items) + return cls(items) def install_options(self, script_text): self.options = shlex.split(self._extract_options(script_text)) @@ -1944,17 +1949,21 @@ class WindowsCommandSpec(CommandSpec): class JythonCommandSpec(CommandSpec): @classmethod - def from_string(cls, string): - """ - On Jython, construct an instance of this class. - On platforms other than Jython, return None. - """ - needs_jython_spec = ( + def relevant(cls): + return ( sys.platform.startswith('java') and __import__('java').lang.System.getProperty('os.name') != 'Linux' ) - return cls([string]) if needs_jython_spec else None + + @classmethod + def from_environment(cls): + string = '"' + cls._sys_executable() + '"' + return cls.from_string(string) + + @classmethod + def from_string(cls, string): + return cls([string]) def as_header(self): """ @@ -2011,7 +2020,7 @@ class ScriptWriter(object): warnings.warn("Use get_header", DeprecationWarning) if wininst: executable = "python.exe" - cmd = cls.command_spec_class.from_param(executable) + cmd = cls.command_spec_class.best().from_param(executable) cmd.install_options(script_text) return cmd.as_header() @@ -2052,7 +2061,7 @@ class ScriptWriter(object): @classmethod def get_header(cls, script_text="", executable=None): """Create a #! line, getting options (if any) from script_text""" - cmd = cls.command_spec_class.from_param(executable) + cmd = cls.command_spec_class.best().from_param(executable) cmd.install_options(script_text) return cmd.as_header() diff --git a/setuptools/command/install_scripts.py b/setuptools/command/install_scripts.py index 20c2cce9..be66cb22 100755 --- a/setuptools/command/install_scripts.py +++ b/setuptools/command/install_scripts.py @@ -39,7 +39,7 @@ class install_scripts(orig.install_scripts): writer = ei.WindowsScriptWriter # resolve the writer to the environment writer = writer.best() - cmd = writer.command_spec_class.from_param(exec_param) + cmd = writer.command_spec_class.best().from_param(exec_param) for args in writer.get_args(dist, cmd.as_header()): self.write_script(*args) -- cgit v1.2.1 From 9209b9f7ce6ecb4d9518037b2463bbedd544dcfc Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 20 Jan 2015 20:48:18 -0500 Subject: Decode file as latin-1 when opening to ensure decoding any bytes. --- setuptools/command/easy_install.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 9978c132..5e25f2cd 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -1801,9 +1801,8 @@ def is_python(text, filename=''): def is_sh(executable): """Determine if the specified executable is a .sh (contains a #! line)""" try: - fp = open(executable) - magic = fp.read(2) - fp.close() + with open(executable, encoding='latin-1') as fp: + magic = fp.read(2) except (OSError, IOError): return executable return magic == '#!' -- cgit v1.2.1 From adbb4edde04b071e4b092b675bb0c2ffb66a0977 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 20 Jan 2015 21:03:56 -0500 Subject: Deprecate fix_jython_executable and replace with JythonCommandSpec --- setuptools/command/easy_install.py | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 5e25f2cd..b8efff73 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -1844,25 +1844,14 @@ def chmod(path, mode): def fix_jython_executable(executable, options): - if sys.platform.startswith('java') and is_sh(executable): - # Workaround for Jython is not needed on Linux systems. - import java + warnings.warn("Use JythonCommandSpec", DeprecationWarning, stacklevel=2) - if java.lang.System.getProperty("os.name") == "Linux": - return executable + if not JythonCommandSpec.relevant(): + return executable - # Workaround Jython's sys.executable being a .sh (an invalid - # shebang line interpreter) - if 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.") - else: - return '/usr/bin/env %s' % executable - return executable + cmd = CommandSpec.best().from_param(executable) + cmd.install_options(options) + return cmd.as_header().lstrip('#!').rstrip('\n') class CommandSpec(list): -- cgit v1.2.1 From 0a81b14fbfdf9b41bf128c99da42a374dff6122a Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 20 Jan 2015 21:05:41 -0500 Subject: Replace use of fix_jython_executable with CommandSpec invocation. --- setuptools/tests/test_easy_install.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py index a2f26e08..3be829c5 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -26,7 +26,7 @@ from setuptools.compat import StringIO, BytesIO, urlparse from setuptools.sandbox import run_setup import setuptools.command.easy_install as ei from setuptools.command.easy_install import ( - easy_install, fix_jython_executable, nt_quote_arg, + easy_install, nt_quote_arg, is_sh, ScriptWriter, CommandSpec, ) from setuptools.command.easy_install import PthDistributions @@ -51,8 +51,7 @@ class FakeDist(object): def as_requirement(self): return 'spec' -WANTED = DALS(""" - #!%s +WANTED = ei.CommandSpec.best().from_environment().as_header() + DALS(""" # EASY-INSTALL-ENTRY-SCRIPT: 'spec','console_scripts','name' __requires__ = 'spec' import sys @@ -62,7 +61,7 @@ WANTED = DALS(""" sys.exit( load_entry_point('spec', 'console_scripts', 'name')() ) - """) % nt_quote_arg(fix_jython_executable(sys.executable, "")) + """) SETUP_PY = DALS(""" from setuptools import setup -- cgit v1.2.1 From 2554cbb108a56ab4932e7f1a773f5a57abdabcd2 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 20 Jan 2015 21:09:10 -0500 Subject: Use module namespace. --- setuptools/tests/test_easy_install.py | 51 +++++++++++++++++------------------ 1 file changed, 24 insertions(+), 27 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py index 3be829c5..51d6f094 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -25,10 +25,6 @@ from setuptools import compat from setuptools.compat import StringIO, BytesIO, urlparse from setuptools.sandbox import run_setup import setuptools.command.easy_install as ei -from setuptools.command.easy_install import ( - easy_install, nt_quote_arg, - is_sh, ScriptWriter, CommandSpec, -) from setuptools.command.easy_install import PthDistributions from setuptools.command import easy_install as easy_install_pkg from setuptools.dist import Distribution @@ -73,7 +69,7 @@ class TestEasyInstallTest: def test_install_site_py(self): dist = Distribution() - cmd = easy_install(dist) + cmd = ei.easy_install(dist) cmd.sitepy_installed = False cmd.install_dir = tempfile.mkdtemp() try: @@ -86,7 +82,7 @@ class TestEasyInstallTest: def test_get_script_args(self): dist = FakeDist() - args = next(ScriptWriter.get_args(dist)) + args = next(ei.ScriptWriter.get_args(dist)) name, script = itertools.islice(args, 2) assert script == WANTED @@ -95,7 +91,7 @@ class TestEasyInstallTest: # new option '--no-find-links', that blocks find-links added at # the project level dist = Distribution() - cmd = easy_install(dist) + cmd = ei.easy_install(dist) cmd.check_pth_processing = lambda: True cmd.no_find_links = True cmd.find_links = ['link1', 'link2'] @@ -105,7 +101,7 @@ class TestEasyInstallTest: assert cmd.package_index.scanned_urls == {} # let's try without it (default behavior) - cmd = easy_install(dist) + cmd = ei.easy_install(dist) cmd.check_pth_processing = lambda: True cmd.find_links = ['link1', 'link2'] cmd.install_dir = os.path.join(tempfile.mkdtemp(), 'ok') @@ -154,7 +150,7 @@ class TestUserInstallTest: #XXX: replace with something meaningfull dist = Distribution() dist.script_name = 'setup.py' - cmd = easy_install(dist) + cmd = ei.easy_install(dist) cmd.args = ['py'] cmd.ensure_finalized() assert cmd.user, 'user should be implied' @@ -175,7 +171,7 @@ class TestUserInstallTest: #XXX: replace with something meaningfull dist = Distribution() dist.script_name = 'setup.py' - cmd = easy_install(dist) + cmd = ei.easy_install(dist) cmd.args = ['py'] cmd.initialize_options() assert not cmd.user, 'NOT user should be implied' @@ -196,7 +192,7 @@ class TestUserInstallTest: try: dist = Distribution() dist.script_name = 'setup.py' - cmd = easy_install(dist) + cmd = ei.easy_install(dist) cmd.install_dir = target cmd.args = ['foo'] cmd.ensure_finalized() @@ -423,24 +419,25 @@ class TestScriptHeader: exe_with_spaces = r'C:\Program Files\Python33\python.exe' @pytest.mark.skipif( - sys.platform.startswith('java') and is_sh(sys.executable), + sys.platform.startswith('java') and ei.is_sh(sys.executable), reason="Test cannot run under java when executable is sh" ) def test_get_script_header(self): - expected = '#!%s\n' % nt_quote_arg(os.path.normpath(sys.executable)) - actual = ScriptWriter.get_script_header('#!/usr/local/bin/python') + expected = '#!%s\n' % ei.nt_quote_arg(os.path.normpath(sys.executable)) + actual = ei.ScriptWriter.get_script_header('#!/usr/local/bin/python') assert actual == expected - expected = '#!%s -x\n' % nt_quote_arg(os.path.normpath(sys.executable)) - actual = ScriptWriter.get_script_header('#!/usr/bin/python -x') + expected = '#!%s -x\n' % ei.nt_quote_arg(os.path.normpath + (sys.executable)) + actual = ei.ScriptWriter.get_script_header('#!/usr/bin/python -x') assert actual == expected - actual = ScriptWriter.get_script_header('#!/usr/bin/python', + actual = ei.ScriptWriter.get_script_header('#!/usr/bin/python', executable=self.non_ascii_exe) expected = '#!%s -x\n' % self.non_ascii_exe assert actual == expected - actual = ScriptWriter.get_script_header('#!/usr/bin/python', + actual = ei.ScriptWriter.get_script_header('#!/usr/bin/python', executable='"'+self.exe_with_spaces+'"') expected = '#!"%s"\n' % self.exe_with_spaces assert actual == expected @@ -463,7 +460,7 @@ class TestScriptHeader: f.write(header) exe = str(exe) - header = ScriptWriter.get_script_header('#!/usr/local/bin/python', + header = ei.ScriptWriter.get_script_header('#!/usr/local/bin/python', executable=exe) assert header == '#!/usr/bin/env %s\n' % exe @@ -472,14 +469,14 @@ class TestScriptHeader: with contexts.quiet() as (stdout, stderr): # When options are included, generate a broken shebang line # with a warning emitted - candidate = ScriptWriter.get_script_header('#!/usr/bin/python -x', + candidate = ei.ScriptWriter.get_script_header('#!/usr/bin/python -x', executable=exe) 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 = ScriptWriter.get_script_header('#!/usr/bin/python', + 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] @@ -492,20 +489,20 @@ class TestCommandSpec: Show how a custom CommandSpec could be used to specify a #! executable which takes parameters. """ - cmd = CommandSpec(['/usr/bin/env', 'python3']) + cmd = ei.CommandSpec(['/usr/bin/env', 'python3']) assert cmd.as_header() == '#!/usr/bin/env python3\n' def test_from_param_for_CommandSpec_is_passthrough(self): """ from_param should return an instance of a CommandSpec """ - cmd = CommandSpec(['python']) - cmd_new = CommandSpec.from_param(cmd) + cmd = ei.CommandSpec(['python']) + cmd_new = ei.CommandSpec.from_param(cmd) assert cmd is cmd_new def test_from_environment_with_spaces_in_executable(self): with mock.patch('sys.executable', TestScriptHeader.exe_with_spaces): - cmd = CommandSpec.from_environment() + cmd = ei.CommandSpec.from_environment() assert len(cmd) == 1 assert cmd.as_header().startswith('#!"') @@ -514,7 +511,7 @@ class TestCommandSpec: In order to support `executable = /usr/bin/env my-python`, make sure from_param invokes shlex on that input. """ - cmd = CommandSpec.from_param('/usr/bin/env my-python') + cmd = ei.CommandSpec.from_param('/usr/bin/env my-python') assert len(cmd) == 2 assert '"' not in cmd.as_header() @@ -522,7 +519,7 @@ class TestCommandSpec: """ CommandSpec.from_string(sys.executable) should contain just that param. """ - writer = ScriptWriter.best() + writer = ei.ScriptWriter.best() cmd = writer.command_spec_class.from_string(sys.executable) assert len(cmd) == 1 assert cmd[0] == sys.executable -- cgit v1.2.1 From 209fbc31d5df376de6db40bc6b1d1d50e87a0a83 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 20 Jan 2015 21:11:36 -0500 Subject: Move global into the only method where it's used. --- setuptools/tests/test_easy_install.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py index 51d6f094..ab6a8f0d 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -47,18 +47,6 @@ class FakeDist(object): def as_requirement(self): return 'spec' -WANTED = ei.CommandSpec.best().from_environment().as_header() + DALS(""" - # EASY-INSTALL-ENTRY-SCRIPT: 'spec','console_scripts','name' - __requires__ = 'spec' - import sys - from pkg_resources import load_entry_point - - if __name__ == '__main__': - sys.exit( - load_entry_point('spec', 'console_scripts', 'name')() - ) - """) - SETUP_PY = DALS(""" from setuptools import setup @@ -80,12 +68,24 @@ class TestEasyInstallTest: shutil.rmtree(cmd.install_dir) def test_get_script_args(self): + header = ei.CommandSpec.best().from_environment().as_header() + expected = header + DALS(""" + # EASY-INSTALL-ENTRY-SCRIPT: 'spec','console_scripts','name' + __requires__ = 'spec' + import sys + from pkg_resources import load_entry_point + + if __name__ == '__main__': + sys.exit( + load_entry_point('spec', 'console_scripts', 'name')() + ) + """) dist = FakeDist() args = next(ei.ScriptWriter.get_args(dist)) name, script = itertools.islice(args, 2) - assert script == WANTED + assert script == expected def test_no_find_links(self): # new option '--no-find-links', that blocks find-links added at -- cgit v1.2.1 From d66e85f360940a5e583ef6a363d20e8aa8cfd486 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 20 Jan 2015 21:47:02 -0500 Subject: Use io module for Python 2 compatibility --- setuptools/command/easy_install.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index b8efff73..206fc58d 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -37,6 +37,7 @@ import struct import contextlib import subprocess import shlex +import io from setuptools import Command from setuptools.sandbox import run_setup @@ -1801,7 +1802,7 @@ def is_python(text, filename=''): def is_sh(executable): """Determine if the specified executable is a .sh (contains a #! line)""" try: - with open(executable, encoding='latin-1') as fp: + with io.open(executable, encoding='latin-1') as fp: magic = fp.read(2) except (OSError, IOError): return executable -- cgit v1.2.1 From 71f6d20fcaa959ef429aa162d1f7c1fa73f52a44 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 20 Jan 2015 22:16:20 -0500 Subject: Bumped to 12.0.5 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index 2527f6f7..8bb69c5f 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '12.0.4' +__version__ = '12.0.5' -- cgit v1.2.1 From dc1b07f1dfc92e097be704ad19824194a95317d2 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 20 Jan 2015 09:40:43 -0500 Subject: Add test capturing regression in script creation in WindowsScriptWriter. --- setuptools/tests/test_easy_install.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'setuptools') diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py index cbbe99db..a2f26e08 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -24,6 +24,7 @@ from setuptools import sandbox from setuptools import compat from setuptools.compat import StringIO, BytesIO, urlparse from setuptools.sandbox import run_setup +import setuptools.command.easy_install as ei from setuptools.command.easy_install import ( easy_install, fix_jython_executable, nt_quote_arg, is_sh, ScriptWriter, CommandSpec, @@ -526,3 +527,14 @@ class TestCommandSpec: cmd = writer.command_spec_class.from_string(sys.executable) assert len(cmd) == 1 assert cmd[0] == sys.executable + + +class TestWindowsScriptWriter: + def test_header(self): + hdr = ei.WindowsScriptWriter.get_script_header('') + assert hdr.startswith('#!') + assert hdr.endswith('\n') + hdr = hdr.lstrip('#!') + hdr = hdr.rstrip('\n') + # header should not start with an escaped quote + assert not hdr.startswith('\\"') -- cgit v1.2.1 From c279903336c73f74c9c8df7aac1e43fb6046c34e Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 20 Jan 2015 09:56:16 -0500 Subject: Bypass string handling when default behavior of sys.executable is used. --- setuptools/command/easy_install.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 541666ce..dda183c8 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -1897,7 +1897,9 @@ class CommandSpec(list): @classmethod def from_environment(cls): - return cls.from_string('"' + cls._sys_executable() + '"') + string = '"' + cls._sys_executable() + '"' + jython_spec = JythonCommandSpec.from_string(string) + return jython_spec or cls([cls._sys_executable()]) @classmethod def from_string(cls, string): -- cgit v1.2.1 From 0478d8fa223ca94e5c9a3f42dd5f92ed8be1270f Mon Sep 17 00:00:00 2001 From: Min RK Date: Tue, 20 Jan 2015 11:24:18 -0800 Subject: remove warning on normalization It seems inappropriate to show a warning on schemes officially supported in PEP 440. --HG-- branch : no-normalize-warning --- setuptools/dist.py | 7 ------- 1 file changed, 7 deletions(-) (limited to 'setuptools') diff --git a/setuptools/dist.py b/setuptools/dist.py index bc29b131..03d78520 100644 --- a/setuptools/dist.py +++ b/setuptools/dist.py @@ -276,13 +276,6 @@ class Distribution(_Distribution): ver = packaging.version.Version(self.metadata.version) normalized_version = str(ver) if self.metadata.version != normalized_version: - warnings.warn( - "The version specified requires normalization, " - "consider using '%s' instead of '%s'." % ( - normalized_version, - self.metadata.version, - ) - ) self.metadata.version = normalized_version except (packaging.version.InvalidVersion, TypeError): warnings.warn( -- cgit v1.2.1 From 732f5e89a8e417ff536d9a51a85d7b328e80dab1 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Mon, 26 Jan 2015 08:29:56 -0500 Subject: Add test capturing Attribute error. Ref #339. --- setuptools/tests/test_easy_install.py | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'setuptools') diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py index ab6a8f0d..4331d30e 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -13,6 +13,7 @@ import contextlib import tarfile import logging import itertools +import distutils.errors import pytest try: @@ -110,6 +111,16 @@ class TestEasyInstallTest: keys = sorted(cmd.package_index.scanned_urls.keys()) assert keys == ['link1', 'link2'] + def test_write_exception(self): + """ + Test that `cant_write_to_target` is rendered as a DistutilsError. + """ + dist = Distribution() + cmd = ei.easy_install(dist) + cmd.install_dir = os.getcwd() + with pytest.raises(distutils.errors.DistutilsError): + cmd.cant_write_to_target() + class TestPTHFileWriter: def test_add_from_cwd_site_sets_dirty(self): -- cgit v1.2.1 From 7824a2b4c6c53615feb18ff558a8a60b44e8fd41 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Mon, 26 Jan 2015 08:32:27 -0500 Subject: Reference the proper attribute. Fixes #339. --- setuptools/command/easy_install.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 206fc58d..e057b508 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -483,7 +483,7 @@ class easy_install(Command): """).lstrip() def cant_write_to_target(self): - msg = self._cant_write_msg % (sys.exc_info()[1], self.install_dir,) + msg = self.__cant_write_msg % (sys.exc_info()[1], self.install_dir,) if not os.path.exists(self.install_dir): msg += '\n' + self.__not_exists_id -- cgit v1.2.1 From f5098c20ae773bff28ac809a6dea9459f24a27dc Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Mon, 26 Jan 2015 08:35:43 -0500 Subject: Bumped to 12.0.6 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index 8bb69c5f..56d97f7f 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '12.0.5' +__version__ = '12.0.6' -- cgit v1.2.1 From 492758aff46622fb93845f96b9062dab029064f4 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 3 Feb 2015 22:28:29 +0400 Subject: Re-use context available in sandbox. --- setuptools/sandbox.py | 4 +++- setuptools/tests/contexts.py | 8 -------- setuptools/tests/test_easy_install.py | 2 +- 3 files changed, 4 insertions(+), 10 deletions(-) (limited to 'setuptools') diff --git a/setuptools/sandbox.py b/setuptools/sandbox.py index 83283ca3..67255123 100755 --- a/setuptools/sandbox.py +++ b/setuptools/sandbox.py @@ -47,8 +47,10 @@ def _execfile(filename, globals, locals=None): @contextlib.contextmanager -def save_argv(): +def save_argv(repl=None): saved = sys.argv[:] + if repl is not None: + sys.argv[:] = repl try: yield saved finally: diff --git a/setuptools/tests/contexts.py b/setuptools/tests/contexts.py index 4a461765..1d29284b 100644 --- a/setuptools/tests/contexts.py +++ b/setuptools/tests/contexts.py @@ -48,14 +48,6 @@ def environment(**replacements): os.environ.update(saved) -@contextlib.contextmanager -def argv(repl): - old_argv = sys.argv[:] - sys.argv[:] = repl - yield - sys.argv[:] = old_argv - - @contextlib.contextmanager def quiet(): """ diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py index 4331d30e..b9b2e392 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -312,7 +312,7 @@ class TestSetupRequires: '--install-dir', temp_install_dir, dist_file, ] - with contexts.argv(['easy_install']): + with sandbox.save_argv(['easy_install']): # attempt to install the dist. It should fail because # it doesn't exist. with pytest.raises(SystemExit): -- cgit v1.2.1 From 88f62bfe62531bed69f871425d21d8c4e3203ecf Mon Sep 17 00:00:00 2001 From: MinRK Date: Thu, 5 Feb 2015 12:11:23 -0800 Subject: soften normalized version warning indicate that normalization is happening, but don't be pushy about changing valid versions. --HG-- branch : no-normalize-warning --- setuptools/dist.py | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'setuptools') diff --git a/setuptools/dist.py b/setuptools/dist.py index 03d78520..ffbc7c48 100644 --- a/setuptools/dist.py +++ b/setuptools/dist.py @@ -276,6 +276,12 @@ class Distribution(_Distribution): ver = packaging.version.Version(self.metadata.version) normalized_version = str(ver) if self.metadata.version != normalized_version: + warnings.warn( + "Normalizing '%s' to '%s'" % ( + self.metadata.version, + normalized_version, + ) + ) self.metadata.version = normalized_version except (packaging.version.InvalidVersion, TypeError): warnings.warn( -- cgit v1.2.1 From f12a54d83140cb65a7a0098eeb20e469ce7fb5b5 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 10 Feb 2015 20:15:39 -0500 Subject: Bumped to 12.1 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index 56d97f7f..9e9002b4 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '12.0.6' +__version__ = '12.1' -- cgit v1.2.1 From 5d2f77f308c8ccc89be855994da1b7503b5a4294 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 10 Feb 2015 20:17:22 -0500 Subject: Bumped to 12.2 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index 9e9002b4..c59a5777 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '12.1' +__version__ = '12.2' -- cgit v1.2.1 From 582d31e08ea15893f98deddfaa476cd294f1b5db Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Mon, 16 Feb 2015 10:25:13 -0500 Subject: Bumped to 12.3 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index c59a5777..c2fa1dce 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '12.2' +__version__ = '12.3' -- cgit v1.2.1 From 47cbdc5228ca5a730518f1cca83df283c54f7249 Mon Sep 17 00:00:00 2001 From: Arfrever Frehtes Taifersar Arahesis Date: Wed, 18 Feb 2015 20:42:49 +0100 Subject: Fix setuptools.command.easy_install.extract_wininst_cfg() with Python 2.6 and 2.7. It was broken since commit 3bbd42903af8, which changed chr(0) (which is '\x00') into bytes([0]). bytes([0]) is '[0]' in Python 2.6 and 2.7 and b'\x00' in Python 3. --- setuptools/command/easy_install.py | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index e057b508..b039e2da 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -1413,13 +1413,8 @@ def extract_wininst_cfg(dist_filename): {'version': '', 'target_version': ''}) try: part = f.read(cfglen) - # part is in bytes, but we need to read up to the first null - # byte. - if sys.version_info >= (2, 6): - null_byte = bytes([0]) - else: - null_byte = chr(0) - config = part.split(null_byte, 1)[0] + # Read up to the first null byte. + config = part.split(b'\0', 1)[0] # Now the config is in bytes, but for RawConfigParser, it should # be text, so decode it. config = config.decode(sys.getfilesystemencoding()) -- cgit v1.2.1 From b16a6dd269e4fd283a78834c7f379c977aad0f6e Mon Sep 17 00:00:00 2001 From: Arfrever Frehtes Taifersar Arahesis Date: Wed, 18 Feb 2015 21:09:01 +0100 Subject: Delete some dead code. --- setuptools/command/bdist_egg.py | 13 ++----------- setuptools/command/build_py.py | 17 +---------------- 2 files changed, 3 insertions(+), 27 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/bdist_egg.py b/setuptools/command/bdist_egg.py index 34fdeec2..87dce882 100644 --- a/setuptools/command/bdist_egg.py +++ b/setuptools/command/bdist_egg.py @@ -2,7 +2,6 @@ Build .egg distributions""" -# This module should be kept compatible with Python 2.3 from distutils.errors import DistutilsSetupError from distutils.dir_util import remove_tree, mkpath from distutils import log @@ -406,10 +405,6 @@ def scan_module(egg_dir, base, name, stubs): if bad in symbols: log.warn("%s: module MAY be using inspect.%s", module, bad) safe = False - if '__name__' in symbols and '__main__' in symbols and '.' not in module: - if sys.version[:3] == "2.4": # -m works w/zipfiles in 2.5 - log.warn("%s: top-level module may be 'python -m' script", module) - safe = False return safe @@ -441,7 +436,7 @@ INSTALL_DIRECTORY_ATTRS = [ ] -def make_zipfile(zip_filename, base_dir, verbose=0, dry_run=0, compress=None, +def make_zipfile(zip_filename, base_dir, verbose=0, dry_run=0, compress=True, mode='w'): """Create a zip file from all the files under 'base_dir'. The output zip file will be named 'base_dir' + ".zip". Uses either the "zipfile" @@ -463,11 +458,7 @@ def make_zipfile(zip_filename, base_dir, verbose=0, dry_run=0, compress=None, z.write(path, p) log.debug("adding '%s'" % p) - if compress is None: - # avoid 2.3 zipimport bug when 64 bits - compress = (sys.version >= "2.4") - - compression = [zipfile.ZIP_STORED, zipfile.ZIP_DEFLATED][bool(compress)] + compression = zipfile.ZIP_DEFLATED if compress else zipfile.ZIP_STORED if not dry_run: z = zipfile.ZipFile(zip_filename, mode, compression=compression) for dirname, dirs, files in os.walk(base_dir): diff --git a/setuptools/command/build_py.py b/setuptools/command/build_py.py index 98080694..a873d54b 100644 --- a/setuptools/command/build_py.py +++ b/setuptools/command/build_py.py @@ -136,22 +136,7 @@ class build_py(orig.build_py, Mixin2to3): mf.setdefault(src_dirs[d], []).append(path) def get_data_files(self): - pass # kludge 2.4 for lazy computation - - if sys.version < "2.4": # Python 2.4 already has this code - def get_outputs(self, include_bytecode=1): - """Return complete list of files copied to the build directory - - This includes both '.py' files and data files, as well as '.pyc' - and '.pyo' files if 'include_bytecode' is true. (This method is - needed for the 'install_lib' command to do its job properly, and to - generate a correct installation manifest.) - """ - return orig.build_py.get_outputs(self, include_bytecode) + [ - os.path.join(build_dir, filename) - for package, src_dir, build_dir, filenames in self.data_files - for filename in filenames - ] + pass # Lazily compute data files in _get_data_files() function. def check_package(self, package, package_dir): """Check namespace packages' __init__ for declare_namespace""" -- cgit v1.2.1 From f8813bed5e035a4b7f3deba54949439e846c8125 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Thu, 26 Feb 2015 14:16:10 -0500 Subject: Bumped to 12.4 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index c2fa1dce..f64c7985 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '12.3' +__version__ = '12.4' -- cgit v1.2.1 From 7aa02cb6109845a421aabdc366216dacfdf38d33 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 4 Mar 2015 11:09:37 -0500 Subject: Bumped to 12.5 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index f64c7985..e5fc9c8c 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '12.4' +__version__ = '12.5' -- cgit v1.2.1 From 67aa21c88ef5e57d7a2d0f379c970e5987c14cd4 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Thu, 5 Mar 2015 19:51:32 -0500 Subject: Bumped to 13.0 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index e5fc9c8c..0a56eb68 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '12.5' +__version__ = '13.0' -- cgit v1.2.1 From 1914157913c7e28c21ccb8fa5ffe7581721d5bad Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Thu, 5 Mar 2015 20:42:40 -0500 Subject: Bumped to 13.0.1 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index 0a56eb68..d1ff1727 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '13.0' +__version__ = '13.0.1' -- cgit v1.2.1 From 570305131f408b42522d1d7e87292ec752457e65 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Thu, 5 Mar 2015 20:43:59 -0500 Subject: Bumped to 13.0.2 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index d1ff1727..525a47ea 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '13.0.1' +__version__ = '13.0.2' -- cgit v1.2.1 From d138579b07086630732fa949a947dfad34a241d5 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 6 Mar 2015 15:46:27 -0500 Subject: Update test to match new expectation following pull request #109. Refs #285. --- setuptools/tests/test_easy_install.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py index b9b2e392..af09d681 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -156,15 +156,17 @@ class TestUserInstallTest: @mock.patch('setuptools.command.easy_install.__file__', None) def test_user_install_implied(self): + # simulate setuptools installed in user site packages easy_install_pkg.__file__ = site.USER_SITE - site.ENABLE_USER_SITE = True # disabled sometimes - #XXX: replace with something meaningfull + site.ENABLE_USER_SITE = True + + # create a finalized easy_install command dist = Distribution() dist.script_name = 'setup.py' cmd = ei.easy_install(dist) cmd.args = ['py'] cmd.ensure_finalized() - assert cmd.user, 'user should be implied' + assert not cmd.user, 'user should not be implied' def test_multiproc_atexit(self): try: -- cgit v1.2.1 From c05957b09a66c4728c9a578e2e5f33fbd7b97977 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 6 Mar 2015 15:48:40 -0500 Subject: Use pytest.importorskip. --- setuptools/tests/test_easy_install.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py index af09d681..8ba0c49c 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -169,11 +169,7 @@ class TestUserInstallTest: assert not cmd.user, 'user should not be implied' def test_multiproc_atexit(self): - try: - __import__('multiprocessing') - except ImportError: - # skip the test if multiprocessing is not available - return + pytest.importorskip('multiprocessing') log = logging.getLogger('test_easy_install') logging.basicConfig(level=logging.INFO, stream=sys.stderr) -- cgit v1.2.1 From 1ea8018e5c3a8c7c8d980368efc5ac3b81df37e9 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 6 Mar 2015 15:49:04 -0500 Subject: Rename test to reflect implementation. --- setuptools/tests/test_easy_install.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py index 8ba0c49c..36d66428 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -155,7 +155,7 @@ def setup_context(tmpdir): class TestUserInstallTest: @mock.patch('setuptools.command.easy_install.__file__', None) - def test_user_install_implied(self): + def test_user_install_not_implied(self): # simulate setuptools installed in user site packages easy_install_pkg.__file__ = site.USER_SITE site.ENABLE_USER_SITE = True -- cgit v1.2.1 From 55f0838ddfdd301f6f69369f94a3b476b5591b71 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 6 Mar 2015 15:49:46 -0500 Subject: Move related tests into proximity --- setuptools/tests/test_easy_install.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py index 36d66428..2f7b27c5 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -168,13 +168,6 @@ class TestUserInstallTest: cmd.ensure_finalized() assert not cmd.user, 'user should not be implied' - def test_multiproc_atexit(self): - pytest.importorskip('multiprocessing') - - log = logging.getLogger('test_easy_install') - logging.basicConfig(level=logging.INFO, stream=sys.stderr) - log.info('this should not break') - def test_user_install_not_implied_without_usersite_enabled(self): site.ENABLE_USER_SITE = False # usually enabled #XXX: replace with something meaningfull @@ -185,6 +178,13 @@ class TestUserInstallTest: cmd.initialize_options() assert not cmd.user, 'NOT user should be implied' + def test_multiproc_atexit(self): + pytest.importorskip('multiprocessing') + + log = logging.getLogger('test_easy_install') + logging.basicConfig(level=logging.INFO, stream=sys.stderr) + log.info('this should not break') + def test_local_index(self): # make sure the local index is used # when easy_install looks for installed -- cgit v1.2.1 From dc5ad278255437f54f3033e5c526d6f2d1d1f2e5 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 6 Mar 2015 15:51:33 -0500 Subject: Functions now mirror each other. --- setuptools/tests/test_easy_install.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py index 2f7b27c5..ec5d5faa 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -155,7 +155,7 @@ def setup_context(tmpdir): class TestUserInstallTest: @mock.patch('setuptools.command.easy_install.__file__', None) - def test_user_install_not_implied(self): + def test_user_install_not_implied_user_site_enabled(self): # simulate setuptools installed in user site packages easy_install_pkg.__file__ = site.USER_SITE site.ENABLE_USER_SITE = True @@ -168,9 +168,11 @@ class TestUserInstallTest: cmd.ensure_finalized() assert not cmd.user, 'user should not be implied' - def test_user_install_not_implied_without_usersite_enabled(self): - site.ENABLE_USER_SITE = False # usually enabled - #XXX: replace with something meaningfull + def test_user_install_not_implied_user_site_disabled(self): + # ensure user-site not enabled + site.ENABLE_USER_SITE = False + + # create a finalized easy_install command dist = Distribution() dist.script_name = 'setup.py' cmd = ei.easy_install(dist) -- cgit v1.2.1 From 997f97fcf456e9f63664e356e5ed2838e33d4cba Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 6 Mar 2015 15:53:13 -0500 Subject: Extract method for common behavior. --- setuptools/tests/test_easy_install.py | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py index ec5d5faa..eed3bdb5 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -160,25 +160,23 @@ class TestUserInstallTest: easy_install_pkg.__file__ = site.USER_SITE site.ENABLE_USER_SITE = True - # create a finalized easy_install command - dist = Distribution() - dist.script_name = 'setup.py' - cmd = ei.easy_install(dist) - cmd.args = ['py'] - cmd.ensure_finalized() - assert not cmd.user, 'user should not be implied' + self.assert_not_user_site() def test_user_install_not_implied_user_site_disabled(self): # ensure user-site not enabled site.ENABLE_USER_SITE = False + self.assert_not_user_site() + + @staticmethod + def assert_not_user_site(): # create a finalized easy_install command dist = Distribution() dist.script_name = 'setup.py' cmd = ei.easy_install(dist) cmd.args = ['py'] - cmd.initialize_options() - assert not cmd.user, 'NOT user should be implied' + cmd.ensure_finalized() + assert not cmd.user, 'user should not be implied' def test_multiproc_atexit(self): pytest.importorskip('multiprocessing') -- cgit v1.2.1 From 52172aa131f643c83370aa36968fa3f279c53858 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 6 Mar 2015 15:58:03 -0500 Subject: Move patching into the patch methods. --- setuptools/tests/test_easy_install.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py index eed3bdb5..773ca6b6 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -154,18 +154,14 @@ def setup_context(tmpdir): @pytest.mark.usefixtures("setup_context") class TestUserInstallTest: - @mock.patch('setuptools.command.easy_install.__file__', None) + # simulate setuptools installed in user site packages + @mock.patch('setuptools.command.easy_install.__file__', site.USER_SITE) + @mock.patch('site.ENABLE_USER_SITE', True) def test_user_install_not_implied_user_site_enabled(self): - # simulate setuptools installed in user site packages - easy_install_pkg.__file__ = site.USER_SITE - site.ENABLE_USER_SITE = True - self.assert_not_user_site() + @mock.patch('site.ENABLE_USER_SITE', False) def test_user_install_not_implied_user_site_disabled(self): - # ensure user-site not enabled - site.ENABLE_USER_SITE = False - self.assert_not_user_site() @staticmethod -- cgit v1.2.1 From 85dd199e880fdf29a2dbe25bff944b5fc3b1081e Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 6 Mar 2015 16:00:56 -0500 Subject: Replace comment with docstring assertion. --- setuptools/tests/test_easy_install.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py index 773ca6b6..4942acbf 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -182,9 +182,10 @@ class TestUserInstallTest: log.info('this should not break') def test_local_index(self): - # make sure the local index is used - # when easy_install looks for installed - # packages + """ + The local index must be used when easy_install locates installed + packages. + """ new_location = tempfile.mkdtemp() target = tempfile.mkdtemp() egg_file = os.path.join(new_location, 'foo-1.0.egg-info') -- cgit v1.2.1 From ac3e0877123c9cb1a4d53653e273dfb3f1d40ed3 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 6 Mar 2015 16:16:18 -0500 Subject: Extract fixture for foo_package. --- setuptools/tests/test_easy_install.py | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py index 4942acbf..791e3038 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -181,17 +181,19 @@ class TestUserInstallTest: logging.basicConfig(level=logging.INFO, stream=sys.stderr) log.info('this should not break') - def test_local_index(self): + @pytest.fixture() + def foo_package(self, tmpdir): + egg_file = tmpdir / 'foo-1.0.egg-info' + with egg_file.open('w') as f: + f.write('Name: foo\n') + return str(tmpdir) + + def test_local_index(self, foo_package): """ The local index must be used when easy_install locates installed packages. """ - new_location = tempfile.mkdtemp() target = tempfile.mkdtemp() - egg_file = os.path.join(new_location, 'foo-1.0.egg-info') - with open(egg_file, 'w') as f: - f.write('Name: foo\n') - sys.path.append(target) old_ppath = os.environ.get('PYTHONPATH') os.environ['PYTHONPATH'] = os.path.pathsep.join(sys.path) @@ -202,14 +204,14 @@ class TestUserInstallTest: cmd.install_dir = target cmd.args = ['foo'] cmd.ensure_finalized() - cmd.local_index.scan([new_location]) + cmd.local_index.scan([foo_package]) res = cmd.easy_install('foo') actual = os.path.normcase(os.path.realpath(res.location)) - expected = os.path.normcase(os.path.realpath(new_location)) + expected = os.path.normcase(os.path.realpath(foo_package)) assert actual == expected finally: sys.path.remove(target) - for basedir in [new_location, target, ]: + for basedir in [target, ]: if not os.path.exists(basedir) or not os.path.isdir(basedir): continue try: -- cgit v1.2.1 From a2719779b6604634f87aed64cf4413486ccca88c Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 6 Mar 2015 16:19:57 -0500 Subject: Extract install_target as fixture --- setuptools/tests/test_easy_install.py | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py index 791e3038..1acf08b5 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -188,20 +188,23 @@ class TestUserInstallTest: f.write('Name: foo\n') return str(tmpdir) - def test_local_index(self, foo_package): + @pytest.fixture() + def install_target(self, tmpdir): + return str(tmpdir) + + def test_local_index(self, foo_package, install_target): """ The local index must be used when easy_install locates installed packages. """ - target = tempfile.mkdtemp() - sys.path.append(target) + sys.path.append(install_target) old_ppath = os.environ.get('PYTHONPATH') os.environ['PYTHONPATH'] = os.path.pathsep.join(sys.path) try: dist = Distribution() dist.script_name = 'setup.py' cmd = ei.easy_install(dist) - cmd.install_dir = target + cmd.install_dir = install_target cmd.args = ['foo'] cmd.ensure_finalized() cmd.local_index.scan([foo_package]) @@ -210,14 +213,7 @@ class TestUserInstallTest: expected = os.path.normcase(os.path.realpath(foo_package)) assert actual == expected finally: - sys.path.remove(target) - for basedir in [target, ]: - if not os.path.exists(basedir) or not os.path.isdir(basedir): - continue - try: - shutil.rmtree(basedir) - except: - pass + sys.path.remove(install_target) if old_ppath is not None: os.environ['PYTHONPATH'] = old_ppath else: -- cgit v1.2.1 From c3b4d4bc997f71943b29bb8dccbdfcbc72bd7488 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 6 Mar 2015 16:33:25 -0500 Subject: Extract sys.path and os.environ patching into install_target fixture --- setuptools/tests/test_easy_install.py | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py index 1acf08b5..6e2b25dd 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -188,18 +188,19 @@ class TestUserInstallTest: f.write('Name: foo\n') return str(tmpdir) - @pytest.fixture() + @pytest.yield_fixture() def install_target(self, tmpdir): - return str(tmpdir) + target = str(tmpdir) + with mock.patch('sys.path', sys.path + [target]): + python_path = os.path.pathsep.join(sys.path) + with mock.patch.dict(os.environ, PYTHONPATH=python_path): + yield target def test_local_index(self, foo_package, install_target): """ The local index must be used when easy_install locates installed packages. """ - sys.path.append(install_target) - old_ppath = os.environ.get('PYTHONPATH') - os.environ['PYTHONPATH'] = os.path.pathsep.join(sys.path) try: dist = Distribution() dist.script_name = 'setup.py' @@ -213,11 +214,7 @@ class TestUserInstallTest: expected = os.path.normcase(os.path.realpath(foo_package)) assert actual == expected finally: - sys.path.remove(install_target) - if old_ppath is not None: - os.environ['PYTHONPATH'] = old_ppath - else: - del os.environ['PYTHONPATH'] + pass @contextlib.contextmanager def user_install_setup_context(self, *args, **kwargs): -- cgit v1.2.1 From 427b3bf0f2ddc07cc01637605277ca555d5b26ce Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 6 Mar 2015 16:34:34 -0500 Subject: Remove unnecessary block --- setuptools/tests/test_easy_install.py | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py index 6e2b25dd..7d61fb83 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -201,20 +201,17 @@ class TestUserInstallTest: The local index must be used when easy_install locates installed packages. """ - try: - dist = Distribution() - dist.script_name = 'setup.py' - cmd = ei.easy_install(dist) - cmd.install_dir = install_target - cmd.args = ['foo'] - cmd.ensure_finalized() - cmd.local_index.scan([foo_package]) - res = cmd.easy_install('foo') - actual = os.path.normcase(os.path.realpath(res.location)) - expected = os.path.normcase(os.path.realpath(foo_package)) - assert actual == expected - finally: - pass + dist = Distribution() + dist.script_name = 'setup.py' + cmd = ei.easy_install(dist) + cmd.install_dir = install_target + cmd.args = ['foo'] + cmd.ensure_finalized() + cmd.local_index.scan([foo_package]) + res = cmd.easy_install('foo') + actual = os.path.normcase(os.path.realpath(res.location)) + expected = os.path.normcase(os.path.realpath(foo_package)) + assert actual == expected @contextlib.contextmanager def user_install_setup_context(self, *args, **kwargs): -- cgit v1.2.1 From adbfaa73e54eef2a24673f49995c933eb0f88adf Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 6 Mar 2015 17:30:09 -0500 Subject: Bumped to 14.0 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index 525a47ea..7720175d 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '13.0.2' +__version__ = '14.0' -- cgit v1.2.1 From 45bf0df21a53809a891ea5bb45e5407a2ebb5e02 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 6 Mar 2015 17:30:46 -0500 Subject: Bumped to 14.1 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index 7720175d..2ac79c23 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '14.0' +__version__ = '14.1' -- cgit v1.2.1 From ab794ef306bcbe88c1fde6439ed02f889487c239 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 6 Mar 2015 22:59:39 -0500 Subject: Use filter(None) for brevity --- setuptools/command/easy_install.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 4e841520..81573fea 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -435,7 +435,7 @@ class easy_install(Command): self.pth_file = None PYTHONPATH = os.environ.get('PYTHONPATH', '').split(os.pathsep) - if instdir not in map(normalize_path, [_f for _f in PYTHONPATH if _f]): + if instdir not in map(normalize_path, filter(None, PYTHONPATH)): # only PYTHONPATH dirs need a site.py, so pretend it's there self.sitepy_installed = True elif self.multi_version and not os.path.exists(pth_file): -- cgit v1.2.1 From 275336b8fb9171ba8bf7a7114a2d6ae41993848b Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 6 Mar 2015 23:11:45 -0500 Subject: Remove comment that references a setup command, but even at the time it was committed, it's not duplicate code from anything in setuptools, and I'm unaware of what a setup command is. --- setuptools/command/easy_install.py | 1 - 1 file changed, 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 81573fea..c9e61d13 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -238,7 +238,6 @@ class easy_install(Command): self.config_vars['usersite'] = self.install_usersite # fix the install_dir if "--user" was used - # XXX: duplicate of the code in the setup command if self.user and site.ENABLE_USER_SITE: self.create_home_path() if self.install_userbase is None: -- cgit v1.2.1 From 126161426c858f6b3e73a330086d9bb0d2995a12 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 6 Mar 2015 23:16:27 -0500 Subject: Calculate scheme name directly. --- setuptools/command/easy_install.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index c9e61d13..c35ae16c 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -244,10 +244,8 @@ class easy_install(Command): raise DistutilsPlatformError( "User base directory is not specified") self.install_base = self.install_platbase = self.install_userbase - if os.name == 'posix': - self.select_scheme("unix_user") - else: - self.select_scheme(os.name + "_user") + scheme_name = os.name.replace('posix', 'unix') + '_user' + self.select_scheme(scheme_name) self.expand_basedirs() self.expand_dirs() -- cgit v1.2.1 From 3a8d4728cbc3080a7a816f87dc20efafae6e28e5 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 6 Mar 2015 23:19:23 -0500 Subject: Extract method for fixing install dir --- setuptools/command/easy_install.py | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index c35ae16c..872f6bb8 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -237,15 +237,7 @@ class easy_install(Command): self.config_vars['userbase'] = self.install_userbase self.config_vars['usersite'] = self.install_usersite - # fix the install_dir if "--user" was used - if self.user and site.ENABLE_USER_SITE: - self.create_home_path() - if self.install_userbase is None: - raise DistutilsPlatformError( - "User base directory is not specified") - self.install_base = self.install_platbase = self.install_userbase - scheme_name = os.name.replace('posix', 'unix') + '_user' - self.select_scheme(scheme_name) + self._fix_install_dir_for_user_site() self.expand_basedirs() self.expand_dirs() @@ -340,6 +332,19 @@ class easy_install(Command): self.outputs = [] + def _fix_install_dir_for_user_site(self): + """ + Fix the install_dir if "--user" was used. + """ + if self.user and site.ENABLE_USER_SITE: + self.create_home_path() + if self.install_userbase is None: + raise DistutilsPlatformError( + "User base directory is not specified") + self.install_base = self.install_platbase = self.install_userbase + scheme_name = os.name.replace('posix', 'unix') + '_user' + self.select_scheme(scheme_name) + def _expand_attrs(self, attrs): for attr in attrs: val = getattr(self, attr) -- cgit v1.2.1 From 727f1668fc61f74867cc0cfdfabdd6d23699a6d9 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 6 Mar 2015 23:21:01 -0500 Subject: Use short circuit instead of nesting functionality. --- setuptools/command/easy_install.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 872f6bb8..efe5f68b 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -336,14 +336,16 @@ class easy_install(Command): """ Fix the install_dir if "--user" was used. """ - if self.user and site.ENABLE_USER_SITE: - self.create_home_path() - if self.install_userbase is None: - raise DistutilsPlatformError( - "User base directory is not specified") - self.install_base = self.install_platbase = self.install_userbase - scheme_name = os.name.replace('posix', 'unix') + '_user' - self.select_scheme(scheme_name) + if not self.user or not site.ENABLE_USER_SITE: + return + + self.create_home_path() + if self.install_userbase is None: + raise DistutilsPlatformError( + "User base directory is not specified") + self.install_base = self.install_platbase = self.install_userbase + scheme_name = os.name.replace('posix', 'unix') + '_user' + self.select_scheme(scheme_name) def _expand_attrs(self, attrs): for attr in attrs: -- cgit v1.2.1 From f922da30d3d4d6ef6ac99f65509cf243dcce1ea4 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 6 Mar 2015 23:22:40 -0500 Subject: Extract variable for error message. --- setuptools/command/easy_install.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index efe5f68b..9f480f05 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -341,8 +341,8 @@ class easy_install(Command): self.create_home_path() if self.install_userbase is None: - raise DistutilsPlatformError( - "User base directory is not specified") + msg = "User base directory is not specified" + raise DistutilsPlatformError(msg) self.install_base = self.install_platbase = self.install_userbase scheme_name = os.name.replace('posix', 'unix') + '_user' self.select_scheme(scheme_name) -- cgit v1.2.1 From 537c16561318df78f1a512101d0eca1b0593616e Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 6 Mar 2015 23:29:47 -0500 Subject: Filter blockers in the iterable --- setuptools/command/easy_install.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 9f480f05..531ac8ff 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -200,8 +200,11 @@ class easy_install(Command): ) def delete_blockers(self, blockers): - for filename in blockers: - if os.path.exists(filename) or os.path.islink(filename): + extant_blockers = ( + filename for filename in blockers + if os.path.exists(filename) or os.path.islink(filename) + ) + for filename in extant_blockers: log.info("Deleting %s", filename) if not self.dry_run: if (os.path.isdir(filename) and -- cgit v1.2.1 From f9fd181f25d50bd149c715c7ac52827da34d0e59 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 6 Mar 2015 23:31:49 -0500 Subject: Extract method for filename deletion. --- setuptools/command/easy_install.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 531ac8ff..01c67ccc 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -204,7 +204,9 @@ class easy_install(Command): filename for filename in blockers if os.path.exists(filename) or os.path.islink(filename) ) - for filename in extant_blockers: + list(map(self._delete_filename, extant_blockers)) + + def _delete_filename(self, filename): log.info("Deleting %s", filename) if not self.dry_run: if (os.path.isdir(filename) and -- cgit v1.2.1 From 7ab342a1ed684563ee7742fc3f7fd04fac5b7fc2 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 6 Mar 2015 23:35:27 -0500 Subject: Remove excess indent --- setuptools/command/easy_install.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 01c67ccc..7dbbc878 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -207,13 +207,13 @@ class easy_install(Command): list(map(self._delete_filename, extant_blockers)) def _delete_filename(self, filename): - log.info("Deleting %s", filename) - if not self.dry_run: - if (os.path.isdir(filename) and - not os.path.islink(filename)): - rmtree(filename) - else: - os.unlink(filename) + log.info("Deleting %s", filename) + if not self.dry_run: + if (os.path.isdir(filename) and + not os.path.islink(filename)): + rmtree(filename) + else: + os.unlink(filename) def finalize_options(self): if self.version: -- cgit v1.2.1 From e4fe5c76f89d0249ff7035a38795fa5ae1e38f09 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 6 Mar 2015 23:36:10 -0500 Subject: Short circuit on dry run --- setuptools/command/easy_install.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 7dbbc878..7f360e05 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -208,12 +208,14 @@ class easy_install(Command): def _delete_filename(self, filename): log.info("Deleting %s", filename) - if not self.dry_run: - if (os.path.isdir(filename) and - not os.path.islink(filename)): - rmtree(filename) - else: - os.unlink(filename) + if self.dry_run: + return + + if (os.path.isdir(filename) and + not os.path.islink(filename)): + rmtree(filename) + else: + os.unlink(filename) def finalize_options(self): if self.version: -- cgit v1.2.1 From 16060fd91b26126c6f1fce2c1dba4a79cf85177e Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 6 Mar 2015 23:36:45 -0500 Subject: Extract variable for is_tree --- setuptools/command/easy_install.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 7f360e05..bf380f13 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -211,8 +211,8 @@ class easy_install(Command): if self.dry_run: return - if (os.path.isdir(filename) and - not os.path.islink(filename)): + is_tree = os.path.isdir(filename) and not os.path.islink(filename) + if is_tree: rmtree(filename) else: os.unlink(filename) -- cgit v1.2.1 From 16a4240286b5202e2a52c22efb63fc3c1ba7ab02 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 6 Mar 2015 23:39:36 -0500 Subject: More concisely describe the removal. --- setuptools/command/easy_install.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index bf380f13..0828be84 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -212,10 +212,8 @@ class easy_install(Command): return is_tree = os.path.isdir(filename) and not os.path.islink(filename) - if is_tree: - rmtree(filename) - else: - os.unlink(filename) + remover = rmtree if is_tree else os.unlink + remover(filename) def finalize_options(self): if self.version: -- cgit v1.2.1 From cbc3c959feecae75c1ce7864543c7f3a14b65ab0 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 6 Mar 2015 23:40:47 -0500 Subject: Use 'path' to describe a file or directory. --- setuptools/command/easy_install.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 0828be84..276b6f99 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -204,16 +204,16 @@ class easy_install(Command): filename for filename in blockers if os.path.exists(filename) or os.path.islink(filename) ) - list(map(self._delete_filename, extant_blockers)) + list(map(self._delete_path, extant_blockers)) - def _delete_filename(self, filename): - log.info("Deleting %s", filename) + def _delete_path(self, path): + log.info("Deleting %s", path) if self.dry_run: return - is_tree = os.path.isdir(filename) and not os.path.islink(filename) + is_tree = os.path.isdir(path) and not os.path.islink(path) remover = rmtree if is_tree else os.unlink - remover(filename) + remover(path) def finalize_options(self): if self.version: -- cgit v1.2.1 From 09c966b75de843ec24c6fbababdc19772b24268d Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 14 Mar 2015 21:31:50 -0400 Subject: Bumped to 14.2 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index 2ac79c23..a52fd832 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '14.1' +__version__ = '14.2' -- cgit v1.2.1 From 1919a4358eebcfd48e24756e0bb68035e8750800 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 14 Mar 2015 22:09:26 -0400 Subject: Remove regression test for Distribute issue #318. The continuing relevance of this test is questionnaible, given that user installs of setuptools no longer imply user installs of other packages. Ref #360. --- setuptools/tests/test_easy_install.py | 20 -------------------- 1 file changed, 20 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py index 7d61fb83..c5714998 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -232,26 +232,6 @@ class TestUserInstallTest: self.user_install_setup_context, ) - def test_setup_requires(self): - """Regression test for Distribute issue #318 - - Ensure that a package with setup_requires can be installed when - setuptools is installed in the user site-packages without causing a - SandboxViolation. - """ - - test_pkg = create_setup_requires_package(os.getcwd()) - test_setup_py = os.path.join(test_pkg, 'setup.py') - - try: - with contexts.quiet(): - with self.patched_setup_context(): - run_setup(test_setup_py, ['install']) - except IndexError: - # Test fails in some cases due to bugs in Python - # See https://bitbucket.org/pypa/setuptools/issue/201 - pass - @pytest.yield_fixture def distutils_package(): -- cgit v1.2.1 From 24b1723a48ef5ba95afeabf96f8021b939d8391a Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 14 Mar 2015 22:40:27 -0400 Subject: Bypass the checking of site-packages when asserting not user install in site-packages. Fixes #360. --- setuptools/tests/test_easy_install.py | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'setuptools') diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py index c5714998..e71bbfc9 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -154,13 +154,23 @@ def setup_context(tmpdir): @pytest.mark.usefixtures("setup_context") class TestUserInstallTest: + # prevent check that site-packages is writable. easy_install + # shouldn't be writing to system site-packages during finalize + # options, but while it does, bypass the behavior. + prev_sp_write = mock.patch( + 'setuptools.command.easy_install.easy_install.check_site_dir', + mock.Mock(), + ) + # simulate setuptools installed in user site packages @mock.patch('setuptools.command.easy_install.__file__', site.USER_SITE) @mock.patch('site.ENABLE_USER_SITE', True) + @prev_sp_write def test_user_install_not_implied_user_site_enabled(self): self.assert_not_user_site() @mock.patch('site.ENABLE_USER_SITE', False) + @prev_sp_write def test_user_install_not_implied_user_site_disabled(self): self.assert_not_user_site() -- cgit v1.2.1 From aba25cd363c6f7dc9469f00a1c56ef8f4ffc6f17 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 14 Mar 2015 22:44:48 -0400 Subject: Bumped to 14.1.1 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index a52fd832..8800c207 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '14.2' +__version__ = '14.1.1' -- cgit v1.2.1 From 0e0db0408fbcbb0a0a6de45a70dca32f5d91170b Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 14 Mar 2015 22:45:30 -0400 Subject: Bumped to 14.1.2 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index 8800c207..134b5685 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '14.1.1' +__version__ = '14.1.2' -- cgit v1.2.1 From 6301007c244531948add7852db54045e9c3a11ce Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 15 Mar 2015 08:18:41 -0400 Subject: Bumped to 14.2 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index 134b5685..a52fd832 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '14.1.2' +__version__ = '14.2' -- cgit v1.2.1 From 6d69e5a0d777c6a564ec32f9b726da64f2a5ad9c Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 15 Mar 2015 08:19:20 -0400 Subject: Bumped to 14.3 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index a52fd832..89a024f0 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '14.2' +__version__ = '14.3' -- cgit v1.2.1 From 1581c8404e12f32190d3bc29825b9910a46f2347 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 15 Mar 2015 09:47:40 -0400 Subject: Bumped to 14.4 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index 89a024f0..5b9a2bc6 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '14.3' +__version__ = '14.4' -- cgit v1.2.1 From 3ff70513dceb10287c79ca9eb902e42b74f3e55f Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Thu, 19 Mar 2015 14:10:49 -0400 Subject: Replace deprecated usage with preferred usage. Fixes #364. --- setuptools/command/egg_info.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/command/egg_info.py b/setuptools/command/egg_info.py index a9940677..50f3d5c0 100755 --- a/setuptools/command/egg_info.py +++ b/setuptools/command/egg_info.py @@ -168,7 +168,8 @@ class egg_info(Command): self.mkpath(self.egg_info) installer = self.distribution.fetch_build_egg for ep in iter_entry_points('egg_info.writers'): - writer = ep.load(installer=installer) + ep.require(installer=installer) + writer = ep.resolve() writer(self, ep.name, os.path.join(self.egg_info, ep.name)) # Get rid of native_libs.txt if it was put there by older bdist_egg -- cgit v1.2.1 From a631a0700d2ebcc9ee98c91d474f351974cc0b92 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 20 Mar 2015 13:30:51 -0400 Subject: Match Python 3 for bdist_dumb. --- setuptools/package_index.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'setuptools') diff --git a/setuptools/package_index.py b/setuptools/package_index.py index 5ed19130..963b4b41 100755 --- a/setuptools/package_index.py +++ b/setuptools/package_index.py @@ -140,8 +140,9 @@ def interpret_distro_name( parts = basename.split('-') if not py_version: for i,p in enumerate(parts[2:]): - if len(p)==5 and p.startswith('py2.'): - return # It's a bdist_dumb, not an sdist -- bail out + if p.match('py\d\.\d'): + # It's a bdist_dumb, not an sdist -- bail out + return for p in range(1,len(parts)+1): yield Distribution( -- cgit v1.2.1 From 00477b5b3e1f42b5ad9cdc553652e04beb675dbb Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 20 Mar 2015 13:31:38 -0400 Subject: Remove unused variable --- setuptools/package_index.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/package_index.py b/setuptools/package_index.py index 963b4b41..c117cb62 100755 --- a/setuptools/package_index.py +++ b/setuptools/package_index.py @@ -139,7 +139,7 @@ def interpret_distro_name( parts = basename.split('-') if not py_version: - for i,p in enumerate(parts[2:]): + for p in parts[2:]: if p.match('py\d\.\d'): # It's a bdist_dumb, not an sdist -- bail out return -- cgit v1.2.1 From edf097e299d4382700f819288cb08390c53e109d Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 20 Mar 2015 13:34:15 -0400 Subject: Flat is better than nested. --- setuptools/package_index.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'setuptools') diff --git a/setuptools/package_index.py b/setuptools/package_index.py index c117cb62..51769cdf 100755 --- a/setuptools/package_index.py +++ b/setuptools/package_index.py @@ -138,11 +138,9 @@ def interpret_distro_name( # versions in distribution archive names (sdist and bdist). parts = basename.split('-') - if not py_version: - for p in parts[2:]: - if p.match('py\d\.\d'): - # It's a bdist_dumb, not an sdist -- bail out - return + if not py_version and any(p.match('py\d\.\d') for p in parts[2:]): + # it is a bdist_dumb, not an sdist -- bail out + return for p in range(1,len(parts)+1): yield Distribution( -- cgit v1.2.1 From 01bb6e0e9217255cd835cefb8162463dac5d8e6d Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 20 Mar 2015 15:58:37 -0400 Subject: Correct regex usage --- setuptools/package_index.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/package_index.py b/setuptools/package_index.py index 963b4b41..95eb1cf3 100755 --- a/setuptools/package_index.py +++ b/setuptools/package_index.py @@ -140,7 +140,7 @@ def interpret_distro_name( parts = basename.split('-') if not py_version: for i,p in enumerate(parts[2:]): - if p.match('py\d\.\d'): + if re.match('py\d\.\d$', p): # It's a bdist_dumb, not an sdist -- bail out return -- cgit v1.2.1 From fcb4bf6759c8fa674d749f2129f833195cd50431 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 20 Mar 2015 16:08:27 -0400 Subject: Bumped to 14.3.1 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index 5b9a2bc6..5fed68f1 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '14.4' +__version__ = '14.3.1' -- cgit v1.2.1 From f0b26583b2abdfba057dc199d31701497ad894c1 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 20 Mar 2015 16:09:13 -0400 Subject: Bumped to 14.3.2 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index 5fed68f1..a2f34e92 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '14.3.1' +__version__ = '14.3.2' -- cgit v1.2.1 From e1f0b4019be6efa9c20f0f0dae13009f071ff2a0 Mon Sep 17 00:00:00 2001 From: Marc Abramowitz Date: Tue, 24 Mar 2015 08:20:42 -0700 Subject: DistributionNotFound: Move message template to class --HG-- branch : DistributionNotFound_list_requirers --- setuptools/command/easy_install.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 276b6f99..f2bfa68d 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -709,9 +709,7 @@ class easy_install(Command): [requirement], self.local_index, self.easy_install ) except DistributionNotFound as e: - raise DistutilsError( - "Could not find required distribution %s" % e.args - ) + raise DistutilsError(str(e)) except VersionConflict as e: raise DistutilsError(e.report()) if self.always_copy or self.always_copy_from: -- cgit v1.2.1 From 9a33ea35df1a77e721ebeb1700acaa74ca28a430 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 28 Mar 2015 11:07:10 -0400 Subject: Bumped to 15.0 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index a2f34e92..60d8514e 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '14.3.2' +__version__ = '15.0' -- cgit v1.2.1 From 933e26cd75231ba6402c38e4044e001a5d47fa3f Mon Sep 17 00:00:00 2001 From: Arfrever Frehtes Taifersar Arahesis Date: Mon, 30 Mar 2015 03:40:43 +0200 Subject: Fix some typos. --- setuptools/command/easy_install.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index f2bfa68d..74803b59 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -152,7 +152,7 @@ class easy_install(Command): create_index = PackageIndex def initialize_options(self): - # the --user option seemst to be an opt-in one, + # the --user option seems to be an opt-in one, # so the default should be False. self.user = 0 self.zip_ok = self.local_snapshots_ok = None -- cgit v1.2.1 From 8fe7605a2787648a23c28741e20ba403e95a357b Mon Sep 17 00:00:00 2001 From: Arfrever Frehtes Taifersar Arahesis Date: Mon, 30 Mar 2015 04:26:56 +0200 Subject: Fix setuptools.sandbox._execfile() with Python 3.1. It fixes failure of setuptools.tests.test_sandbox.TestSandbox.test_setup_py_with_CRLF() with Python 3.1. --- setuptools/sandbox.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'setuptools') diff --git a/setuptools/sandbox.py b/setuptools/sandbox.py index 67255123..31e3eb2d 100755 --- a/setuptools/sandbox.py +++ b/setuptools/sandbox.py @@ -34,12 +34,12 @@ def _execfile(filename, globals, locals=None): Python 3 implementation of execfile. """ mode = 'rb' - # Python 2.6 compile requires LF for newlines, so use deprecated - # Universal newlines support. - if sys.version_info < (2, 7): - mode += 'U' with open(filename, mode) as stream: script = stream.read() + # compile() function in Python 2.6 and 3.1 requires LF line endings. + if sys.version_info[:2] < (2, 7) or sys.version_info[:2] >= (3, 0) and sys.version_info[:2] < (3, 2): + script = script.replace(b'\r\n', b'\n') + script = script.replace(b'\r', b'\n') if locals is None: locals = globals code = compile(script, filename, 'exec') -- cgit v1.2.1 From 56e49ec7d8b1c9fd7f2c36d041a87bb756baa2a3 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 3 Apr 2015 18:26:41 -0400 Subject: Bumped to 15.1 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index 60d8514e..1b29a7b4 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '15.0' +__version__ = '15.1' -- cgit v1.2.1 From 82d003629ef23fd7f0dc2fb71d5edc937271ffd8 Mon Sep 17 00:00:00 2001 From: Thomas Bechtold Date: Sun, 5 Apr 2015 08:39:18 +0200 Subject: Fix TypeError for pytest.skip() pytests skip() method doesn't have a 'reason' parameter. This fixes: TypeError: skip() got an unexpected keyword argument 'reason' --HG-- branch : fix-type-error-skip-reason --- setuptools/tests/test_integration.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_integration.py b/setuptools/tests/test_integration.py index 90bb4313..07f06db2 100644 --- a/setuptools/tests/test_integration.py +++ b/setuptools/tests/test_integration.py @@ -28,7 +28,7 @@ def setup_module(module): try: urlopen('https://pypi.python.org/pypi') except Exception as exc: - pytest.skip(reason=str(exc)) + pytest.skip(str(exc)) @pytest.fixture -- cgit v1.2.1 From c2cc7435a96775ef4cd018930fdd83b8ba1dd45d Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 15 Apr 2015 09:17:24 -0400 Subject: Bumped to 15.2 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index 1b29a7b4..2771d939 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '15.1' +__version__ = '15.2' -- cgit v1.2.1 From 2039b2aeba48685275bd2b341bf69d3f3f63786b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Gr=C3=B6nholm?= Date: Tue, 21 Apr 2015 22:24:09 +0300 Subject: Check for Jython using sys.platform, not os.name --- setuptools/sandbox.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/sandbox.py b/setuptools/sandbox.py index 31e3eb2d..213cebff 100755 --- a/setuptools/sandbox.py +++ b/setuptools/sandbox.py @@ -10,7 +10,7 @@ import pickle import pkg_resources -if os.name == "java": +if sys.platform.startswith('java'): import org.python.modules.posix.PosixModule as _os else: _os = sys.modules[os.name] -- cgit v1.2.1 From 42c62a7a344e2139f285c571930d179866167bd5 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 26 Apr 2015 11:02:44 -0400 Subject: Bumped to 15.3 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index 2771d939..f0d1b4d4 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '15.2' +__version__ = '15.3' -- cgit v1.2.1 From 33544f0bf806d73495b00b9f8a0e45c25742fbc1 Mon Sep 17 00:00:00 2001 From: Marc Abramowitz Date: Fri, 1 May 2015 08:23:57 -0700 Subject: Nicer error when problem in install_requires Instead of: $ python setup.py egg_info error in adminweb setup command: 'install_requires' must be a string or list of strings containing valid project/version requirement specifiers We now have the more helpful: $ python setup.py egg_info error in adminweb setup command: 'install_requires' must be a string or list of strings containing valid project/version requirement specifiers. Error: Expected version spec in smsdk.authsvc>=0.0.8,2.0 at 2.0 It took me longer than it should to find the problem with the old error message. The new error message would've helped greatly. --- setuptools/dist.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'setuptools') diff --git a/setuptools/dist.py b/setuptools/dist.py index ffbc7c48..220bcf8c 100644 --- a/setuptools/dist.py +++ b/setuptools/dist.py @@ -122,11 +122,15 @@ def check_requirements(dist, attr, value): """Verify that install_requires is a valid requirements list""" try: list(pkg_resources.parse_requirements(value)) - except (TypeError,ValueError): + except (TypeError, ValueError) as e: raise DistutilsSetupError( "%r must be a string or list of strings " - "containing valid project/version requirement specifiers" % (attr,) + "containing valid project/version requirement specifiers.\n" + "Error: %s" + % (attr, ' '.join(e.args)) ) + + def check_entry_points(dist, attr, value): """Verify that entry_points map is parseable""" try: -- cgit v1.2.1 From fb27525a41a3f941aac906564d144d7177d35a79 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 3 May 2015 11:59:38 -0400 Subject: Let the exception render itself. --- setuptools/dist.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'setuptools') diff --git a/setuptools/dist.py b/setuptools/dist.py index 220bcf8c..892044dd 100644 --- a/setuptools/dist.py +++ b/setuptools/dist.py @@ -126,8 +126,8 @@ def check_requirements(dist, attr, value): raise DistutilsSetupError( "%r must be a string or list of strings " "containing valid project/version requirement specifiers.\n" - "Error: %s" - % (attr, ' '.join(e.args)) + "%s" + % (attr, e) ) -- cgit v1.2.1 From 95a68afdf62f63e044f600ab87a4410db6bdf128 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 3 May 2015 12:34:02 -0400 Subject: Render the error message as a single line without a period (for consistency with other usage). --- setuptools/dist.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'setuptools') diff --git a/setuptools/dist.py b/setuptools/dist.py index 892044dd..05669366 100644 --- a/setuptools/dist.py +++ b/setuptools/dist.py @@ -123,13 +123,11 @@ def check_requirements(dist, attr, value): try: list(pkg_resources.parse_requirements(value)) except (TypeError, ValueError) as e: - raise DistutilsSetupError( + tmpl = ( "%r must be a string or list of strings " - "containing valid project/version requirement specifiers.\n" - "%s" - % (attr, e) + "containing valid project/version requirement specifiers; %s" ) - + raise DistutilsSetupError(tmpl % (attr, e)) def check_entry_points(dist, attr, value): """Verify that entry_points map is parseable""" -- cgit v1.2.1 From 0cc8362038f6feb3ede00ee9ce8ba8c7d04940d9 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 3 May 2015 12:39:16 -0400 Subject: Use new string formatting --- setuptools/dist.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'setuptools') diff --git a/setuptools/dist.py b/setuptools/dist.py index 05669366..d7ad4655 100644 --- a/setuptools/dist.py +++ b/setuptools/dist.py @@ -115,19 +115,20 @@ def check_extras(dist, attr, value): def assert_bool(dist, attr, value): """Verify that value is True, False, 0, or 1""" if bool(value) != value: - raise DistutilsSetupError( - "%r must be a boolean value (got %r)" % (attr,value) - ) + tmpl = "{attr!r} must be a boolean value (got {value!r})" + raise DistutilsSetupError(tmpl.format(attr=attr, value=value)) + + def check_requirements(dist, attr, value): """Verify that install_requires is a valid requirements list""" try: list(pkg_resources.parse_requirements(value)) - except (TypeError, ValueError) as e: + except (TypeError, ValueError) as error: tmpl = ( - "%r must be a string or list of strings " - "containing valid project/version requirement specifiers; %s" + "{attr!r} must be a string or list of strings " + "containing valid project/version requirement specifiers; {error}" ) - raise DistutilsSetupError(tmpl % (attr, e)) + raise DistutilsSetupError(tmpl.format(attr=attr, error=error)) def check_entry_points(dist, attr, value): """Verify that entry_points map is parseable""" -- cgit v1.2.1 From c7a68c40760615084c2f3cd4db4158cd248af3aa Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Mon, 18 May 2015 15:07:22 +0800 Subject: Bumped to 16.0 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index f0d1b4d4..fd4afc5a 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '15.3' +__version__ = '16.0' -- cgit v1.2.1 From 1f7177fc0f54fac1d76ee8a1c77f93cb2f6f7dc1 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Mon, 18 May 2015 15:09:52 +0800 Subject: Bumped to 16.1 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index fd4afc5a..aeccd8e3 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '16.0' +__version__ = '16.1' -- cgit v1.2.1 From 16da5eac3a04bc4224082ee54f5f0f5b1c8d92db Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 27 May 2015 18:12:23 -0400 Subject: extract variable for nicer indentation --- setuptools/command/easy_install.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 74803b59..515c89d5 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -2024,8 +2024,8 @@ class ScriptWriter(object): group = type_ + '_scripts' for name, ep in dist.get_entry_map(group).items(): script_text = cls.template % locals() - for res in cls._get_script_args(type_, name, header, - script_text): + args = cls._get_script_args(type_, name, header, script_text) + for res in args: yield res @classmethod -- cgit v1.2.1 From 7ee56c5270d979f73c248c3ef5bac48793cd77d6 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 27 May 2015 18:14:16 -0400 Subject: Update docstring to include the actual entry point names (for hits when grepping). --- setuptools/command/easy_install.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 515c89d5..2c127126 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -2015,7 +2015,8 @@ class ScriptWriter(object): @classmethod def get_args(cls, dist, header=None): """ - Yield write_script() argument tuples for a distribution's entrypoints + Yield write_script() argument tuples for a distribution's + console_scripts and gui_scripts entry points. """ if header is None: header = cls.get_header() -- cgit v1.2.1 From b2847255769f7e40fa757c830020cb2daad7860d Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 27 May 2015 18:40:01 -0400 Subject: Disallow path separators in script names. Fixes #390 --- setuptools/command/easy_install.py | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 2c127126..1b32b1c8 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -2024,11 +2024,21 @@ class ScriptWriter(object): for type_ in 'console', 'gui': group = type_ + '_scripts' for name, ep in dist.get_entry_map(group).items(): + cls._ensure_safe_name(name) script_text = cls.template % locals() args = cls._get_script_args(type_, name, header, script_text) for res in args: yield res + @staticmethod + def _ensure_safe_name(name): + """ + Prevent paths in *_scripts entry point names. + """ + has_path_sep = re.search(r'[\\/]', name) + if has_path_sep: + raise ValueError("Path separators not allowed in script names") + @classmethod def get_writer(cls, force_windows): # for backward compatibility -- cgit v1.2.1 From 664646d91c8af89509193c747916eb3f4d920db8 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Thu, 28 May 2015 17:54:28 -0400 Subject: Bumped to 17.0 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index aeccd8e3..f4fad79b 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '16.1' +__version__ = '17.0' -- cgit v1.2.1 From 435745ff2ff4be11ba68c41f297fbcbc3ee1fed5 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Thu, 28 May 2015 22:23:34 -0400 Subject: Bumped to 17.1 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index f4fad79b..f57a6fba 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '17.0' +__version__ = '17.1' -- cgit v1.2.1 From 77b0d0176a4c26de3121d135853b28c3f290c3c7 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 7 Jun 2015 10:39:14 -0400 Subject: Bumped to 17.2 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index f57a6fba..7da47b5e 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '17.1' +__version__ = '17.2' -- cgit v1.2.1 From bcd3e0055d24ea0b0077a2d986f6c4090489a644 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Mon, 8 Jun 2015 13:36:25 -0400 Subject: Bumped to 17.1.1 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index 7da47b5e..6c8b4c2b 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '17.2' +__version__ = '17.1.1' -- cgit v1.2.1 From c1d71724e6f73eec022cb86161cf777ff37b009b Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Mon, 8 Jun 2015 13:37:34 -0400 Subject: Bumped to 17.1.2 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index 6c8b4c2b..a9da9717 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '17.1.1' +__version__ = '17.1.2' -- cgit v1.2.1 From a811c089a4362c0dc6c4a84b708953dde9ebdbf8 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 10 Jun 2015 12:33:54 -0400 Subject: Detect Cython later in the build process, allowing the library to be specified in setup_requires. Fixes #288. --- setuptools/command/build_ext.py | 15 +++------------ setuptools/extension.py | 21 ++++++++++----------- 2 files changed, 13 insertions(+), 23 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/build_ext.py b/setuptools/command/build_ext.py index e4b2c593..92e4a189 100644 --- a/setuptools/command/build_ext.py +++ b/setuptools/command/build_ext.py @@ -11,8 +11,8 @@ import itertools from setuptools.extension import Library try: - # Attempt to use Pyrex for building extensions, if available - from Pyrex.Distutils.build_ext import build_ext as _build_ext + # Attempt to use Cython for building extensions, if available + from Cython.Distutils.build_ext import build_ext as _build_ext except ImportError: _build_ext = _du_build_ext @@ -42,7 +42,6 @@ elif os.name != 'nt': if_dl = lambda s: s if have_rtld else '' - class build_ext(_build_ext): def run(self): """Build extensions in build directory, then copy if --inplace""" @@ -74,15 +73,6 @@ class build_ext(_build_ext): if ext._needs_stub: self.write_stub(package_dir or os.curdir, ext, True) - if _build_ext is not _du_build_ext and not hasattr(_build_ext, - 'pyrex_sources'): - # Workaround for problems using some Pyrex versions w/SWIG and/or 2.4 - def swig_sources(self, sources, *otherargs): - # first do any Pyrex processing - sources = _build_ext.swig_sources(self, sources) or sources - # Then do any actual SWIG stuff on the remainder - return _du_build_ext.swig_sources(self, sources, *otherargs) - def get_ext_filename(self, fullname): filename = _build_ext.get_ext_filename(self, fullname) if fullname in self.ext_map: @@ -176,6 +166,7 @@ class build_ext(_build_ext): return _build_ext.get_export_symbols(self, ext) def build_extension(self, ext): + ext._convert_pyx_sources_to_lang() _compiler = self.compiler try: if isinstance(ext, Library): diff --git a/setuptools/extension.py b/setuptools/extension.py index 8178ed33..a7c40f86 100644 --- a/setuptools/extension.py +++ b/setuptools/extension.py @@ -12,35 +12,34 @@ _Extension = _get_unpatched(distutils.core.Extension) msvc9_support.patch_for_specialized_compiler() -def have_pyrex(): +def _have_cython(): """ - Return True if Cython or Pyrex can be imported. + Return True if Cython can be imported. """ - pyrex_impls = 'Cython.Distutils.build_ext', 'Pyrex.Distutils.build_ext' - for pyrex_impl in pyrex_impls: + cython_impls = 'Cython.Distutils.build_ext', + for cython_impl in cython_impls: try: - # from (pyrex_impl) import build_ext - __import__(pyrex_impl, fromlist=['build_ext']).build_ext + # from (cython_impl) import build_ext + __import__(cython_impl, fromlist=['build_ext']).build_ext return True except Exception: pass return False +# for compatibility +have_pyrex = _have_cython + class Extension(_Extension): """Extension that uses '.c' files in place of '.pyx' files""" - def __init__(self, *args, **kw): - _Extension.__init__(self, *args, **kw) - self._convert_pyx_sources_to_lang() - def _convert_pyx_sources_to_lang(self): """ Replace sources with .pyx extensions to sources with the target language extension. This mechanism allows language authors to supply pre-converted sources but to prefer the .pyx sources. """ - if have_pyrex(): + if _have_cython(): # the build has Cython, so allow it to compile the .pyx files return lang = self.language or '' -- cgit v1.2.1 From 7bbbe8f420a1d52652eca080b3302f2fa64d9c30 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 10 Jun 2015 12:46:41 -0400 Subject: Bumped to 18.0 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index a9da9717..407a82bc 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '17.1.2' +__version__ = '18.0' -- cgit v1.2.1 From 3c047624cfa74a42320334ed6ec0dd7b6bd789b6 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 10 Jun 2015 14:56:52 -0400 Subject: Remove loop, made unnecessary by removal of support for Pyrex --- setuptools/extension.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'setuptools') diff --git a/setuptools/extension.py b/setuptools/extension.py index a7c40f86..35eb7c7c 100644 --- a/setuptools/extension.py +++ b/setuptools/extension.py @@ -16,14 +16,13 @@ def _have_cython(): """ Return True if Cython can be imported. """ - cython_impls = 'Cython.Distutils.build_ext', - for cython_impl in cython_impls: - try: - # from (cython_impl) import build_ext - __import__(cython_impl, fromlist=['build_ext']).build_ext - return True - except Exception: - pass + cython_impl = 'Cython.Distutils.build_ext', + try: + # from (cython_impl) import build_ext + __import__(cython_impl, fromlist=['build_ext']).build_ext + return True + except Exception: + pass return False # for compatibility -- cgit v1.2.1 From e5588b705a2418bd7c46aeae4971f7ebe4bd6ead Mon Sep 17 00:00:00 2001 From: Stephen Drake Date: Thu, 11 Jun 2015 03:22:51 +0000 Subject: Don't quote executable name twice in script headers Don't quote the executable name in JythonCommandSpec.from_environment() since it is quoted if necessary in CommandSpec._render(). With the executable quoted on initialisation of JythonCommandSpec, the quotes get escaped in the resulting header, eg: #!/usr/bin/env \"/path/to/jython\" --- setuptools/command/easy_install.py | 9 --------- 1 file changed, 9 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 1b32b1c8..df1655bf 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -1944,15 +1944,6 @@ class JythonCommandSpec(CommandSpec): __import__('java').lang.System.getProperty('os.name') != 'Linux' ) - @classmethod - def from_environment(cls): - string = '"' + cls._sys_executable() + '"' - return cls.from_string(string) - - @classmethod - def from_string(cls, string): - return cls([string]) - def as_header(self): """ Workaround Jython's sys.executable being a .sh (an invalid -- cgit v1.2.1 From 79e447fcc29d4591f1a4b3403840357e8bccb234 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 13 Jun 2015 11:05:37 -0400 Subject: Fix test failure when __PYVENV_LAUNCHER__ is set. Fixes #396. --- setuptools/tests/test_easy_install.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py index e71bbfc9..a690315d 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -488,9 +488,11 @@ class TestCommandSpec: cmd_new = ei.CommandSpec.from_param(cmd) assert cmd is cmd_new + @mock.patch('sys.executable', TestScriptHeader.exe_with_spaces) + @mock.patch.dict(os.environ) def test_from_environment_with_spaces_in_executable(self): - with mock.patch('sys.executable', TestScriptHeader.exe_with_spaces): - cmd = ei.CommandSpec.from_environment() + del os.environ['__PYVENV_LAUNCHER__'] + cmd = ei.CommandSpec.from_environment() assert len(cmd) == 1 assert cmd.as_header().startswith('#!"') -- cgit v1.2.1 From 47413a2792fb772f4bdcf7a61a843b495464feae Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 23 Jun 2015 18:52:38 -0400 Subject: Bumped to 18.1 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index 407a82bc..92f36007 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '18.0' +__version__ = '18.1' -- cgit v1.2.1 From ea96c15d03dea659cb3cd572e1246bb15ec68e1c Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 23 Jun 2015 20:20:13 -0400 Subject: Conditionally remove __PYVENV_LAUNCHER__ --- setuptools/tests/test_easy_install.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py index a690315d..66601bfe 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -491,7 +491,7 @@ class TestCommandSpec: @mock.patch('sys.executable', TestScriptHeader.exe_with_spaces) @mock.patch.dict(os.environ) def test_from_environment_with_spaces_in_executable(self): - del os.environ['__PYVENV_LAUNCHER__'] + os.environ.pop('__PYVENV_LAUNCHER__', None) cmd = ei.CommandSpec.from_environment() assert len(cmd) == 1 assert cmd.as_header().startswith('#!"') -- cgit v1.2.1 From fc350581c83b27d5846b192016f7525059790f5e Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 24 Jun 2015 16:59:48 -0400 Subject: Bumped to 18.0.1 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index 92f36007..0c6e893f 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '18.1' +__version__ = '18.0.1' -- cgit v1.2.1 From d215171466c4c7511044f92337e215ceda26d07f Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 24 Jun 2015 17:01:04 -0400 Subject: Bumped to 18.0.2 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index 0c6e893f..0767a409 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '18.0.1' +__version__ = '18.0.2' -- cgit v1.2.1 From d51ba2d7a8850a7fb56a6572b372626dd1cd3631 Mon Sep 17 00:00:00 2001 From: Luke Plant Date: Mon, 20 Jul 2015 16:35:49 +0100 Subject: Big performance fix for find_packages by ignoring hidden dirs earlier --- setuptools/__init__.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'setuptools') diff --git a/setuptools/__init__.py b/setuptools/__init__.py index 8188f125..f6536359 100644 --- a/setuptools/__init__.py +++ b/setuptools/__init__.py @@ -81,10 +81,20 @@ class PackageFinder(object): for dir in dirs: yield os.path.relpath(os.path.join(root, dir), base_path) + @staticmethod + def _suitable_dirs(base_path): + """ + Return all suitable package dirs in base_path, relative to base_path + """ + for root, dirs, files in os.walk(base_path, followlinks=True): + # Mutate dirs to trim the search: + dirs[:] = filterfalse(lambda n: '.' in n, dirs) + for dir in dirs: + yield os.path.relpath(os.path.join(root, dir), base_path) + @classmethod def _find_packages_iter(cls, base_path): - dirs = cls._all_dirs(base_path) - suitable = filterfalse(lambda n: '.' in n, dirs) + suitable = cls._suitable_dirs(base_path) return ( path.replace(os.path.sep, '.') for path in suitable -- cgit v1.2.1 From 35bd5713397e0a25eaf1d79230fd1f119838f109 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 2 Aug 2015 14:51:39 -0400 Subject: Bumped to 18.1 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index 0767a409..92f36007 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '18.0.2' +__version__ = '18.1' -- cgit v1.2.1 From 30ece5ff98b651251c491ecf9c7f8c12ebe0f6b8 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 2 Aug 2015 14:52:45 -0400 Subject: Bumped to 18.2 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index 92f36007..715ea4a6 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '18.1' +__version__ = '18.2' -- cgit v1.2.1 From 504d4012293d09847e02d5aa5b495db730077f4f Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 7 Aug 2015 14:06:28 -0400 Subject: Remove unused _all_dirs. Prefer 'candidate' to 'suitable'. Update documentation. --- setuptools/__init__.py | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) (limited to 'setuptools') diff --git a/setuptools/__init__.py b/setuptools/__init__.py index f6536359..2c492446 100644 --- a/setuptools/__init__.py +++ b/setuptools/__init__.py @@ -73,31 +73,24 @@ class PackageFinder(object): yield pkg @staticmethod - def _all_dirs(base_path): + def _candidate_dirs(base_path): """ - Return all dirs in base_path, relative to base_path + Return all dirs in base_path that might be packages. """ + has_dot = lambda name: '.' in name for root, dirs, files in os.walk(base_path, followlinks=True): - for dir in dirs: - yield os.path.relpath(os.path.join(root, dir), base_path) - - @staticmethod - def _suitable_dirs(base_path): - """ - Return all suitable package dirs in base_path, relative to base_path - """ - for root, dirs, files in os.walk(base_path, followlinks=True): - # Mutate dirs to trim the search: - dirs[:] = filterfalse(lambda n: '.' in n, dirs) + # Exclude directories that contain a period, as they cannot be + # packages. Mutate the list to avoid traversal. + dirs[:] = filterfalse(has_dot, dirs) for dir in dirs: yield os.path.relpath(os.path.join(root, dir), base_path) @classmethod def _find_packages_iter(cls, base_path): - suitable = cls._suitable_dirs(base_path) + candidates = cls._candidate_dirs(base_path) return ( path.replace(os.path.sep, '.') - for path in suitable + for path in candidates if cls._looks_like_package(os.path.join(base_path, path)) ) -- cgit v1.2.1 From 413d2abe55dc436b22516ac663f14dd85987d3d9 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 19 Aug 2015 17:47:20 +0100 Subject: Bumped to 18.3 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index 715ea4a6..861921f0 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '18.2' +__version__ = '18.3' -- cgit v1.2.1 From 1f9c2b756ae6050e11d2dfde03a48df354fb0835 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 19 Aug 2015 19:33:55 +0100 Subject: Extract variable --- setuptools/command/easy_install.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index df1655bf..dfdd757e 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -1530,7 +1530,8 @@ class PthDistributions(Environment): if not self.dirty: return - data = '\n'.join(map(self.make_relative, self.paths)) + rel_paths = map(self.make_relative, self.paths) + data = '\n'.join(rel_paths) if data: log.debug("Saving %s", self.filename) data = ( -- cgit v1.2.1 From 9dc51a56c6133f2b115bc8133236e25cd2bb0a31 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 19 Aug 2015 19:36:06 +0100 Subject: Do join late --- setuptools/command/easy_install.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index dfdd757e..4688cc42 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -1530,9 +1530,8 @@ class PthDistributions(Environment): if not self.dirty: return - rel_paths = map(self.make_relative, self.paths) - data = '\n'.join(rel_paths) - if data: + rel_paths = list(map(self.make_relative, self.paths)) + if rel_paths: log.debug("Saving %s", self.filename) data = ( "import sys; sys.__plen = len(sys.path)\n" @@ -1541,7 +1540,7 @@ class PthDistributions(Environment): " del sys.path[sys.__plen:];" " p=getattr(sys,'__egginsert',0); sys.path[p:p]=new;" " sys.__egginsert = p+len(new)\n" - ) % data + ) % '\n'.join(rel_paths) if os.path.islink(self.filename): os.unlink(self.filename) -- cgit v1.2.1 From 3f2ccea66a3deee1e4a4234d695dd94282ec3819 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 19 Aug 2015 19:46:57 +0100 Subject: Extract method for wrapping lines --- setuptools/command/easy_install.py | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 4688cc42..15b260dd 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -1533,14 +1533,8 @@ class PthDistributions(Environment): rel_paths = list(map(self.make_relative, self.paths)) if rel_paths: log.debug("Saving %s", self.filename) - data = ( - "import sys; sys.__plen = len(sys.path)\n" - "%s\n" - "import sys; new=sys.path[sys.__plen:];" - " del sys.path[sys.__plen:];" - " p=getattr(sys,'__egginsert',0); sys.path[p:p]=new;" - " sys.__egginsert = p+len(new)\n" - ) % '\n'.join(rel_paths) + lines = self._wrap_lines(rel_paths) + data = '\n'.join(lines) + '\n' if os.path.islink(self.filename): os.unlink(self.filename) @@ -1554,6 +1548,26 @@ class PthDistributions(Environment): self.dirty = False + def _wrap_lines(self, lines): + yield self._inline(""" + import sys + sys.__plen = len(sys.path) + """) + for line in lines: + yield line + yield self._inline(""" + import sys + new = sys.path[sys.__plen:] + del sys.path[sys.__plen:] + p = getattr(sys, '__egginsert', 0) + sys.path[p:p] = new + sys.__egginsert = p + len(new) + """) + + @staticmethod + def _inline(text): + return textwrap.dedent(text).strip().replace('\n', '; ') + def add(self, dist): """Add `dist` to the distribution map""" new_path = ( -- cgit v1.2.1 From 50aaf9938a4437db7f2949df6ecb6460c789ff28 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 19 Aug 2015 19:47:55 +0100 Subject: Open file in context manager --- setuptools/command/easy_install.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 15b260dd..0e912156 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -1538,9 +1538,8 @@ class PthDistributions(Environment): if os.path.islink(self.filename): os.unlink(self.filename) - f = open(self.filename, 'wt') - f.write(data) - f.close() + with open(self.filename, 'wt') as f: + f.write(data) elif os.path.exists(self.filename): log.debug("Deleting empty %s", self.filename) -- cgit v1.2.1 From 5cbb2ada2e22f95b1dd0cd8ed14643a8cb3766cd Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 19 Aug 2015 19:58:12 +0100 Subject: Calculate prelude and postlude early --- setuptools/command/easy_install.py | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 0e912156..b6b0cffd 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -1547,25 +1547,26 @@ class PthDistributions(Environment): self.dirty = False - def _wrap_lines(self, lines): - yield self._inline(""" - import sys - sys.__plen = len(sys.path) - """) + @classmethod + def _wrap_lines(cls, lines): + yield cls.prelude for line in lines: yield line - yield self._inline(""" - import sys - new = sys.path[sys.__plen:] - del sys.path[sys.__plen:] - p = getattr(sys, '__egginsert', 0) - sys.path[p:p] = new - sys.__egginsert = p + len(new) - """) + yield cls.postlude - @staticmethod - def _inline(text): - return textwrap.dedent(text).strip().replace('\n', '; ') + _inline = lambda text: textwrap.dedent(text).strip().replace('\n', '; ') + prelude = _inline(""" + import sys + sys.__plen = len(sys.path) + """) + postlude = _inline(""" + import sys + new = sys.path[sys.__plen:] + del sys.path[sys.__plen:] + p = getattr(sys, '__egginsert', 0) + sys.path[p:p] = new + sys.__egginsert = p + len(new) + """) def add(self, dist): """Add `dist` to the distribution map""" -- cgit v1.2.1 From e2124f4d4c74770ccc0b9fc5f0e17becda578063 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 19 Aug 2015 20:29:08 +0100 Subject: Extract a class for the behavior that rewrites the sys.path --- setuptools/command/easy_install.py | 50 +++++++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 20 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index b6b0cffd..2b639c1b 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -1547,26 +1547,9 @@ class PthDistributions(Environment): self.dirty = False - @classmethod - def _wrap_lines(cls, lines): - yield cls.prelude - for line in lines: - yield line - yield cls.postlude - - _inline = lambda text: textwrap.dedent(text).strip().replace('\n', '; ') - prelude = _inline(""" - import sys - sys.__plen = len(sys.path) - """) - postlude = _inline(""" - import sys - new = sys.path[sys.__plen:] - del sys.path[sys.__plen:] - p = getattr(sys, '__egginsert', 0) - sys.path[p:p] = new - sys.__egginsert = p + len(new) - """) + @staticmethod + def _wrap_lines(lines): + return lines def add(self, dist): """Add `dist` to the distribution map""" @@ -1605,6 +1588,33 @@ class PthDistributions(Environment): return path +class RewritePthDistributions(PthDistributions): + + @classmethod + def _wrap_lines(cls, lines): + yield cls.prelude + for line in lines: + yield line + yield cls.postlude + + _inline = lambda text: textwrap.dedent(text).strip().replace('\n', '; ') + prelude = _inline(""" + import sys + sys.__plen = len(sys.path) + """) + postlude = _inline(""" + import sys + new = sys.path[sys.__plen:] + del sys.path[sys.__plen:] + p = getattr(sys, '__egginsert', 0) + sys.path[p:p] = new + sys.__egginsert = p + len(new) + """) + + +PthDistributions = RewritePthDistributions + + def _first_line_re(): """ Return a regular expression based on first_line_re suitable for matching -- cgit v1.2.1 From b0b9dae622b4bcebf96555753d1310319a90bbbe Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 19 Aug 2015 20:47:45 +0100 Subject: Allow disabling of the sys.path rewrite technique using an environment variable. --- setuptools/command/easy_install.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 2b639c1b..7c0dfa99 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -1612,7 +1612,8 @@ class RewritePthDistributions(PthDistributions): """) -PthDistributions = RewritePthDistributions +if os.environ.get('SETUPTOOLS_SYS_PATH_TECHNIQUE', 'rewrite') == 'rewrite': + PthDistributions = RewritePthDistributions def _first_line_re(): -- cgit v1.2.1 From 4e854d1e6ffd5ee1adffd8750589b0a16517d67c Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 30 Aug 2015 11:12:58 -0400 Subject: Allow dict.update to do the iteration --- setuptools/__init__.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'setuptools') diff --git a/setuptools/__init__.py b/setuptools/__init__.py index 2c492446..f1798328 100644 --- a/setuptools/__init__.py +++ b/setuptools/__init__.py @@ -124,9 +124,8 @@ class Command(_Command): def __init__(self, dist, **kw): # Add support for keyword arguments - _Command.__init__(self,dist) - for k,v in kw.items(): - setattr(self,k,v) + _Command.__init__(self, dist) + vars(self).update(kw) def reinitialize_command(self, command, reinit_subcommands=0, **kw): cmd = _Command.reinitialize_command(self, command, reinit_subcommands) -- cgit v1.2.1 From af9943a4906a808c8d7c2b5004ba48f32400f1d3 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 30 Aug 2015 11:14:45 -0400 Subject: Replace comment with docstring. Fixes #423 --- setuptools/__init__.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/__init__.py b/setuptools/__init__.py index f1798328..1f421da4 100644 --- a/setuptools/__init__.py +++ b/setuptools/__init__.py @@ -123,7 +123,10 @@ class Command(_Command): command_consumes_arguments = False def __init__(self, dist, **kw): - # Add support for keyword arguments + """ + Construct the command for dist, updating + vars(self) with any keyword parameters. + """ _Command.__init__(self, dist) vars(self).update(kw) -- cgit v1.2.1 From 028ae1a595c08c581fff6ff52883d2719d8f8160 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 30 Aug 2015 11:15:46 -0400 Subject: Allow dict.update to do the iteration --- setuptools/__init__.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'setuptools') diff --git a/setuptools/__init__.py b/setuptools/__init__.py index 1f421da4..9e76ae11 100644 --- a/setuptools/__init__.py +++ b/setuptools/__init__.py @@ -132,8 +132,7 @@ class Command(_Command): def reinitialize_command(self, command, reinit_subcommands=0, **kw): cmd = _Command.reinitialize_command(self, command, reinit_subcommands) - for k,v in kw.items(): - setattr(cmd,k,v) # update command with keywords + vars(cmd).update(kw) return cmd distutils.core.Command = Command # we can't patch distutils.cmd, alas -- cgit v1.2.1 From 29b422607f3083b9ffebba57fc255f45a20353f3 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 30 Aug 2015 11:16:34 -0400 Subject: Prefer preceding line comments --- setuptools/__init__.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'setuptools') diff --git a/setuptools/__init__.py b/setuptools/__init__.py index 9e76ae11..9bbc06bb 100644 --- a/setuptools/__init__.py +++ b/setuptools/__init__.py @@ -135,7 +135,8 @@ class Command(_Command): vars(cmd).update(kw) return cmd -distutils.core.Command = Command # we can't patch distutils.cmd, alas +# we can't patch distutils.cmd, alas +distutils.core.Command = Command def findall(dir = os.curdir): """Find all files under 'dir' and return the list of full filenames @@ -150,4 +151,5 @@ def findall(dir = os.curdir): all_files.extend(filter(os.path.isfile, files)) return all_files -distutils.filelist.findall = findall # fix findall bug in distutils. +# fix findall bug in distutils. +distutils.filelist.findall = findall -- cgit v1.2.1 From e8ffa23f83d13de6ef3e4fe61b5e481c5e6c1d5b Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 30 Aug 2015 11:34:32 -0400 Subject: Add reference to bug report --- setuptools/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/__init__.py b/setuptools/__init__.py index 9bbc06bb..39dd60c6 100644 --- a/setuptools/__init__.py +++ b/setuptools/__init__.py @@ -151,5 +151,5 @@ def findall(dir = os.curdir): all_files.extend(filter(os.path.isfile, files)) return all_files -# fix findall bug in distutils. +# fix findall bug in distutils (http://bugs.python.org/issue12885) distutils.filelist.findall = findall -- cgit v1.2.1 From c05680c5d1b4f0a688a4e560fabde6aa3022596d Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 30 Aug 2015 13:53:14 -0400 Subject: Replace initialize/inject loop with a list comprehension --- setuptools/__init__.py | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) (limited to 'setuptools') diff --git a/setuptools/__init__.py b/setuptools/__init__.py index 39dd60c6..a884d2d3 100644 --- a/setuptools/__init__.py +++ b/setuptools/__init__.py @@ -1,6 +1,7 @@ """Extensions to the 'distutils' for large or complex distributions""" import os +import functools import distutils.core import distutils.filelist from distutils.core import Command as _Command @@ -138,18 +139,24 @@ class Command(_Command): # we can't patch distutils.cmd, alas distutils.core.Command = Command -def findall(dir = os.curdir): +def findall(dir=os.curdir): """Find all files under 'dir' and return the list of full filenames (relative to 'dir'). """ - all_files = [] - for base, dirs, files in os.walk(dir, followlinks=True): - if base==os.curdir or base.startswith(os.curdir+os.sep): - base = base[2:] - if base: - files = [os.path.join(base, f) for f in files] - all_files.extend(filter(os.path.isfile, files)) - return all_files + def _strip_leading_curdir(base): + do_strip = base == os.curdir or base.startswith(os.curdir + os.sep) + return base[2:] if do_strip else base + + def _base_prepend(base): + base = _strip_leading_curdir(base) + return functools.partial(os.path.join, base) + + return [ + file + for base, dirs, files in os.walk(dir, followlinks=True) + for file in map(_base_prepend(base), files) + if os.path.isfile(file) + ] # fix findall bug in distutils (http://bugs.python.org/issue12885) distutils.filelist.findall = findall -- cgit v1.2.1 From 8496cfb24aa20109e64a3b03c972792cd911c086 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 30 Aug 2015 13:56:54 -0400 Subject: Use relpath to produce results relative to 'dir' --- setuptools/__init__.py | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'setuptools') diff --git a/setuptools/__init__.py b/setuptools/__init__.py index a884d2d3..0d1994dc 100644 --- a/setuptools/__init__.py +++ b/setuptools/__init__.py @@ -143,18 +143,13 @@ def findall(dir=os.curdir): """Find all files under 'dir' and return the list of full filenames (relative to 'dir'). """ - def _strip_leading_curdir(base): - do_strip = base == os.curdir or base.startswith(os.curdir + os.sep) - return base[2:] if do_strip else base - - def _base_prepend(base): - base = _strip_leading_curdir(base) - return functools.partial(os.path.join, base) + def _prepend(base): + return functools.partial(os.path.join, os.path.relpath(base, dir)) return [ file for base, dirs, files in os.walk(dir, followlinks=True) - for file in map(_base_prepend(base), files) + for file in map(_prepend(base), files) if os.path.isfile(file) ] -- cgit v1.2.1 From 56afdde1131d3d67360c4032a518b59007255579 Mon Sep 17 00:00:00 2001 From: Ankur Dedania Date: Mon, 31 Aug 2015 20:10:01 +0000 Subject: Adds #257, pip style version --HG-- branch : AbsoluteMSTR/adds-257-pip-style-version-1441051798003 --- setuptools/command/easy_install.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 7c0dfa99..62c24d77 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -217,7 +217,9 @@ class easy_install(Command): def finalize_options(self): if self.version: - print('setuptools %s' % get_distribution('setuptools').version) + dist = get_distribution('setuptools') + print('setuptools %s from %s (python %s)' % ( + dist.version, dist.location, sys.version[:3])) sys.exit() py_version = sys.version.split()[0] -- cgit v1.2.1 From bbb481088c030bed9c837068d0a3b956c2e26446 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 6 Sep 2015 13:45:21 -0400 Subject: Extract version handling as a separate method --- setuptools/command/easy_install.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 62c24d77..45d180bb 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -215,12 +215,19 @@ class easy_install(Command): remover = rmtree if is_tree else os.unlink remover(path) + @staticmethod + def _render_version(): + """ + Render the Setuptools version and installation details, then exit. + """ + ver = sys.version[:3] + dist = get_distribution('setuptools') + tmpl = 'setuptools {dist.version} from {dist.location} (Python {ver})' + print(tmpl.format(**locals())) + raise SystemExit() + def finalize_options(self): - if self.version: - dist = get_distribution('setuptools') - print('setuptools %s from %s (python %s)' % ( - dist.version, dist.location, sys.version[:3])) - sys.exit() + self.version and self._render_version() py_version = sys.version.split()[0] prefix, exec_prefix = get_config_vars('prefix', 'exec_prefix') -- cgit v1.2.1 From c8364b9cf2eeccf684777e53ae4abad2e4fc30b3 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 6 Sep 2015 14:06:13 -0400 Subject: Bumped to 18.4 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index 861921f0..0cf7321a 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '18.3' +__version__ = '18.4' -- cgit v1.2.1 From 9366bb0996cd7c8d3f77ee45f84ddd77f7ded8b7 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 6 Sep 2015 22:30:23 -0400 Subject: Add tests capturing expected behavior, including failure to match expectation indicated in docstring. --- setuptools/tests/test_setuptools.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 setuptools/tests/test_setuptools.py (limited to 'setuptools') diff --git a/setuptools/tests/test_setuptools.py b/setuptools/tests/test_setuptools.py new file mode 100644 index 00000000..f6bec644 --- /dev/null +++ b/setuptools/tests/test_setuptools.py @@ -0,0 +1,24 @@ +import pytest + +import setuptools + + +@pytest.fixture +def example_source(tmpdir): + tmpdir.mkdir('foo') + (tmpdir / 'foo/bar.py').write('') + (tmpdir / 'readme.txt').write('') + return tmpdir + + +def test_findall(example_source): + found = list(setuptools.findall(str(example_source))) + expected = ['readme.txt', 'foo/bar.py'] + assert found == expected + + +def test_findall_curdir(example_source): + with example_source.as_cwd(): + found = list(setuptools.findall()) + expected = ['readme.txt', 'foo/bar.py'] + assert found == expected -- cgit v1.2.1 From 3c0d3a91f64a9174f6e3473bbcea3be42045004a Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 6 Sep 2015 22:35:48 -0400 Subject: Update docstring and test to match long-standing expectation in behavior. --- setuptools/__init__.py | 5 +++-- setuptools/tests/test_setuptools.py | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'setuptools') diff --git a/setuptools/__init__.py b/setuptools/__init__.py index 2c492446..63ee15ed 100644 --- a/setuptools/__init__.py +++ b/setuptools/__init__.py @@ -137,8 +137,9 @@ class Command(_Command): distutils.core.Command = Command # we can't patch distutils.cmd, alas def findall(dir = os.curdir): - """Find all files under 'dir' and return the list of full filenames - (relative to 'dir'). + """ + Find all files under 'dir' and return the list of full filenames. + Unless dir is '.', return full filenames with dir prepended. """ all_files = [] for base, dirs, files in os.walk(dir, followlinks=True): diff --git a/setuptools/tests/test_setuptools.py b/setuptools/tests/test_setuptools.py index f6bec644..e1a06c96 100644 --- a/setuptools/tests/test_setuptools.py +++ b/setuptools/tests/test_setuptools.py @@ -14,6 +14,7 @@ def example_source(tmpdir): def test_findall(example_source): found = list(setuptools.findall(str(example_source))) expected = ['readme.txt', 'foo/bar.py'] + expected = [example_source.join(fn) for fn in expected] assert found == expected -- cgit v1.2.1 From 32a47417750420524e1270cc5e3fc749eb9e5a89 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 6 Sep 2015 22:58:47 -0400 Subject: Restore old behavior for calculating the base. Fixes failing test and fixes #425. --- setuptools/__init__.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/__init__.py b/setuptools/__init__.py index e9390336..49002619 100644 --- a/setuptools/__init__.py +++ b/setuptools/__init__.py @@ -145,7 +145,9 @@ def findall(dir=os.curdir): Unless dir is '.', return full filenames with dir prepended. """ def _prepend(base): - return functools.partial(os.path.join, os.path.relpath(base, dir)) + if base == os.curdir or base.startswith(os.curdir + os.sep): + base = base[2:] + return functools.partial(os.path.join, base) return [ file -- cgit v1.2.1 From 38a40150670a18742a85435ed2baba422c002a68 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Mon, 7 Sep 2015 01:16:14 -0400 Subject: Another refactor of findall, this time separating the simple walk / join operation from the conditional relative path. --- setuptools/__init__.py | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) (limited to 'setuptools') diff --git a/setuptools/__init__.py b/setuptools/__init__.py index 49002619..a7d75ed4 100644 --- a/setuptools/__init__.py +++ b/setuptools/__init__.py @@ -139,22 +139,29 @@ class Command(_Command): # we can't patch distutils.cmd, alas distutils.core.Command = Command + +def _find_all_simple(path): + """ + Find all files under 'path' + """ + return ( + os.path.join(base, file) + for base, dirs, files in os.walk(path, followlinks=True) + for file in files + ) + + def findall(dir=os.curdir): """ Find all files under 'dir' and return the list of full filenames. Unless dir is '.', return full filenames with dir prepended. """ - def _prepend(base): - if base == os.curdir or base.startswith(os.curdir + os.sep): - base = base[2:] - return functools.partial(os.path.join, base) - - return [ - file - for base, dirs, files in os.walk(dir, followlinks=True) - for file in map(_prepend(base), files) - if os.path.isfile(file) - ] + files = _find_all_simple(dir) + if dir == os.curdir: + make_rel = functools.partial(os.path.relpath, start=dir) + files = map(make_rel, files) + return list(files) + # fix findall bug in distutils (http://bugs.python.org/issue12885) distutils.filelist.findall = findall -- cgit v1.2.1 From 9aec33a0cf4a3bcd152d3d142946a98530588af4 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Mon, 7 Sep 2015 02:23:25 -0400 Subject: Bumped to 18.3.1 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index 0cf7321a..12568fa2 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '18.4' +__version__ = '18.3.1' -- cgit v1.2.1 From 30a15dcce774cd9ed2a3f09644aea42fb9f1e819 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 19 Sep 2015 18:00:22 +0200 Subject: Add another test capturing issue described in http://bugs.python.org/issue12885 --- setuptools/tests/test_setuptools.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'setuptools') diff --git a/setuptools/tests/test_setuptools.py b/setuptools/tests/test_setuptools.py index f6bec644..83c42e3e 100644 --- a/setuptools/tests/test_setuptools.py +++ b/setuptools/tests/test_setuptools.py @@ -1,3 +1,5 @@ +import os + import pytest import setuptools @@ -22,3 +24,24 @@ def test_findall_curdir(example_source): found = list(setuptools.findall()) expected = ['readme.txt', 'foo/bar.py'] assert found == expected + + +@pytest.fixture +def can_symlink(tmpdir): + """ + Skip if cannot create a symbolic link + """ + link_fn = 'link' + target_fn = 'target' + try: + os.symlink(target_fn, link_fn) + except (OSError, NotImplementedError, AttributeError): + pytest.skip("Cannot create symbolic links") + os.remove(link_fn) + + +def test_findall_missing_symlink(tmpdir, can_symlink): + with tmpdir.as_cwd(): + os.symlink('foo', 'bar') + found = list(setuptools.findall()) + assert found == [] -- cgit v1.2.1 From 22a8ace27c7d7aadfa0fa9311686541a2169092c Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 19 Sep 2015 18:07:48 +0200 Subject: Only return results that are files. Fixes failing test and corrects additional regression in 18.3. --- setuptools/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/__init__.py b/setuptools/__init__.py index a7d75ed4..712ec082 100644 --- a/setuptools/__init__.py +++ b/setuptools/__init__.py @@ -144,11 +144,12 @@ def _find_all_simple(path): """ Find all files under 'path' """ - return ( + results = ( os.path.join(base, file) for base, dirs, files in os.walk(path, followlinks=True) for file in files ) + return filter(os.path.isfile, results) def findall(dir=os.curdir): -- cgit v1.2.1 From ec01ecef42dd6f9813a9beca71dfdb92fb539719 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 19 Sep 2015 18:27:06 +0200 Subject: Bumped to 18.3.2 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index 12568fa2..787141c7 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '18.3.1' +__version__ = '18.3.2' -- cgit v1.2.1 From 351f51dcefd0fc260f005d30eb60f23a4fcd3ac1 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 19 Sep 2015 18:33:23 +0200 Subject: Bumped to 18.3.3 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index 787141c7..79dd2dab 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '18.3.2' +__version__ = '18.3.3' -- cgit v1.2.1 From bc3389a6048b23871e50eaab20d8df06ba3ff53d Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 27 Sep 2015 07:50:30 -0400 Subject: Extract _requirement_spec method for rendering the requirement specification for scripts. Ref #439. --- setuptools/command/easy_install.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 45d180bb..2faff4c2 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -766,7 +766,7 @@ class easy_install(Command): def install_script(self, dist, script_name, script_text, dev_path=None): """Generate a legacy script wrapper and install it""" - spec = str(dist.as_requirement()) + spec = self._requirement_spec(dist) is_script = is_python_script(script_text, script_name) if is_script: @@ -774,6 +774,10 @@ class easy_install(Command): self._load_template(dev_path) % locals()) self.write_script(script_name, _to_ascii(script_text), 'b') + @staticmethod + def _requirement_spec(dist): + return str(dist.as_requirement()) + @staticmethod def _load_template(dev_path): """ -- cgit v1.2.1 From b9e23adff55624ba2c3527c9f807ec7962b58c5f Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 27 Sep 2015 08:07:30 -0400 Subject: Backed out changeset 38b415c244b8 --- setuptools/command/easy_install.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 2faff4c2..45d180bb 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -766,7 +766,7 @@ class easy_install(Command): def install_script(self, dist, script_name, script_text, dev_path=None): """Generate a legacy script wrapper and install it""" - spec = self._requirement_spec(dist) + spec = str(dist.as_requirement()) is_script = is_python_script(script_text, script_name) if is_script: @@ -774,10 +774,6 @@ class easy_install(Command): self._load_template(dev_path) % locals()) self.write_script(script_name, _to_ascii(script_text), 'b') - @staticmethod - def _requirement_spec(dist): - return str(dist.as_requirement()) - @staticmethod def _load_template(dev_path): """ -- cgit v1.2.1 From 0a30d49169f5e73c86f452f284d10ed4b1646ff4 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 10 Oct 2015 19:59:20 -0400 Subject: Calculate test_args on demand rather than setting an attribute. --- setuptools/command/test.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/test.py b/setuptools/command/test.py index 42689f70..a80d91ad 100644 --- a/setuptools/command/test.py +++ b/setuptools/command/test.py @@ -72,10 +72,6 @@ class test(Command): "You may specify a module or a suite, but not both" ) - self.test_args = [self.test_suite] - - if self.verbose: - self.test_args.insert(0, '--verbose') if self.test_loader is None: self.test_loader = getattr(self.distribution, 'test_loader', None) if self.test_loader is None: @@ -83,6 +79,11 @@ class test(Command): if self.test_runner is None: self.test_runner = getattr(self.distribution, 'test_runner', None) + @property + def test_args(self): + verbose = ['--verbose'] if self.verbose else [] + return verbose + [self.test_suite] + def with_project_on_sys_path(self, func): with_2to3 = PY3 and getattr(self.distribution, 'use_2to3', False) -- cgit v1.2.1 From a33e201d1a86dd108e8641f641ff24c7f00ba054 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 10 Oct 2015 20:03:33 -0400 Subject: Move value checking into its own block. --- setuptools/command/test.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/test.py b/setuptools/command/test.py index a80d91ad..4d859808 100644 --- a/setuptools/command/test.py +++ b/setuptools/command/test.py @@ -62,15 +62,16 @@ class test(Command): def finalize_options(self): + if self.test_suite and self.test_module: + raise DistutilsOptionError( + "You may specify a module or a suite, but not both" + ) + if self.test_suite is None: if self.test_module is None: self.test_suite = self.distribution.test_suite else: self.test_suite = self.test_module + ".test_suite" - elif self.test_module: - raise DistutilsOptionError( - "You may specify a module or a suite, but not both" - ) if self.test_loader is None: self.test_loader = getattr(self.distribution, 'test_loader', None) -- cgit v1.2.1 From 82f3e20506b4e2646880ec7ac5bb6b10e03e8c40 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 10 Oct 2015 20:03:59 -0400 Subject: Extract variable for nicer indentation --- setuptools/command/test.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/test.py b/setuptools/command/test.py index 4d859808..225f4673 100644 --- a/setuptools/command/test.py +++ b/setuptools/command/test.py @@ -63,9 +63,8 @@ class test(Command): def finalize_options(self): if self.test_suite and self.test_module: - raise DistutilsOptionError( - "You may specify a module or a suite, but not both" - ) + msg = "You may specify a module or a suite, but not both" + raise DistutilsOptionError(msg) if self.test_suite is None: if self.test_module is None: -- cgit v1.2.1 From 552ca4d4c712c68c90601ff3f70cf4115b1636ac Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 10 Oct 2015 20:12:12 -0400 Subject: Resolve test_suite directly rather than referencing test_args --- setuptools/command/test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/command/test.py b/setuptools/command/test.py index 225f4673..3e9f5f72 100644 --- a/setuptools/command/test.py +++ b/setuptools/command/test.py @@ -147,7 +147,7 @@ class test(Command): # re-import them from the build location. Required when 2to3 is used # with namespace packages. if PY3 and getattr(self.distribution, 'use_2to3', False): - module = self.test_args[-1].split('.')[0] + module = self.test_suite.split('.')[0] if module in _namespace_packages: del_modules = [] if module in sys.modules: -- cgit v1.2.1 From 476381578991476afeca2e28a96b51fdbef50c13 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 10 Oct 2015 20:15:25 -0400 Subject: Just pass 'unittest' as argv[0] - the full path to the file shouldn't be relevant --- setuptools/command/test.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/test.py b/setuptools/command/test.py index 3e9f5f72..5f93d92e 100644 --- a/setuptools/command/test.py +++ b/setuptools/command/test.py @@ -1,6 +1,5 @@ from distutils.errors import DistutilsOptionError from unittest import TestLoader -import unittest import sys from pkg_resources import (resource_listdir, resource_exists, normalize_path, @@ -159,7 +158,7 @@ class test(Command): list(map(sys.modules.__delitem__, del_modules)) unittest_main( - None, None, [unittest.__file__] + self.test_args, + None, None, ['unittest'] + self.test_args, testLoader=self._resolve_as_ep(self.test_loader), testRunner=self._resolve_as_ep(self.test_runner), ) -- cgit v1.2.1 From 0f14cd9c52944d924c7d9ac350e4f904b0edb0af Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 10 Oct 2015 20:16:23 -0400 Subject: Extract _argv property. --- setuptools/command/test.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/command/test.py b/setuptools/command/test.py index 5f93d92e..549cfb21 100644 --- a/setuptools/command/test.py +++ b/setuptools/command/test.py @@ -158,11 +158,15 @@ class test(Command): list(map(sys.modules.__delitem__, del_modules)) unittest_main( - None, None, ['unittest'] + self.test_args, + None, None, self._argv, testLoader=self._resolve_as_ep(self.test_loader), testRunner=self._resolve_as_ep(self.test_runner), ) + @property + def _argv(self): + return ['unittest'] + self.test_args + @staticmethod def _resolve_as_ep(val): """ -- cgit v1.2.1 From 9c9bfb0fc0f1f667bdabf220e939349143e0d9ec Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 10 Oct 2015 20:17:37 -0400 Subject: Re-use _argv for the announcement --- setuptools/command/test.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/test.py b/setuptools/command/test.py index 549cfb21..75d55bad 100644 --- a/setuptools/command/test.py +++ b/setuptools/command/test.py @@ -134,11 +134,11 @@ class test(Command): self.distribution.fetch_build_eggs(self.distribution.tests_require) if self.test_suite: - cmd = ' '.join(self.test_args) + cmd = ' '.join(self._argv) if self.dry_run: - self.announce('skipping "unittest %s" (dry run)' % cmd) + self.announce('skipping "%s" (dry run)' % cmd) else: - self.announce('running "unittest %s"' % cmd) + self.announce('running "%s"' % cmd) self.with_project_on_sys_path(self.run_tests) def run_tests(self): -- cgit v1.2.1 From 8223f2804628034993247add70943888d96d6348 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 10 Oct 2015 20:38:36 -0400 Subject: Only include test_suite in args if one is specified. Ref #446. --- setuptools/command/test.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/test.py b/setuptools/command/test.py index 75d55bad..11e4a019 100644 --- a/setuptools/command/test.py +++ b/setuptools/command/test.py @@ -80,8 +80,13 @@ class test(Command): @property def test_args(self): - verbose = ['--verbose'] if self.verbose else [] - return verbose + [self.test_suite] + return list(self._test_args()) + + def _test_args(self): + if self.verbose: + yield '--verbose' + if self.test_suite: + yield self.test_suite def with_project_on_sys_path(self, func): with_2to3 = PY3 and getattr(self.distribution, 'use_2to3', False) -- cgit v1.2.1 From 5a9aed6e210628d16cd446c163fa50c9841dba34 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 10 Oct 2015 20:40:47 -0400 Subject: Accept a pattern argument, supplied by later versions of unittest. --- setuptools/command/test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/command/test.py b/setuptools/command/test.py index 11e4a019..13b8b46b 100644 --- a/setuptools/command/test.py +++ b/setuptools/command/test.py @@ -11,7 +11,7 @@ from setuptools.py31compat import unittest_main class ScanningLoader(TestLoader): - def loadTestsFromModule(self, module): + def loadTestsFromModule(self, module, pattern=None): """Return a suite of all tests cases contained in the given module If the module is a package, load tests from all the modules in it. -- cgit v1.2.1 From 34910765fbafb53bec6604b730875d010a863ae2 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 10 Oct 2015 20:41:25 -0400 Subject: Always execute tests, even if no test_suite is supplied. Fixes #446. --- setuptools/command/test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/command/test.py b/setuptools/command/test.py index 13b8b46b..9c6a8e04 100644 --- a/setuptools/command/test.py +++ b/setuptools/command/test.py @@ -138,7 +138,7 @@ class test(Command): if self.distribution.tests_require: self.distribution.fetch_build_eggs(self.distribution.tests_require) - if self.test_suite: + if True: cmd = ' '.join(self._argv) if self.dry_run: self.announce('skipping "%s" (dry run)' % cmd) -- cgit v1.2.1 From 63140936955baeaf8390ddad115af1947787f37f Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 10 Oct 2015 20:41:50 -0400 Subject: Remove unreachable branch. --- setuptools/command/test.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/test.py b/setuptools/command/test.py index 9c6a8e04..160e21c9 100644 --- a/setuptools/command/test.py +++ b/setuptools/command/test.py @@ -138,13 +138,12 @@ class test(Command): if self.distribution.tests_require: self.distribution.fetch_build_eggs(self.distribution.tests_require) - if True: - cmd = ' '.join(self._argv) - if self.dry_run: - self.announce('skipping "%s" (dry run)' % cmd) - else: - self.announce('running "%s"' % cmd) - self.with_project_on_sys_path(self.run_tests) + cmd = ' '.join(self._argv) + if self.dry_run: + self.announce('skipping "%s" (dry run)' % cmd) + else: + self.announce('running "%s"' % cmd) + self.with_project_on_sys_path(self.run_tests) def run_tests(self): # Purge modules under test from sys.modules. The test loader will -- cgit v1.2.1 From cab9d9c40afac011cc7e12989dc387094a4f1285 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 10 Oct 2015 21:04:06 -0400 Subject: Bumped to 18.4 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index 79dd2dab..0cf7321a 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '18.3.3' +__version__ = '18.4' -- cgit v1.2.1 From 513c0d0f73951677f006cb43fcbc2127154ccbe7 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 10 Oct 2015 21:05:24 -0400 Subject: Bumped to 18.5 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index 0cf7321a..1be1f7ec 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '18.4' +__version__ = '18.5' -- cgit v1.2.1 From bfc525457225a7c0a45553d0fcf29592230e9855 Mon Sep 17 00:00:00 2001 From: Luke Plant Date: Mon, 19 Oct 2015 12:06:08 +0100 Subject: Added test utility for building files quickly. And made use of it in test_egg_info. --- setuptools/tests/files.py | 32 ++++++++++++++++++++++++++++++++ setuptools/tests/test_egg_info.py | 23 ++++++++++++----------- 2 files changed, 44 insertions(+), 11 deletions(-) create mode 100644 setuptools/tests/files.py (limited to 'setuptools') diff --git a/setuptools/tests/files.py b/setuptools/tests/files.py new file mode 100644 index 00000000..4364241b --- /dev/null +++ b/setuptools/tests/files.py @@ -0,0 +1,32 @@ +import os + + +def build_files(file_defs, prefix=""): + """ + Build a set of files/directories, as described by the file_defs dictionary. + + Each key/value pair in the dictionary is interpreted as a filename/contents + pair. If the contents value is a dictionary, a directory is created, and the + dictionary interpreted as the files within it, recursively. + + For example: + + {"README.txt": "A README file", + "foo": { + "__init__.py": "", + "bar": { + "__init__.py": "", + }, + "baz.py": "# Some code", + } + } + """ + for name, contents in file_defs.items(): + full_name = os.path.join(prefix, name) + if isinstance(contents, dict): + if not os.path.exists(full_name): + os.makedirs(full_name) + build_files(contents, prefix=full_name) + else: + with open(full_name, 'w') as f: + f.write(contents) diff --git a/setuptools/tests/test_egg_info.py b/setuptools/tests/test_egg_info.py index a1caf9fd..8d831107 100644 --- a/setuptools/tests/test_egg_info.py +++ b/setuptools/tests/test_egg_info.py @@ -4,6 +4,7 @@ import stat import pytest from . import environment +from .files import build_files from .textwrap import DALS from . import contexts @@ -22,14 +23,13 @@ class TestEggInfo: """) def _create_project(self): - with open('setup.py', 'w') as f: - f.write(self.setup_script) - - with open('hello.py', 'w') as f: - f.write(DALS(""" + build_files({ + 'setup.py': self.setup_script, + 'hello.py': DALS(""" def run(): print('hello') - """)) + """) + }) @pytest.yield_fixture def env(self): @@ -44,13 +44,14 @@ class TestEggInfo: for dirname in subs ) list(map(os.mkdir, env.paths.values())) - config = os.path.join(env.paths['home'], '.pydistutils.cfg') - with open(config, 'w') as f: - f.write(DALS(""" + build_files({ + env.paths['home']: { + '.pydistutils.cfg': DALS(""" [egg_info] egg-base = %(egg-base)s - """ % env.paths - )) + """ % env.paths) + } + }) yield env def test_egg_base_installed_egg_info(self, tmpdir_cwd, env): -- cgit v1.2.1 From 0b9fa15f89c18733d3b17d147a64a72134e0d8a3 Mon Sep 17 00:00:00 2001 From: Luke Plant Date: Mon, 19 Oct 2015 11:49:29 +0100 Subject: Pulled out some test code for re-use. --- setuptools/tests/test_egg_info.py | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_egg_info.py b/setuptools/tests/test_egg_info.py index 8d831107..4977ea01 100644 --- a/setuptools/tests/test_egg_info.py +++ b/setuptools/tests/test_egg_info.py @@ -57,6 +57,20 @@ class TestEggInfo: def test_egg_base_installed_egg_info(self, tmpdir_cwd, env): self._create_project() + self._run_install_command(tmpdir_cwd, env) + actual = self._find_egg_info_files(env.paths['lib']) + + expected = [ + 'PKG-INFO', + 'SOURCES.txt', + 'dependency_links.txt', + 'entry_points.txt', + 'not-zip-safe', + 'top_level.txt', + ] + assert sorted(actual) == expected + + def _run_install_command(self, tmpdir_cwd, env): environ = os.environ.copy().update( HOME=env.paths['home'], ) @@ -76,18 +90,6 @@ class TestEggInfo: if code: raise AssertionError(data) - actual = self._find_egg_info_files(env.paths['lib']) - - expected = [ - 'PKG-INFO', - 'SOURCES.txt', - 'dependency_links.txt', - 'entry_points.txt', - 'not-zip-safe', - 'top_level.txt', - ] - assert sorted(actual) == expected - def _find_egg_info_files(self, root): results = ( filenames -- cgit v1.2.1 From a9c3739984908d8ed9e902e3a6efe21f031c2908 Mon Sep 17 00:00:00 2001 From: Luke Plant Date: Mon, 19 Oct 2015 12:04:26 +0100 Subject: Added test to ensure that egg_info applies MANIFEST.in The 'self.read_template()' line of manifest_maker was previously uncovered by any test, and the test suite passed if you commented it out. --- setuptools/tests/test_egg_info.py | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_egg_info.py b/setuptools/tests/test_egg_info.py index 4977ea01..8281fdc1 100644 --- a/setuptools/tests/test_egg_info.py +++ b/setuptools/tests/test_egg_info.py @@ -58,7 +58,7 @@ class TestEggInfo: self._create_project() self._run_install_command(tmpdir_cwd, env) - actual = self._find_egg_info_files(env.paths['lib']) + _, actual = self._find_egg_info_files(env.paths['lib']) expected = [ 'PKG-INFO', @@ -70,6 +70,21 @@ class TestEggInfo: ] assert sorted(actual) == expected + def test_manifest_template_is_read(self, tmpdir_cwd, env): + self._create_project() + build_files({ + 'MANIFEST.in': DALS(""" + recursive-include docs *.rst + """), + 'docs': { + 'usage.rst': "Run 'hi'", + } + }) + self._run_install_command(tmpdir_cwd, env) + egg_info_dir, _ = self._find_egg_info_files(env.paths['lib']) + sources_txt = os.path.join(egg_info_dir, 'SOURCES.txt') + assert 'docs/usage.rst' in open(sources_txt).read().split('\n') + def _run_install_command(self, tmpdir_cwd, env): environ = os.environ.copy().update( HOME=env.paths['home'], @@ -92,7 +107,7 @@ class TestEggInfo: def _find_egg_info_files(self, root): results = ( - filenames + (dirpath, filenames) for dirpath, dirnames, filenames in os.walk(root) if os.path.basename(dirpath) == 'EGG-INFO' ) -- cgit v1.2.1 From 2ac80cd8a4ab5d9398c51fbfcc71489141f4f1c1 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 1 Nov 2015 19:21:10 -0500 Subject: Bumped to 18.6 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index 1be1f7ec..74e48b04 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '18.5' +__version__ = '18.6' -- cgit v1.2.1 From f05162f5583979a3cc56492b91211cbe54353efa Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 24 Nov 2015 10:54:46 -0500 Subject: Short circuit on skipped behavior, leaving main behavior in the body of the method. --- setuptools/command/easy_install.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 45d180bb..4fae2560 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -760,9 +760,10 @@ class easy_install(Command): return dst def install_wrapper_scripts(self, dist): - if not self.exclude_scripts: - for args in ScriptWriter.best().get_args(dist): - self.write_script(*args) + if self.exclude_scripts: + return + for args in ScriptWriter.best().get_args(dist): + self.write_script(*args) def install_script(self, dist, script_name, script_text, dev_path=None): """Generate a legacy script wrapper and install it""" -- cgit v1.2.1 From f4576e373b51fab07eec7f6f2cde3ffa2e04f6c0 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 24 Nov 2015 11:32:45 -0500 Subject: Add VersionlessRequirement adapter to suppress the version number in a Distribution. Ref #439. --- setuptools/command/develop.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'setuptools') diff --git a/setuptools/command/develop.py b/setuptools/command/develop.py index 368b64fe..0959d937 100755 --- a/setuptools/command/develop.py +++ b/setuptools/command/develop.py @@ -167,3 +167,26 @@ class develop(easy_install): script_text = f.read() f.close() self.install_script(dist, script_name, script_text, script_path) + + +class VersionlessRequirement(object): + """ + Adapt a pkg_resources.Distribution to simply return the project + name as the 'requirement' so that scripts will work across + multiple versions. + + >>> dist = Distribution(project_name='foo', version='1.0') + >>> str(dist.as_requirement()) + 'foo==1.0' + >>> adapted_dist = VersionlessRequirement(dist) + >>> str(adapted_dist.as_requirement()) + 'foo' + """ + def __init__(self, dist): + self.__dist = dist + + def __getattr__(self, name): + return getattr(self.__dist, name) + + def as_requirement(self): + return self.project_name -- cgit v1.2.1 From c23be8f034d8600191decd7e843ae93619d15298 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 24 Nov 2015 11:35:27 -0500 Subject: Adapt the dist to suppress the version in the requirement when installing scripts under the develop command. Fixes #439. --- setuptools/command/develop.py | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'setuptools') diff --git a/setuptools/command/develop.py b/setuptools/command/develop.py index 0959d937..360872fc 100755 --- a/setuptools/command/develop.py +++ b/setuptools/command/develop.py @@ -168,6 +168,10 @@ class develop(easy_install): f.close() self.install_script(dist, script_name, script_text, script_path) + def install_wrapper_scripts(self, dist): + dist = VersionlessRequirement(dist) + return super(develop, self).install_wrapper_scripts(dist) + class VersionlessRequirement(object): """ -- cgit v1.2.1 From 172bd064abe5a973f38ab9641a80b39782ad2cde Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 24 Nov 2015 11:46:14 -0500 Subject: Bumped to 18.7 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index 74e48b04..f6dc6bf4 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '18.6' +__version__ = '18.7' -- cgit v1.2.1 From e311cafb5305a445def27fbc79fdc5f098c76728 Mon Sep 17 00:00:00 2001 From: Ryan Kelly Date: Tue, 24 Nov 2015 13:46:26 -0500 Subject: issue #464: don't crash using super() on a old-style class --- setuptools/command/develop.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/command/develop.py b/setuptools/command/develop.py index 360872fc..5ae25d71 100755 --- a/setuptools/command/develop.py +++ b/setuptools/command/develop.py @@ -170,7 +170,7 @@ class develop(easy_install): def install_wrapper_scripts(self, dist): dist = VersionlessRequirement(dist) - return super(develop, self).install_wrapper_scripts(dist) + return easy_install.install_wrapper_scripts(self, dist) class VersionlessRequirement(object): -- cgit v1.2.1 From a84f4878c07509a79af863cabf29ce4de6f212c2 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 24 Nov 2015 18:52:20 -0500 Subject: Bumped to 18.6.1 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index f6dc6bf4..9f17b0ab 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '18.7' +__version__ = '18.6.1' -- cgit v1.2.1 From cf39578632c13d49866fe924bf4c5f5ba48db554 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 24 Nov 2015 18:54:16 -0500 Subject: Bumped to 18.6.2 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index 9f17b0ab..86ad21c6 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '18.6.1' +__version__ = '18.6.2' -- cgit v1.2.1 From 3bcf6213d25381d9df9baa2b7a16c9449fbf78e7 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 24 Nov 2015 18:55:48 -0500 Subject: Use context manager for opening file --- setuptools/tests/test_develop.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_develop.py b/setuptools/tests/test_develop.py index ed1b194a..b920655d 100644 --- a/setuptools/tests/test_develop.py +++ b/setuptools/tests/test_develop.py @@ -32,15 +32,13 @@ class TestDevelopTest: os.mkdir(os.path.join(self.dir, 'foo')) # setup.py setup = os.path.join(self.dir, 'setup.py') - f = open(setup, 'w') - f.write(SETUP_PY) - f.close() + with open(setup, 'w') as f: + f.write(SETUP_PY) self.old_cwd = os.getcwd() # foo/__init__.py init = os.path.join(self.dir, 'foo', '__init__.py') - f = open(init, 'w') - f.write(INIT_PY) - f.close() + with open(init, 'w') as f: + f.write(INIT_PY) os.chdir(self.dir) self.old_base = site.USER_BASE -- cgit v1.2.1 From bc7f3b0a36a1c676809f89eae7299afbb7f70f32 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 24 Nov 2015 19:32:13 -0500 Subject: Extract setup/teardown methods as proper fixtures. --- setuptools/tests/test_develop.py | 57 +++++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 27 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_develop.py b/setuptools/tests/test_develop.py index b920655d..96b9f4ef 100644 --- a/setuptools/tests/test_develop.py +++ b/setuptools/tests/test_develop.py @@ -6,8 +6,12 @@ import site import sys import tempfile +import pytest + from setuptools.command.develop import develop from setuptools.dist import Distribution +from . import contexts + SETUP_PY = """\ from setuptools import setup @@ -21,43 +25,42 @@ setup(name='foo', INIT_PY = """print "foo" """ +@pytest.yield_fixture +def temp_user(monkeypatch): + with contexts.tempdir() as user_base: + with contexts.tempdir() as user_site: + monkeypatch.setattr('site.USER_BASE', user_base) + monkeypatch.setattr('site.USER_SITE', user_site) + yield + + +@pytest.yield_fixture +def test_env(tmpdir, temp_user): + target = tmpdir + foo = target.mkdir('foo') + setup = target / 'setup.py' + if setup.isfile(): + raise ValueError(dir(target)) + with setup.open('w') as f: + f.write(SETUP_PY) + init = foo / '__init__.py' + with init.open('w') as f: + f.write(INIT_PY) + with target.as_cwd(): + yield target + + class TestDevelopTest: def setup_method(self, method): if hasattr(sys, 'real_prefix'): return - # Directory structure - self.dir = tempfile.mkdtemp() - os.mkdir(os.path.join(self.dir, 'foo')) - # setup.py - setup = os.path.join(self.dir, 'setup.py') - with open(setup, 'w') as f: - f.write(SETUP_PY) - self.old_cwd = os.getcwd() - # foo/__init__.py - init = os.path.join(self.dir, 'foo', '__init__.py') - with open(init, 'w') as f: - f.write(INIT_PY) - - os.chdir(self.dir) - self.old_base = site.USER_BASE - site.USER_BASE = tempfile.mkdtemp() - self.old_site = site.USER_SITE - site.USER_SITE = tempfile.mkdtemp() - def teardown_method(self, method): if hasattr(sys, 'real_prefix') or (hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix): return - os.chdir(self.old_cwd) - shutil.rmtree(self.dir) - shutil.rmtree(site.USER_BASE) - shutil.rmtree(site.USER_SITE) - site.USER_BASE = self.old_base - site.USER_SITE = self.old_site - - def test_develop(self): + def test_develop(self, test_env): if hasattr(sys, 'real_prefix'): return dist = Distribution( -- cgit v1.2.1 From 448cfc53cd16fb11562def2ee8b9bf66ed178b21 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 24 Nov 2015 19:37:11 -0500 Subject: Replace silent test acceptance with a proper skip check --- setuptools/tests/test_develop.py | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_develop.py b/setuptools/tests/test_develop.py index 96b9f4ef..2baf83bb 100644 --- a/setuptools/tests/test_develop.py +++ b/setuptools/tests/test_develop.py @@ -51,18 +51,9 @@ def test_env(tmpdir, temp_user): class TestDevelopTest: - - def setup_method(self, method): - if hasattr(sys, 'real_prefix'): - return - - def teardown_method(self, method): - if hasattr(sys, 'real_prefix') or (hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix): - return - + @pytest.mark.skipif(hasattr(sys, 'real_prefix'), + reason="Cannot run when invoked in a virtualenv") def test_develop(self, test_env): - if hasattr(sys, 'real_prefix'): - return dist = Distribution( dict(name='foo', packages=['foo'], -- cgit v1.2.1 From e1e3570fb01aa4f1fe6d0e56cfb73d38b781a307 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 24 Nov 2015 19:38:13 -0500 Subject: Extract variable --- setuptools/tests/test_develop.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_develop.py b/setuptools/tests/test_develop.py index 2baf83bb..49e007e6 100644 --- a/setuptools/tests/test_develop.py +++ b/setuptools/tests/test_develop.py @@ -54,12 +54,13 @@ class TestDevelopTest: @pytest.mark.skipif(hasattr(sys, 'real_prefix'), reason="Cannot run when invoked in a virtualenv") def test_develop(self, test_env): - dist = Distribution( - dict(name='foo', - packages=['foo'], - use_2to3=True, - version='0.0', - )) + settings = dict( + name='foo', + packages=['foo'], + use_2to3=True, + version='0.0', + ) + dist = Distribution(settings) dist.script_name = 'setup.py' cmd = develop(dist) cmd.user = 1 -- cgit v1.2.1 From 731c83fd5ebe79a7643465e68310c11387b427e8 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 24 Nov 2015 19:41:32 -0500 Subject: Remove unused imports --- setuptools/tests/test_develop.py | 2 -- 1 file changed, 2 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_develop.py b/setuptools/tests/test_develop.py index 49e007e6..962c4f3c 100644 --- a/setuptools/tests/test_develop.py +++ b/setuptools/tests/test_develop.py @@ -1,10 +1,8 @@ """develop tests """ import os -import shutil import site import sys -import tempfile import pytest -- cgit v1.2.1 From 693f20d40fca6b41ac629665901c350cd3dcd4e8 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 24 Nov 2015 19:45:12 -0500 Subject: Use quiet context to suppress stdout. --- setuptools/tests/test_develop.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_develop.py b/setuptools/tests/test_develop.py index 962c4f3c..f0adcb18 100644 --- a/setuptools/tests/test_develop.py +++ b/setuptools/tests/test_develop.py @@ -65,12 +65,8 @@ class TestDevelopTest: cmd.ensure_finalized() cmd.install_dir = site.USER_SITE cmd.user = 1 - old_stdout = sys.stdout - #sys.stdout = StringIO() - try: + with contexts.quiet(): cmd.run() - finally: - sys.stdout = old_stdout # let's see if we got our egg link at the right place content = os.listdir(site.USER_SITE) -- cgit v1.2.1 From 0861296a63b3fafd059759840fb62ba12d4e6adc Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 24 Nov 2015 19:47:58 -0500 Subject: Use io.open and its context for simpler reading of a file --- setuptools/tests/test_develop.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_develop.py b/setuptools/tests/test_develop.py index f0adcb18..ec655462 100644 --- a/setuptools/tests/test_develop.py +++ b/setuptools/tests/test_develop.py @@ -3,6 +3,7 @@ import os import site import sys +import io import pytest @@ -74,16 +75,12 @@ class TestDevelopTest: assert content == ['easy-install.pth', 'foo.egg-link'] # Check that we are using the right code. - egg_link_file = open(os.path.join(site.USER_SITE, 'foo.egg-link'), 'rt') - try: + fn = os.path.join(site.USER_SITE, 'foo.egg-link') + with io.open(fn) as egg_link_file: path = egg_link_file.read().split()[0].strip() - finally: - egg_link_file.close() - init_file = open(os.path.join(path, 'foo', '__init__.py'), 'rt') - try: + fn = os.path.join(path, 'foo', '__init__.py') + with io.open(fn) as init_file: init = init_file.read().strip() - finally: - init_file.close() if sys.version < "3": assert init == 'print "foo"' else: -- cgit v1.2.1 From 951a3b9df51c1c46a39753dc6f2854ea18f45729 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 24 Nov 2015 20:01:32 -0500 Subject: Use if clause. --- setuptools/tests/test_develop.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_develop.py b/setuptools/tests/test_develop.py index ec655462..35f3ea25 100644 --- a/setuptools/tests/test_develop.py +++ b/setuptools/tests/test_develop.py @@ -10,6 +10,7 @@ import pytest from setuptools.command.develop import develop from setuptools.dist import Distribution from . import contexts +from setuptools.compat import PY3 SETUP_PY = """\ @@ -81,7 +82,6 @@ class TestDevelopTest: fn = os.path.join(path, 'foo', '__init__.py') with io.open(fn) as init_file: init = init_file.read().strip() - if sys.version < "3": - assert init == 'print "foo"' - else: - assert init == 'print("foo")' + + expected = 'print("foo")' if PY3 else 'print "foo"' + assert init == expected -- cgit v1.2.1 From 436be23a0ac5d7f21f261bdcd6fd9119a4f55346 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 24 Nov 2015 20:38:52 -0500 Subject: Rename tests for clarity --- setuptools/tests/test_develop.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_develop.py b/setuptools/tests/test_develop.py index 35f3ea25..725c4ce2 100644 --- a/setuptools/tests/test_develop.py +++ b/setuptools/tests/test_develop.py @@ -50,10 +50,10 @@ def test_env(tmpdir, temp_user): yield target -class TestDevelopTest: +class TestDevelop: @pytest.mark.skipif(hasattr(sys, 'real_prefix'), reason="Cannot run when invoked in a virtualenv") - def test_develop(self, test_env): + def test_2to3_user_mode(self, test_env): settings = dict( name='foo', packages=['foo'], -- cgit v1.2.1 From 7bd76e0869310de9da5a32ca2c860f6a1fa461b5 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 24 Nov 2015 21:21:09 -0500 Subject: Draft a test for testing the new expectation for develop command (and general functionality when console scripts are present). --- setuptools/tests/test_develop.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'setuptools') diff --git a/setuptools/tests/test_develop.py b/setuptools/tests/test_develop.py index 725c4ce2..71f0d69a 100644 --- a/setuptools/tests/test_develop.py +++ b/setuptools/tests/test_develop.py @@ -85,3 +85,28 @@ class TestDevelop: expected = 'print("foo")' if PY3 else 'print "foo"' assert init == expected + + def test_console_scripts(self, tmpdir): + """ + Test that console scripts are installed and that they reference + only the project by name and not the current version. + """ + pytest.skip("TODO: needs a fixture to cause 'develop' " + "to be invoked without mutating environment.") + settings = dict( + name='foo', + packages=['foo'], + version='0.0', + entry_points={ + 'console_scripts': [ + 'foocmd = foo:foo', + ], + }, + ) + dist = Distribution(settings) + dist.script_name = 'setup.py' + cmd = develop(dist) + cmd.ensure_finalized() + cmd.install_dir = tmpdir + cmd.run() + #assert '0.0' not in foocmd_text -- cgit v1.2.1 From 75a571e4d9d5f5c3fde661c54a368b533be1978b Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 25 Nov 2015 10:04:33 -0500 Subject: Skip the test when running under venv also --- setuptools/tests/test_develop.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_develop.py b/setuptools/tests/test_develop.py index 71f0d69a..ab5da00e 100644 --- a/setuptools/tests/test_develop.py +++ b/setuptools/tests/test_develop.py @@ -51,8 +51,10 @@ def test_env(tmpdir, temp_user): class TestDevelop: - @pytest.mark.skipif(hasattr(sys, 'real_prefix'), - reason="Cannot run when invoked in a virtualenv") + in_virtualenv = hasattr(sys, 'real_prefix') + in_venv = hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix + @pytest.mark.skipif(in_virtualenv or in_venv, + reason="Cannot run when invoked in a virtualenv or venv") def test_2to3_user_mode(self, test_env): settings = dict( name='foo', -- cgit v1.2.1 From 08edac82f02e771ff82f01938208def8ef9991b0 Mon Sep 17 00:00:00 2001 From: John Vandenberg Date: Fri, 13 Nov 2015 07:02:56 +1100 Subject: Fix docstring started with """" instead of """ --- setuptools/py31compat.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/py31compat.py b/setuptools/py31compat.py index c487ac04..8fe6dd9d 100644 --- a/setuptools/py31compat.py +++ b/setuptools/py31compat.py @@ -20,7 +20,7 @@ except ImportError: import shutil import tempfile class TemporaryDirectory(object): - """" + """ Very simple temporary directory context manager. Will try to delete afterward, but will also ignore OS and similar errors on deletion. -- cgit v1.2.1 From 03e7e8c23889bcac55d2cb563ad8deb172e77210 Mon Sep 17 00:00:00 2001 From: Eric Larson Date: Sun, 15 Nov 2015 22:30:46 -0500 Subject: Add tests ref #419. --- setuptools/tests/test_egg_info.py | 96 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 91 insertions(+), 5 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_egg_info.py b/setuptools/tests/test_egg_info.py index a1caf9fd..b4195e06 100644 --- a/setuptools/tests/test_egg_info.py +++ b/setuptools/tests/test_egg_info.py @@ -6,9 +6,14 @@ import pytest from . import environment from .textwrap import DALS from . import contexts +from pkg_resources import WorkingSet, Requirement -class TestEggInfo: +class Environment(str): + pass + + +class TestEggInfo(object): setup_script = DALS(""" from setuptools import setup @@ -33,8 +38,6 @@ class TestEggInfo: @pytest.yield_fixture def env(self): - class Environment(str): pass - with contexts.tempdir(prefix='setuptools-test.') as env_dir: env = Environment(env_dir) os.chmod(env_dir, stat.S_IRWXU) @@ -49,8 +52,7 @@ class TestEggInfo: f.write(DALS(""" [egg_info] egg-base = %(egg-base)s - """ % env.paths - )) + """ % env.paths)) yield env def test_egg_base_installed_egg_info(self, tmpdir_cwd, env): @@ -96,3 +98,87 @@ class TestEggInfo: # expect exactly one result result, = results return result + + +class TestEggInfoDistutils(object): + + version = '1.11.0.dev0+2329eae' + setup_script = DALS(""" + from distutils.core import setup + + setup( + name='foo', + py_modules=['hello'], + version='%s', + ) + """) + + def _create_project(self): + with open('setup.py', 'w') as f: + f.write(self.setup_script % self.version) + + with open('hello.py', 'w') as f: + f.write(DALS(""" + def run(): + print('hello') + """)) + + @pytest.yield_fixture + def env(self): + with contexts.tempdir(prefix='setuptools-test.') as env_dir: + env = Environment(env_dir) + os.chmod(env_dir, stat.S_IRWXU) + subs = 'home', 'lib', 'scripts', 'data', 'egg-base' + env.paths = dict( + (dirname, os.path.join(env_dir, dirname)) + for dirname in subs + ) + list(map(os.mkdir, env.paths.values())) + config = os.path.join(env.paths['home'], '.pydistutils.cfg') + with open(config, 'w') as f: + f.write(DALS(""" + [egg_info] + egg-base = %(egg-base)s + """ % env.paths)) + yield env + + def test_egg_base_installed_egg_info(self, tmpdir_cwd, env): + self._create_project() + + environ = os.environ.copy().update( + HOME=env.paths['home'], + ) + cmd = [ + 'install', + '--home', env.paths['home'], + '--install-lib', env.paths['lib'], + '--install-scripts', env.paths['scripts'], + '--install-data', env.paths['data'], + ] + code, data = environment.run_setup_py( + cmd=cmd, + pypath=os.pathsep.join([env.paths['lib'], str(tmpdir_cwd)]), + data_stream=1, + env=environ, + ) + if code: + raise AssertionError(data) + + actual = self._find_egg_info_file(env.paths['lib']) + # On Py3k it can be e.g. foo-1.11.0.dev0_2329eae-py3.4.egg-info + # but 2.7 doesn't add the Python version, so to be expedient we + # just check our start and end, omitting the potential version num + assert actual.startswith('foo-' + self.version.replace('+', '_')) + assert actual.endswith('.egg-info') + # this requirement parsing will raise a VersionConflict unless the + # .egg-info file is parsed (see #419 on BitBucket) + req = Requirement.parse('foo>=1.9') + dist = WorkingSet([env.paths['lib']]).find(req) + assert dist.version == self.version + + def _find_egg_info_file(self, root): + # expect exactly one result + result = (filename for dirpath, dirnames, filenames in os.walk(root) + for filename in filenames if filename.endswith('.egg-info')) + result, = result + return result -- cgit v1.2.1 From 32237eae19b3722b2a1c87bc0a74613c5f12d6fd Mon Sep 17 00:00:00 2001 From: sunpoet Date: Fri, 20 Nov 2015 05:54:41 +0800 Subject: Fix package list inconsistency caused by namespace package on Python 3.5 namespace package will be skipped during installation. Since Python 3.5, .pyo files are removed and new .opt-1.pyc (and .opt-2.pyc) files are introduced [1]. However setuptools does not understand that new naming therefore the corresponding foo.opt-1.pyc is still added into package list (via --record). The inconsistency leads to a packaging error. [1] https://www.python.org/dev/peps/pep-0488/ --- setuptools/command/install_lib.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'setuptools') diff --git a/setuptools/command/install_lib.py b/setuptools/command/install_lib.py index 9b772227..78fe6891 100644 --- a/setuptools/command/install_lib.py +++ b/setuptools/command/install_lib.py @@ -79,6 +79,8 @@ class install_lib(orig.install_lib): base = os.path.join('__pycache__', '__init__.' + imp.get_tag()) yield base + '.pyc' yield base + '.pyo' + yield base + '.opt-1.pyc' + yield base + '.opt-2.pyc' def copy_tree( self, infile, outfile, -- cgit v1.2.1 From 864de11cf162c693fe248b609d73545cacb622df Mon Sep 17 00:00:00 2001 From: grizzlynyo Date: Sat, 21 Nov 2015 15:15:23 +0200 Subject: fix an issue for bdist_wininst with gui_scripts: The script header was always generated with non-gui executable. This was caused by by adjust_header assuming the executable is always an absolute path. Fixed by using find_executables() from distutils. --HG-- branch : bdist_wininst_gui_scripts --- setuptools/command/easy_install.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 45d180bb..7ceac03f 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -2137,10 +2137,13 @@ class WindowsScriptWriter(ScriptWriter): pattern, repl = repl, pattern pattern_ob = re.compile(re.escape(pattern), re.IGNORECASE) new_header = pattern_ob.sub(string=orig_header, repl=repl) - clean_header = new_header[2:-1].strip('"') - if sys.platform == 'win32' and not os.path.exists(clean_header): - # the adjusted version doesn't exist, so return the original - return orig_header + if sys.platform == 'win32': + from distutils.spawn import find_executable + + clean_header = new_header[2:-1].strip('"') + if not find_executable(clean_header): + # the adjusted version doesn't exist, so return the original + return orig_header return new_header -- cgit v1.2.1 From a361ef49cda256e1f53894470cb921d19e04e853 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 27 Nov 2015 21:35:51 -0500 Subject: Extract _use_header method --- setuptools/command/easy_install.py | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index f3b5fa62..9e9c5e54 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -20,6 +20,7 @@ from distutils.errors import DistutilsArgError, DistutilsOptionError, \ from distutils.command.install import INSTALL_SCHEMES, SCHEME_KEYS from distutils import log, dir_util from distutils.command.build_scripts import first_line_re +from distutils.spawn import find_executable import sys import os import zipimport @@ -2126,8 +2127,8 @@ class WindowsScriptWriter(ScriptWriter): blockers = [name + x for x in old] yield name + ext, header + script_text, 't', blockers - @staticmethod - def _adjust_header(type_, orig_header): + @classmethod + def _adjust_header(cls, type_, orig_header): """ Make sure 'pythonw' is used for gui and and 'python' is used for console (regardless of what sys.executable is). @@ -2138,14 +2139,19 @@ class WindowsScriptWriter(ScriptWriter): pattern, repl = repl, pattern pattern_ob = re.compile(re.escape(pattern), re.IGNORECASE) new_header = pattern_ob.sub(string=orig_header, repl=repl) - if sys.platform == 'win32': - from distutils.spawn import find_executable - - clean_header = new_header[2:-1].strip('"') - if not find_executable(clean_header): - # the adjusted version doesn't exist, so return the original - return orig_header - return new_header + return new_header if cls._use_header(new_header) else orig_header + + @staticmethod + def _use_header(new_header): + """ + Should _adjust_header use the replaced header? + + On non-windows systems, always use. On + Windows systems, only use the replaced header if it resolves + to an executable on the system. + """ + clean_header = new_header[2:-1].strip('"') + return sys.platform != 'win32' or find_executable(clean_header) class WindowsExecutableLauncherWriter(WindowsScriptWriter): -- cgit v1.2.1 From a63119c9ebd8e7c578203628023877f7aa3f7e97 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 27 Nov 2015 22:41:52 -0500 Subject: Make test.test_args a non-data property per Pull Request #155. --- setuptools/command/test.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/command/test.py b/setuptools/command/test.py index 160e21c9..c26f5fc9 100644 --- a/setuptools/command/test.py +++ b/setuptools/command/test.py @@ -41,6 +41,17 @@ class ScanningLoader(TestLoader): return tests[0] # don't create a nested suite for only one return +# adapted from jaraco.classes.properties:NonDataProperty +class NonDataProperty(object): + def __init__(self, fget): + self.fget = fget + + def __get__(self, obj, objtype=None): + if obj is None: + return self + return self.fget(obj) + + class test(Command): """Command to run unit tests after in-place build""" @@ -78,7 +89,7 @@ class test(Command): if self.test_runner is None: self.test_runner = getattr(self.distribution, 'test_runner', None) - @property + @NonDataProperty def test_args(self): return list(self._test_args()) -- cgit v1.2.1 From 141d093b0e7f50459c8053ee4619c9991473be6e Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 28 Nov 2015 11:51:17 -0500 Subject: Move test into pkg_resources tests --- setuptools/tests/test_egg_info.py | 85 --------------------------------------- 1 file changed, 85 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_egg_info.py b/setuptools/tests/test_egg_info.py index b4195e06..645c379c 100644 --- a/setuptools/tests/test_egg_info.py +++ b/setuptools/tests/test_egg_info.py @@ -6,7 +6,6 @@ import pytest from . import environment from .textwrap import DALS from . import contexts -from pkg_resources import WorkingSet, Requirement class Environment(str): @@ -98,87 +97,3 @@ class TestEggInfo(object): # expect exactly one result result, = results return result - - -class TestEggInfoDistutils(object): - - version = '1.11.0.dev0+2329eae' - setup_script = DALS(""" - from distutils.core import setup - - setup( - name='foo', - py_modules=['hello'], - version='%s', - ) - """) - - def _create_project(self): - with open('setup.py', 'w') as f: - f.write(self.setup_script % self.version) - - with open('hello.py', 'w') as f: - f.write(DALS(""" - def run(): - print('hello') - """)) - - @pytest.yield_fixture - def env(self): - with contexts.tempdir(prefix='setuptools-test.') as env_dir: - env = Environment(env_dir) - os.chmod(env_dir, stat.S_IRWXU) - subs = 'home', 'lib', 'scripts', 'data', 'egg-base' - env.paths = dict( - (dirname, os.path.join(env_dir, dirname)) - for dirname in subs - ) - list(map(os.mkdir, env.paths.values())) - config = os.path.join(env.paths['home'], '.pydistutils.cfg') - with open(config, 'w') as f: - f.write(DALS(""" - [egg_info] - egg-base = %(egg-base)s - """ % env.paths)) - yield env - - def test_egg_base_installed_egg_info(self, tmpdir_cwd, env): - self._create_project() - - environ = os.environ.copy().update( - HOME=env.paths['home'], - ) - cmd = [ - 'install', - '--home', env.paths['home'], - '--install-lib', env.paths['lib'], - '--install-scripts', env.paths['scripts'], - '--install-data', env.paths['data'], - ] - code, data = environment.run_setup_py( - cmd=cmd, - pypath=os.pathsep.join([env.paths['lib'], str(tmpdir_cwd)]), - data_stream=1, - env=environ, - ) - if code: - raise AssertionError(data) - - actual = self._find_egg_info_file(env.paths['lib']) - # On Py3k it can be e.g. foo-1.11.0.dev0_2329eae-py3.4.egg-info - # but 2.7 doesn't add the Python version, so to be expedient we - # just check our start and end, omitting the potential version num - assert actual.startswith('foo-' + self.version.replace('+', '_')) - assert actual.endswith('.egg-info') - # this requirement parsing will raise a VersionConflict unless the - # .egg-info file is parsed (see #419 on BitBucket) - req = Requirement.parse('foo>=1.9') - dist = WorkingSet([env.paths['lib']]).find(req) - assert dist.version == self.version - - def _find_egg_info_file(self, root): - # expect exactly one result - result = (filename for dirpath, dirnames, filenames in os.walk(root) - for filename in filenames if filename.endswith('.egg-info')) - result, = result - return result -- cgit v1.2.1 From e79907fc0a582234cbddcdc964ebf8206120469d Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 28 Nov 2015 17:57:44 -0500 Subject: Bumped to 18.7 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index 86ad21c6..f6dc6bf4 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '18.6.2' +__version__ = '18.7' -- cgit v1.2.1 From c11203148a150299fac498918b76c0dd83c3fd81 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 28 Nov 2015 17:59:46 -0500 Subject: Bumped to 18.8 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index f6dc6bf4..aeb7307b 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '18.7' +__version__ = '18.8' -- cgit v1.2.1 From 81c103f75d22580b14f162103232632444c9ec6f Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 1 Dec 2015 12:27:21 -0500 Subject: Expect failure on LC_ALL=C also --- setuptools/tests/test_easy_install.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py index 66601bfe..fa510098 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -430,8 +430,10 @@ class TestScriptHeader: expected = '#!"%s"\n' % self.exe_with_spaces assert actual == expected + c_type = os.environ.get("LC_CTYPE", os.environ.get("LC_ALL")) + is_ascii = c_type in ("C", "POSIX") @pytest.mark.xfail( - compat.PY3 and os.environ.get("LC_CTYPE") in ("C", "POSIX"), + compat.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= -- cgit v1.2.1 From efededd6aa8be5ab054037ee32680a772d06a3c5 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 1 Dec 2015 12:41:58 -0500 Subject: Expect failures on these tests due to ASCII --- setuptools/tests/__init__.py | 4 ++++ setuptools/tests/test_easy_install.py | 4 +--- setuptools/tests/test_sdist.py | 8 +++++--- 3 files changed, 10 insertions(+), 6 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/__init__.py b/setuptools/tests/__init__.py index b8a29cba..a93be134 100644 --- a/setuptools/tests/__init__.py +++ b/setuptools/tests/__init__.py @@ -16,6 +16,10 @@ import setuptools.depends as dep from setuptools import Feature from setuptools.depends import Require +c_type = os.environ.get("LC_CTYPE", os.environ.get("LC_ALL")) +is_ascii = c_type in ("C", "POSIX") +fail_on_ascii = pytest.mark.xfail(is_ascii, "Test fails in this locale") + def makeSetup(**args): """Return distribution from 'setup(**args)', without executing commands""" diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py index fa510098..00e16b63 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -35,7 +35,7 @@ import setuptools.tests.server import pkg_resources from .py26compat import tarfile_open -from . import contexts +from . import contexts, is_ascii from .textwrap import DALS @@ -430,8 +430,6 @@ class TestScriptHeader: expected = '#!"%s"\n' % self.exe_with_spaces assert actual == expected - c_type = os.environ.get("LC_CTYPE", os.environ.get("LC_ALL")) - is_ascii = c_type in ("C", "POSIX") @pytest.mark.xfail( compat.PY3 and is_ascii, reason="Test fails in this locale on Python 3" diff --git a/setuptools/tests/test_sdist.py b/setuptools/tests/test_sdist.py index 9013b505..4313c456 100644 --- a/setuptools/tests/test_sdist.py +++ b/setuptools/tests/test_sdist.py @@ -16,6 +16,8 @@ from setuptools.compat import StringIO, unicode, PY3, PY2 from setuptools.command.sdist import sdist from setuptools.command.egg_info import manifest_maker from setuptools.dist import Distribution +from setuptools.tests import fail_on_ascii + SETUP_ATTRS = { 'name': 'sdist_test', @@ -147,6 +149,7 @@ class TestSdistTest: assert 'setup.py' not in manifest, manifest assert 'setup.cfg' not in manifest, manifest + @fail_on_ascii def test_manifest_is_written_with_utf8_encoding(self): # Test for #303. dist = Distribution(SETUP_ATTRS) @@ -256,6 +259,7 @@ class TestSdistTest: # The filelist should have been updated as well assert u_filename not in mm.filelist.files + @fail_on_ascii def test_manifest_is_read_with_utf8_encoding(self): # Test for #303. dist = Distribution(SETUP_ATTRS) @@ -320,9 +324,7 @@ class TestSdistTest: filename = filename.decode('latin-1') assert filename not in cmd.filelist.files - @pytest.mark.skipif(PY3 and locale.getpreferredencoding() != 'UTF-8', - reason='Unittest fails if locale is not utf-8 but the manifests is ' - 'recorded correctly') + @fail_on_ascii def test_sdist_with_utf8_encoded_filename(self): # Test for #303. dist = Distribution(SETUP_ATTRS) -- cgit v1.2.1 From df2fad0435a7875bbbb2f91240754d85a8aebc1f Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 1 Dec 2015 12:45:10 -0500 Subject: Correct usage --- setuptools/tests/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/tests/__init__.py b/setuptools/tests/__init__.py index a93be134..fed07628 100644 --- a/setuptools/tests/__init__.py +++ b/setuptools/tests/__init__.py @@ -18,7 +18,7 @@ from setuptools.depends import Require c_type = os.environ.get("LC_CTYPE", os.environ.get("LC_ALL")) is_ascii = c_type in ("C", "POSIX") -fail_on_ascii = pytest.mark.xfail(is_ascii, "Test fails in this locale") +fail_on_ascii = pytest.mark.xfail(is_ascii, reason="Test fails in this locale") def makeSetup(**args): """Return distribution from 'setup(**args)', without executing commands""" -- cgit v1.2.1 From e7fdbbf85712acea80a591d2ec079b5349a53129 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 1 Dec 2015 13:14:18 -0500 Subject: Try inlining the xfail marker. --- setuptools/tests/test_sdist.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_sdist.py b/setuptools/tests/test_sdist.py index 4313c456..cc7661e6 100644 --- a/setuptools/tests/test_sdist.py +++ b/setuptools/tests/test_sdist.py @@ -16,7 +16,7 @@ from setuptools.compat import StringIO, unicode, PY3, PY2 from setuptools.command.sdist import sdist from setuptools.command.egg_info import manifest_maker from setuptools.dist import Distribution -from setuptools.tests import fail_on_ascii +from setuptools.tests import fail_on_ascii, is_ascii SETUP_ATTRS = { @@ -149,7 +149,7 @@ class TestSdistTest: assert 'setup.py' not in manifest, manifest assert 'setup.cfg' not in manifest, manifest - @fail_on_ascii + @pytest.mark.xfail(is_ascii, reason="Test fails in this locale") def test_manifest_is_written_with_utf8_encoding(self): # Test for #303. dist = Distribution(SETUP_ATTRS) -- cgit v1.2.1 From 2e46cd7f81c5cf46ae45f8d7687ed4a4f9132a76 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 1 Dec 2015 13:20:47 -0500 Subject: WTF --- setuptools/tests/test_sdist.py | 1 + 1 file changed, 1 insertion(+) (limited to 'setuptools') diff --git a/setuptools/tests/test_sdist.py b/setuptools/tests/test_sdist.py index cc7661e6..4d100fad 100644 --- a/setuptools/tests/test_sdist.py +++ b/setuptools/tests/test_sdist.py @@ -152,6 +152,7 @@ class TestSdistTest: @pytest.mark.xfail(is_ascii, reason="Test fails in this locale") def test_manifest_is_written_with_utf8_encoding(self): # Test for #303. + assert not is_ascii dist = Distribution(SETUP_ATTRS) dist.script_name = 'setup.py' mm = manifest_maker(dist) -- cgit v1.2.1 From b4724ffead99897ce9c1411ff59206977df64f5f Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 1 Dec 2015 13:31:01 -0500 Subject: Try setting LC_CTYPE also --- setuptools/tests/test_sdist.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_sdist.py b/setuptools/tests/test_sdist.py index 4d100fad..df46518b 100644 --- a/setuptools/tests/test_sdist.py +++ b/setuptools/tests/test_sdist.py @@ -1,7 +1,6 @@ # -*- coding: utf-8 -*- """sdist tests""" -import locale import os import shutil import sys @@ -9,14 +8,12 @@ import tempfile import unicodedata import contextlib -import pytest - import pkg_resources from setuptools.compat import StringIO, unicode, PY3, PY2 from setuptools.command.sdist import sdist from setuptools.command.egg_info import manifest_maker from setuptools.dist import Distribution -from setuptools.tests import fail_on_ascii, is_ascii +from setuptools.tests import fail_on_ascii SETUP_ATTRS = { @@ -149,10 +146,9 @@ class TestSdistTest: assert 'setup.py' not in manifest, manifest assert 'setup.cfg' not in manifest, manifest - @pytest.mark.xfail(is_ascii, reason="Test fails in this locale") + @fail_on_ascii def test_manifest_is_written_with_utf8_encoding(self): # Test for #303. - assert not is_ascii dist = Distribution(SETUP_ATTRS) dist.script_name = 'setup.py' mm = manifest_maker(dist) -- cgit v1.2.1 From 8e0ac92076007aa6e49f22029003b9618605c996 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 1 Dec 2015 14:07:15 -0500 Subject: Expect failure running Python 3 only tests on Python 2 --- setuptools/tests/__init__.py | 1 + setuptools/tests/test_sdist.py | 210 +++++++++++++++++++++-------------------- 2 files changed, 107 insertions(+), 104 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/__init__.py b/setuptools/tests/__init__.py index fed07628..f985a6e4 100644 --- a/setuptools/tests/__init__.py +++ b/setuptools/tests/__init__.py @@ -20,6 +20,7 @@ c_type = os.environ.get("LC_CTYPE", os.environ.get("LC_ALL")) is_ascii = c_type in ("C", "POSIX") fail_on_ascii = pytest.mark.xfail(is_ascii, reason="Test fails in this locale") + def makeSetup(**args): """Return distribution from 'setup(**args)', without executing commands""" diff --git a/setuptools/tests/test_sdist.py b/setuptools/tests/test_sdist.py index df46518b..2b4d5207 100644 --- a/setuptools/tests/test_sdist.py +++ b/setuptools/tests/test_sdist.py @@ -8,6 +8,8 @@ import tempfile import unicodedata import contextlib +import pytest + import pkg_resources from setuptools.compat import StringIO, unicode, PY3, PY2 from setuptools.command.sdist import sdist @@ -16,6 +18,9 @@ from setuptools.dist import Distribution from setuptools.tests import fail_on_ascii +py3_only = pytest.mark.xfail(PY2, reason="Test runs on Python 3 only") + + SETUP_ATTRS = { 'name': 'sdist_test', 'version': '0.0', @@ -181,80 +186,79 @@ class TestSdistTest: assert posix(filename) in u_contents - # Python 3 only - if PY3: + @py3_only + def test_write_manifest_allows_utf8_filenames(self): + # Test for #303. + dist = Distribution(SETUP_ATTRS) + dist.script_name = 'setup.py' + mm = manifest_maker(dist) + mm.manifest = os.path.join('sdist_test.egg-info', 'SOURCES.txt') + os.mkdir('sdist_test.egg-info') - def test_write_manifest_allows_utf8_filenames(self): - # Test for #303. - dist = Distribution(SETUP_ATTRS) - dist.script_name = 'setup.py' - mm = manifest_maker(dist) - mm.manifest = os.path.join('sdist_test.egg-info', 'SOURCES.txt') - os.mkdir('sdist_test.egg-info') - - # UTF-8 filename - filename = os.path.join(b('sdist_test'), b('smörbröd.py')) - - # Must touch the file or risk removal - open(filename, "w").close() - - # Add filename and write manifest - with quiet(): - mm.run() - u_filename = filename.decode('utf-8') - mm.filelist.files.append(u_filename) - # Re-write manifest - mm.write_manifest() - - manifest = open(mm.manifest, 'rbU') - contents = manifest.read() - manifest.close() - - # The manifest should be UTF-8 encoded - contents.decode('UTF-8') - - # The manifest should contain the UTF-8 filename - assert posix(filename) in contents - - # The filelist should have been updated as well - assert u_filename in mm.filelist.files - - def test_write_manifest_skips_non_utf8_filenames(self): - """ - Files that cannot be encoded to UTF-8 (specifically, those that - weren't originally successfully decoded and have surrogate - escapes) should be omitted from the manifest. - See https://bitbucket.org/tarek/distribute/issue/303 for history. - """ - dist = Distribution(SETUP_ATTRS) - dist.script_name = 'setup.py' - mm = manifest_maker(dist) - mm.manifest = os.path.join('sdist_test.egg-info', 'SOURCES.txt') - os.mkdir('sdist_test.egg-info') - - # Latin-1 filename - filename = os.path.join(b('sdist_test'), LATIN1_FILENAME) - - # Add filename with surrogates and write manifest - with quiet(): - mm.run() - u_filename = filename.decode('utf-8', 'surrogateescape') - mm.filelist.append(u_filename) - # Re-write manifest - mm.write_manifest() - - manifest = open(mm.manifest, 'rbU') - contents = manifest.read() - manifest.close() - - # The manifest should be UTF-8 encoded - contents.decode('UTF-8') - - # The Latin-1 filename should have been skipped - assert posix(filename) not in contents - - # The filelist should have been updated as well - assert u_filename not in mm.filelist.files + # UTF-8 filename + filename = os.path.join(b('sdist_test'), b('smörbröd.py')) + + # Must touch the file or risk removal + open(filename, "w").close() + + # Add filename and write manifest + with quiet(): + mm.run() + u_filename = filename.decode('utf-8') + mm.filelist.files.append(u_filename) + # Re-write manifest + mm.write_manifest() + + manifest = open(mm.manifest, 'rbU') + contents = manifest.read() + manifest.close() + + # The manifest should be UTF-8 encoded + contents.decode('UTF-8') + + # The manifest should contain the UTF-8 filename + assert posix(filename) in contents + + # The filelist should have been updated as well + assert u_filename in mm.filelist.files + + @py3_only + def test_write_manifest_skips_non_utf8_filenames(self): + """ + Files that cannot be encoded to UTF-8 (specifically, those that + weren't originally successfully decoded and have surrogate + escapes) should be omitted from the manifest. + See https://bitbucket.org/tarek/distribute/issue/303 for history. + """ + dist = Distribution(SETUP_ATTRS) + dist.script_name = 'setup.py' + mm = manifest_maker(dist) + mm.manifest = os.path.join('sdist_test.egg-info', 'SOURCES.txt') + os.mkdir('sdist_test.egg-info') + + # Latin-1 filename + filename = os.path.join(b('sdist_test'), LATIN1_FILENAME) + + # Add filename with surrogates and write manifest + with quiet(): + mm.run() + u_filename = filename.decode('utf-8', 'surrogateescape') + mm.filelist.append(u_filename) + # Re-write manifest + mm.write_manifest() + + manifest = open(mm.manifest, 'rbU') + contents = manifest.read() + manifest.close() + + # The manifest should be UTF-8 encoded + contents.decode('UTF-8') + + # The Latin-1 filename should have been skipped + assert posix(filename) not in contents + + # The filelist should have been updated as well + assert u_filename not in mm.filelist.files @fail_on_ascii def test_manifest_is_read_with_utf8_encoding(self): @@ -288,38 +292,36 @@ class TestSdistTest: filename = filename.decode('utf-8') assert filename in cmd.filelist.files - # Python 3 only - if PY3: + @py3_only + def test_read_manifest_skips_non_utf8_filenames(self): + # Test for #303. + dist = Distribution(SETUP_ATTRS) + dist.script_name = 'setup.py' + cmd = sdist(dist) + cmd.ensure_finalized() + + # Create manifest + with quiet(): + cmd.run() + + # Add Latin-1 filename to manifest + filename = os.path.join(b('sdist_test'), LATIN1_FILENAME) + cmd.manifest = os.path.join('sdist_test.egg-info', 'SOURCES.txt') + manifest = open(cmd.manifest, 'ab') + manifest.write(b('\n') + filename) + manifest.close() + + # The file must exist to be included in the filelist + open(filename, 'w').close() + + # Re-read manifest + cmd.filelist.files = [] + with quiet(): + cmd.read_manifest() - def test_read_manifest_skips_non_utf8_filenames(self): - # Test for #303. - dist = Distribution(SETUP_ATTRS) - dist.script_name = 'setup.py' - cmd = sdist(dist) - cmd.ensure_finalized() - - # Create manifest - with quiet(): - cmd.run() - - # Add Latin-1 filename to manifest - filename = os.path.join(b('sdist_test'), LATIN1_FILENAME) - cmd.manifest = os.path.join('sdist_test.egg-info', 'SOURCES.txt') - manifest = open(cmd.manifest, 'ab') - manifest.write(b('\n') + filename) - manifest.close() - - # The file must exist to be included in the filelist - open(filename, 'w').close() - - # Re-read manifest - cmd.filelist.files = [] - with quiet(): - cmd.read_manifest() - - # The Latin-1 filename should have been skipped - filename = filename.decode('latin-1') - assert filename not in cmd.filelist.files + # The Latin-1 filename should have been skipped + filename = filename.decode('latin-1') + assert filename not in cmd.filelist.files @fail_on_ascii def test_sdist_with_utf8_encoded_filename(self): -- cgit v1.2.1 From dc67e7816dcc9f2f5d2056fe4b4613c74fe1e0d3 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 1 Dec 2015 14:08:43 -0500 Subject: Expect fail when LC_ALL=C --- setuptools/tests/test_sdist.py | 1 + 1 file changed, 1 insertion(+) (limited to 'setuptools') diff --git a/setuptools/tests/test_sdist.py b/setuptools/tests/test_sdist.py index 2b4d5207..ec3c8aa9 100644 --- a/setuptools/tests/test_sdist.py +++ b/setuptools/tests/test_sdist.py @@ -187,6 +187,7 @@ class TestSdistTest: assert posix(filename) in u_contents @py3_only + @fail_on_ascii def test_write_manifest_allows_utf8_filenames(self): # Test for #303. dist = Distribution(SETUP_ATTRS) -- cgit v1.2.1 From 42cba609fdb7b639b9fa6d48742afceb8b6e93ff Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 1 Dec 2015 14:14:11 -0500 Subject: Bumped to 18.7.1 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index aeb7307b..ac653aa1 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '18.8' +__version__ = '18.7.1' -- cgit v1.2.1 From dadd14d82c5f1db83704eb1c6da0b62998cb25a7 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 1 Dec 2015 14:15:38 -0500 Subject: Bumped to 18.7.2 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index ac653aa1..5e40c658 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '18.7.1' +__version__ = '18.7.2' -- cgit v1.2.1 From 98ea00965bed70ccf57eb58394d15739fb7372ab Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 1 Dec 2015 21:59:33 -0500 Subject: Use context manager for opening file --- setuptools/command/easy_install.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 9e9c5e54..547a8842 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -805,9 +805,8 @@ class easy_install(Command): ensure_directory(target) if os.path.exists(target): os.unlink(target) - f = open(target, "w" + mode) - f.write(contents) - f.close() + with open(target, "w" + mode) as f: + f.write(contents) chmod(target, 0o777 - mask) def install_eggs(self, spec, dist_filename, tmpdir): -- cgit v1.2.1 From 2086ae7b381287872add8fe9a91b74498d501679 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 1 Dec 2015 22:00:45 -0500 Subject: Extract variable --- setuptools/command/easy_install.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 547a8842..79f068b1 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -772,8 +772,8 @@ class easy_install(Command): is_script = is_python_script(script_text, script_name) if is_script: - script_text = (ScriptWriter.get_header(script_text) + - self._load_template(dev_path) % locals()) + body = self._load_template(dev_path) % locals() + script_text = ScriptWriter.get_header(script_text) + body self.write_script(script_name, _to_ascii(script_text), 'b') @staticmethod -- cgit v1.2.1 From 9a86e5c638a16afc092c9895ae24c4669248448e Mon Sep 17 00:00:00 2001 From: Stanislaw Pitucha Date: Mon, 7 Dec 2015 16:13:26 +1100 Subject: Fix multiline strings with missing spaces --- setuptools/dist.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'setuptools') diff --git a/setuptools/dist.py b/setuptools/dist.py index d7ad4655..03369da8 100644 --- a/setuptools/dist.py +++ b/setuptools/dist.py @@ -160,7 +160,7 @@ def check_packages(dist, attr, value): for pkgname in value: if not re.match(r'\w+(\.\w+)*', pkgname): distutils.log.warn( - "WARNING: %r not a valid package name; please use only" + "WARNING: %r not a valid package name; please use only " ".-separated package names in setup.py", pkgname ) @@ -818,7 +818,7 @@ class Feature: if not self.available: raise DistutilsPlatformError( - self.description+" is required," + self.description+" is required, " "but is not available on this platform" ) -- cgit v1.2.1 From fc916c8ea1f7ac0ee5cc56dfaa0ab4ef6aee1cfb Mon Sep 17 00:00:00 2001 From: Sachi King Date: Mon, 7 Dec 2015 19:52:21 +1300 Subject: Add get_command_list to dist and process distutils.commands entry points --HG-- branch : get_command_list --- setuptools/dist.py | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'setuptools') diff --git a/setuptools/dist.py b/setuptools/dist.py index d7ad4655..c5f04b33 100644 --- a/setuptools/dist.py +++ b/setuptools/dist.py @@ -440,6 +440,14 @@ class Distribution(_Distribution): self.cmdclass[ep.name] = cmdclass return _Distribution.print_commands(self) + def get_command_list(self): + for ep in pkg_resources.iter_entry_points('distutils.commands'): + if ep.name not in self.cmdclass: + # don't require extras as the commands won't be invoked + cmdclass = ep.resolve() + self.cmdclass[ep.name] = cmdclass + return _Distribution.get_command_list(self) + def _set_feature(self,name,status): """Set feature's inclusion status""" setattr(self,self._feature_attrname(name),status) -- cgit v1.2.1 From bb967deca4ff251c5aa8f0404b1223e94d9a301b Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 8 Dec 2015 19:04:13 -0500 Subject: Don't rely on repr for an HTML attribute value (could end up with 'u' prefix). Fixes #471. --- setuptools/package_index.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/package_index.py b/setuptools/package_index.py index cabf1039..dd2df229 100755 --- a/setuptools/package_index.py +++ b/setuptools/package_index.py @@ -1037,7 +1037,7 @@ def local_open(url): break elif os.path.isdir(os.path.join(filename,f)): f+='/' - files.append("%s" % (f,f)) + files.append('{name}'.format(name=f)) else: body = ("%s" % url) + \ "%s" % '\n'.join(files) -- cgit v1.2.1 From 59e47d76244bf25a9c385800328394e97be74b48 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 8 Dec 2015 19:06:03 -0500 Subject: Update syntax for modern style --- setuptools/package_index.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'setuptools') diff --git a/setuptools/package_index.py b/setuptools/package_index.py index dd2df229..330b8391 100755 --- a/setuptools/package_index.py +++ b/setuptools/package_index.py @@ -1031,12 +1031,12 @@ def local_open(url): elif path.endswith('/') and os.path.isdir(filename): files = [] for f in os.listdir(filename): - if f=='index.html': - with open(os.path.join(filename,f),'r') as fp: + if f == 'index.html': + with open(os.path.join(filename, f), 'r') as fp: body = fp.read() break - elif os.path.isdir(os.path.join(filename,f)): - f+='/' + elif os.path.isdir(os.path.join(filename, f)): + f += '/' files.append('{name}'.format(name=f)) else: body = ("%s" % url) + \ -- cgit v1.2.1 From 5a662289e866fb9bac77736ffede2fca05c79367 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 8 Dec 2015 19:06:41 -0500 Subject: Extract variable --- setuptools/package_index.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'setuptools') diff --git a/setuptools/package_index.py b/setuptools/package_index.py index 330b8391..1c156f07 100755 --- a/setuptools/package_index.py +++ b/setuptools/package_index.py @@ -1031,11 +1031,12 @@ def local_open(url): elif path.endswith('/') and os.path.isdir(filename): files = [] for f in os.listdir(filename): + filepath = os.path.join(filename, f) if f == 'index.html': - with open(os.path.join(filename, f), 'r') as fp: + with open(filepath, 'r') as fp: body = fp.read() break - elif os.path.isdir(os.path.join(filename, f)): + elif os.path.isdir(filepath): f += '/' files.append('{name}'.format(name=f)) else: -- cgit v1.2.1 From 95ac77a928a08c836c6f4ccc066a797357207abc Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 8 Dec 2015 19:14:04 -0500 Subject: Use new string formatting here as well --- setuptools/package_index.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'setuptools') diff --git a/setuptools/package_index.py b/setuptools/package_index.py index 1c156f07..525cb645 100755 --- a/setuptools/package_index.py +++ b/setuptools/package_index.py @@ -1040,8 +1040,9 @@ def local_open(url): f += '/' files.append('{name}'.format(name=f)) else: - body = ("%s" % url) + \ - "%s" % '\n'.join(files) + tmpl = ("{url}" + "{files}") + body = tmpl.format(url=url, files='\n'.join(files)) status, message = 200, "OK" else: status, message, body = 404, "Path not found", "Not found" -- cgit v1.2.1 From e76a139ca4fad75c4ce8b3bc95e0009ea0823eb5 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 9 Dec 2015 02:48:31 -0500 Subject: Use io.open in build_py --- setuptools/command/build_py.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/command/build_py.py b/setuptools/command/build_py.py index a873d54b..779adf2a 100644 --- a/setuptools/command/build_py.py +++ b/setuptools/command/build_py.py @@ -5,6 +5,8 @@ import os import sys import fnmatch import textwrap +import io + try: from setuptools.lib2to3_ex import Mixin2to3 @@ -157,7 +159,7 @@ class build_py(orig.build_py, Mixin2to3): else: return init_py - f = open(init_py, 'rbU') + f = io.open(init_py, 'rb') if 'declare_namespace'.encode() not in f.read(): from distutils.errors import DistutilsError -- cgit v1.2.1 From 2ef88b8e709f0c090a3f7f8c7f612aacbbcd648f Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 9 Dec 2015 02:49:48 -0500 Subject: Use context manager for closing file --- setuptools/command/build_py.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/build_py.py b/setuptools/command/build_py.py index 779adf2a..c971626c 100644 --- a/setuptools/command/build_py.py +++ b/setuptools/command/build_py.py @@ -159,7 +159,8 @@ class build_py(orig.build_py, Mixin2to3): else: return init_py - f = io.open(init_py, 'rb') + with io.open(init_py, 'rb') as f: + contents = f.read() if 'declare_namespace'.encode() not in f.read(): from distutils.errors import DistutilsError @@ -169,7 +170,6 @@ class build_py(orig.build_py, Mixin2to3): 'fix it.\n(See the setuptools manual under ' '"Namespace Packages" for details.)\n"' % (package,) ) - f.close() return init_py def initialize_options(self): -- cgit v1.2.1 From d7b8b096a206b178d588049a396d5687dbe7235a Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 9 Dec 2015 02:50:30 -0500 Subject: Prefer bytes literal --- setuptools/command/build_py.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/command/build_py.py b/setuptools/command/build_py.py index c971626c..f0d76705 100644 --- a/setuptools/command/build_py.py +++ b/setuptools/command/build_py.py @@ -161,7 +161,7 @@ class build_py(orig.build_py, Mixin2to3): with io.open(init_py, 'rb') as f: contents = f.read() - if 'declare_namespace'.encode() not in f.read(): + if b'declare_namespace' not in f.read(): from distutils.errors import DistutilsError raise DistutilsError( -- cgit v1.2.1 From 2b2c7c76e8eda4c608183c8e75d9eb0123724135 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 9 Dec 2015 02:51:23 -0500 Subject: Move import to top --- setuptools/command/build_py.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/build_py.py b/setuptools/command/build_py.py index f0d76705..43159c7c 100644 --- a/setuptools/command/build_py.py +++ b/setuptools/command/build_py.py @@ -6,6 +6,7 @@ import sys import fnmatch import textwrap import io +import distutils.errors try: @@ -162,9 +163,7 @@ class build_py(orig.build_py, Mixin2to3): with io.open(init_py, 'rb') as f: contents = f.read() if b'declare_namespace' not in f.read(): - from distutils.errors import DistutilsError - - raise DistutilsError( + raise distutils.errors.DistutilsError( "Namespace package problem: %s is a namespace package, but " "its\n__init__.py does not call declare_namespace()! Please " 'fix it.\n(See the setuptools manual under ' -- cgit v1.2.1 From fc28df6ec826b3bd1ffa89d55d3674aa89d2f5fc Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 9 Dec 2015 02:52:39 -0500 Subject: Remove hanging indent --- setuptools/command/build_py.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/build_py.py b/setuptools/command/build_py.py index 43159c7c..e729f712 100644 --- a/setuptools/command/build_py.py +++ b/setuptools/command/build_py.py @@ -183,8 +183,10 @@ class build_py(orig.build_py, Mixin2to3): def exclude_data_files(self, package, src_dir, files): """Filter filenames for package's data files in 'src_dir'""" - globs = (self.exclude_package_data.get('', []) - + self.exclude_package_data.get(package, [])) + globs = ( + self.exclude_package_data.get('', []) + + self.exclude_package_data.get(package, []) + ) bad = [] for pattern in globs: bad.extend( -- cgit v1.2.1 From a0ad4c94c41a9af9f2479567139ba6489305b9cc Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 9 Dec 2015 02:59:46 -0500 Subject: Rewrite init/loop/extend as dual-for generator expression. --- setuptools/command/build_py.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/build_py.py b/setuptools/command/build_py.py index e729f712..5bbf0870 100644 --- a/setuptools/command/build_py.py +++ b/setuptools/command/build_py.py @@ -187,14 +187,14 @@ class build_py(orig.build_py, Mixin2to3): self.exclude_package_data.get('', []) + self.exclude_package_data.get(package, []) ) - bad = [] - for pattern in globs: - bad.extend( - fnmatch.filter( - files, os.path.join(src_dir, convert_path(pattern)) - ) + bad = dict.fromkeys( + item + for pattern in globs + for item in fnmatch.filter( + files, + os.path.join(src_dir, convert_path(pattern)), ) - bad = dict.fromkeys(bad) + ) seen = {} return [ f for f in files if f not in bad -- cgit v1.2.1 From 4e960934f61c50b98953d6cd12b72b30e85bccf3 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 9 Dec 2015 03:00:28 -0500 Subject: Prefer set to dict.fromkeys --- setuptools/command/build_py.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/command/build_py.py b/setuptools/command/build_py.py index 5bbf0870..3ae331fd 100644 --- a/setuptools/command/build_py.py +++ b/setuptools/command/build_py.py @@ -187,7 +187,7 @@ class build_py(orig.build_py, Mixin2to3): self.exclude_package_data.get('', []) + self.exclude_package_data.get(package, []) ) - bad = dict.fromkeys( + bad = set( item for pattern in globs for item in fnmatch.filter( -- cgit v1.2.1 From 3744e23d533ab5b0ebcb34f6d8792777c3433014 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 9 Dec 2015 03:14:08 -0500 Subject: Reindent to remove trailing comment --- setuptools/command/build_py.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/build_py.py b/setuptools/command/build_py.py index 3ae331fd..55aed230 100644 --- a/setuptools/command/build_py.py +++ b/setuptools/command/build_py.py @@ -197,8 +197,12 @@ class build_py(orig.build_py, Mixin2to3): ) seen = {} return [ - f for f in files if f not in bad - and f not in seen and seen.setdefault(f, 1) # ditch dupes + fn + for fn in files + if fn not in bad + # ditch dupes + and fn not in seen + and seen.setdefault(fn, 1) ] -- cgit v1.2.1 From a8d85057026bc070b2f73b57133f1910218ad815 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 9 Dec 2015 03:20:12 -0500 Subject: Use a defaultdict and count to track seen items --- setuptools/command/build_py.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/build_py.py b/setuptools/command/build_py.py index 55aed230..317dbba4 100644 --- a/setuptools/command/build_py.py +++ b/setuptools/command/build_py.py @@ -7,6 +7,8 @@ import fnmatch import textwrap import io import distutils.errors +import collections +import itertools try: @@ -195,14 +197,13 @@ class build_py(orig.build_py, Mixin2to3): os.path.join(src_dir, convert_path(pattern)), ) ) - seen = {} + seen = collections.defaultdict(itertools.count) return [ fn for fn in files if fn not in bad # ditch dupes - and fn not in seen - and seen.setdefault(fn, 1) + and not next(seen[fn]) ] -- cgit v1.2.1 From 1c7e97f95ea74c241b91dfb975c709940ba00f47 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 9 Dec 2015 03:26:58 -0500 Subject: Remove unused import --- setuptools/command/build_py.py | 1 - 1 file changed, 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/command/build_py.py b/setuptools/command/build_py.py index 317dbba4..b2dafec9 100644 --- a/setuptools/command/build_py.py +++ b/setuptools/command/build_py.py @@ -2,7 +2,6 @@ from glob import glob from distutils.util import convert_path import distutils.command.build_py as orig import os -import sys import fnmatch import textwrap import io -- cgit v1.2.1 From 41112f5afd0d2b0c14899ab1cf2c27183e64d6ac Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 9 Dec 2015 03:34:35 -0500 Subject: Use io.open for future compatibility and consistency --- setuptools/command/build_py.py | 2 +- setuptools/command/develop.py | 6 +++--- setuptools/command/egg_info.py | 4 ++-- setuptools/command/sdist.py | 6 ++---- setuptools/tests/test_sdist.py | 18 +++++++++--------- 5 files changed, 17 insertions(+), 19 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/build_py.py b/setuptools/command/build_py.py index b2dafec9..8a50f032 100644 --- a/setuptools/command/build_py.py +++ b/setuptools/command/build_py.py @@ -163,7 +163,7 @@ class build_py(orig.build_py, Mixin2to3): with io.open(init_py, 'rb') as f: contents = f.read() - if b'declare_namespace' not in f.read(): + if b'declare_namespace' not in contents: raise distutils.errors.DistutilsError( "Namespace package problem: %s is a namespace package, but " "its\n__init__.py does not call declare_namespace()! Please " diff --git a/setuptools/command/develop.py b/setuptools/command/develop.py index 5ae25d71..3a16cdc7 100755 --- a/setuptools/command/develop.py +++ b/setuptools/command/develop.py @@ -3,6 +3,7 @@ from distutils import log from distutils.errors import DistutilsError, DistutilsOptionError import os import glob +import io from pkg_resources import Distribution, PathMetadata, normalize_path from setuptools.command.easy_install import easy_install @@ -163,9 +164,8 @@ class develop(easy_install): for script_name in self.distribution.scripts or []: script_path = os.path.abspath(convert_path(script_name)) script_name = os.path.basename(script_path) - f = open(script_path, 'rU') - script_text = f.read() - f.close() + with io.open(script_path) as strm: + script_text = strm.read() self.install_script(dist, script_name, script_text, script_path) def install_wrapper_scripts(self, dist): diff --git a/setuptools/command/egg_info.py b/setuptools/command/egg_info.py index 50f3d5c0..9a9193c1 100755 --- a/setuptools/command/egg_info.py +++ b/setuptools/command/egg_info.py @@ -10,6 +10,7 @@ import distutils.filelist import os import re import sys +import io try: from setuptools_svn import svn_utils @@ -471,10 +472,9 @@ def get_pkg_info_revision(): # a subversion revision # if os.path.exists('PKG-INFO'): - f = open('PKG-INFO', 'rU') + with io.open('PKG-INFO') as f: for line in f: match = re.match(r"Version:.*-r(\d+)\s*$", line) if match: return int(match.group(1)) - f.close() return 0 diff --git a/setuptools/command/sdist.py b/setuptools/command/sdist.py index 851a1775..71196512 100755 --- a/setuptools/command/sdist.py +++ b/setuptools/command/sdist.py @@ -3,6 +3,7 @@ from distutils import log import distutils.command.sdist as orig import os import sys +import io from setuptools.compat import PY3 from setuptools.utils import cs_path_exists @@ -166,11 +167,8 @@ class sdist(orig.sdist): if not os.path.isfile(self.manifest): return False - fp = open(self.manifest, 'rbU') - try: + with io.open(self.manifest, 'rb') as fp: first_line = fp.readline() - finally: - fp.close() return (first_line != '# file GENERATED by distutils, do NOT edit\n'.encode()) diff --git a/setuptools/tests/test_sdist.py b/setuptools/tests/test_sdist.py index ec3c8aa9..8ec9a4cb 100644 --- a/setuptools/tests/test_sdist.py +++ b/setuptools/tests/test_sdist.py @@ -7,6 +7,7 @@ import sys import tempfile import unicodedata import contextlib +import io import pytest @@ -81,6 +82,11 @@ def decompose(path): return path +def read_all_bytes(filename): + with io.open(filename, 'rb') as fp: + return fp.read() + + class TestSdistTest: def setup_method(self, method): @@ -172,9 +178,7 @@ class TestSdistTest: mm.filelist.append(filename) mm.write_manifest() - manifest = open(mm.manifest, 'rbU') - contents = manifest.read() - manifest.close() + contents = read_all_bytes(mm.manifest) # The manifest should be UTF-8 encoded u_contents = contents.decode('UTF-8') @@ -210,9 +214,7 @@ class TestSdistTest: # Re-write manifest mm.write_manifest() - manifest = open(mm.manifest, 'rbU') - contents = manifest.read() - manifest.close() + contents = read_all_bytes(mm.manifest) # The manifest should be UTF-8 encoded contents.decode('UTF-8') @@ -248,9 +250,7 @@ class TestSdistTest: # Re-write manifest mm.write_manifest() - manifest = open(mm.manifest, 'rbU') - contents = manifest.read() - manifest.close() + contents = read_all_bytes(mm.manifest) # The manifest should be UTF-8 encoded contents.decode('UTF-8') -- cgit v1.2.1 From 50d864aa0693530a70efd6ffc8007d8328bfea6d Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 9 Dec 2015 03:35:46 -0500 Subject: Reindent --- setuptools/command/egg_info.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/egg_info.py b/setuptools/command/egg_info.py index 9a9193c1..fb94a044 100755 --- a/setuptools/command/egg_info.py +++ b/setuptools/command/egg_info.py @@ -472,9 +472,9 @@ def get_pkg_info_revision(): # a subversion revision # if os.path.exists('PKG-INFO'): - with io.open('PKG-INFO') as f: - for line in f: - match = re.match(r"Version:.*-r(\d+)\s*$", line) - if match: - return int(match.group(1)) + with io.open('PKG-INFO') as f: + for line in f: + match = re.match(r"Version:.*-r(\d+)\s*$", line) + if match: + return int(match.group(1)) return 0 -- cgit v1.2.1 From 1265c31f954afe7a1e47edc6dddfe7a5d4c9aa2a Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 9 Dec 2015 03:40:13 -0500 Subject: Replace comment with docstring --- setuptools/command/egg_info.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/egg_info.py b/setuptools/command/egg_info.py index fb94a044..57e89c07 100755 --- a/setuptools/command/egg_info.py +++ b/setuptools/command/egg_info.py @@ -468,9 +468,10 @@ def write_entries(cmd, basename, filename): def get_pkg_info_revision(): - # See if we can get a -r### off of PKG-INFO, in case this is an sdist of - # a subversion revision - # + """ + Get a -r### off of PKG-INFO Version in case this is an sdist of + a subversion revision. + """ if os.path.exists('PKG-INFO'): with io.open('PKG-INFO') as f: for line in f: -- cgit v1.2.1 From ebaf4f2547e71247248abc77f9899e2106482646 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 9 Dec 2015 03:51:59 -0500 Subject: Deprecate get_pkg_info_revision --- setuptools/command/egg_info.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'setuptools') diff --git a/setuptools/command/egg_info.py b/setuptools/command/egg_info.py index 57e89c07..3afd0a45 100755 --- a/setuptools/command/egg_info.py +++ b/setuptools/command/egg_info.py @@ -11,6 +11,7 @@ import os import re import sys import io +import warnings try: from setuptools_svn import svn_utils @@ -472,6 +473,7 @@ def get_pkg_info_revision(): Get a -r### off of PKG-INFO Version in case this is an sdist of a subversion revision. """ + warnings.warn("get_pkg_info_revision is deprecated.", DeprecationWarning) if os.path.exists('PKG-INFO'): with io.open('PKG-INFO') as f: for line in f: -- cgit v1.2.1 From 6840f40ad0cc4df8c98cd8b78f4c86d6200c1b57 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 9 Dec 2015 03:53:38 -0500 Subject: Remove check that would never succeed, because svn_utils always returns an integer and get_svn_revision always returns a non-empty string. --- setuptools/command/egg_info.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/egg_info.py b/setuptools/command/egg_info.py index 3afd0a45..28aa7994 100755 --- a/setuptools/command/egg_info.py +++ b/setuptools/command/egg_info.py @@ -186,9 +186,7 @@ class egg_info(Command): if self.tag_build: version += self.tag_build if self.tag_svn_revision: - rev = self.get_svn_revision() - if rev: # is 0 if it's not an svn working copy - version += '-r%s' % rev + version += '-r%s' % self.get_svn_revision() if self.tag_date: import time -- cgit v1.2.1 From 2a379eac97f2defcb828589ad5b46ace8a54d0f5 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 9 Dec 2015 03:54:32 -0500 Subject: Reorganize imports --- setuptools/command/egg_info.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/egg_info.py b/setuptools/command/egg_info.py index 28aa7994..8b393a71 100755 --- a/setuptools/command/egg_info.py +++ b/setuptools/command/egg_info.py @@ -13,11 +13,6 @@ import sys import io import warnings -try: - from setuptools_svn import svn_utils -except ImportError: - pass - from setuptools import Command from setuptools.command.sdist import sdist from setuptools.compat import basestring, PY3, StringIO @@ -29,6 +24,12 @@ import setuptools.unicode_utils as unicode_utils from pkg_resources import packaging +try: + from setuptools_svn import svn_utils +except ImportError: + pass + + class egg_info(Command): description = "create a distribution's .egg-info directory" -- cgit v1.2.1 From 81ca4fea9e4672f39864439f2049108ad731c8fa Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 9 Dec 2015 03:57:25 -0500 Subject: Move imports to top --- setuptools/command/egg_info.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/egg_info.py b/setuptools/command/egg_info.py index 8b393a71..1301bd84 100755 --- a/setuptools/command/egg_info.py +++ b/setuptools/command/egg_info.py @@ -12,11 +12,15 @@ import re import sys import io import warnings +import time + +from setuptools.compat import basestring, PY3, StringIO from setuptools import Command from setuptools.command.sdist import sdist -from setuptools.compat import basestring, PY3, StringIO from setuptools.command.sdist import walk_revctrl +from setuptools.command.setopt import edit_config +from setuptools.command import bdist_egg from pkg_resources import ( parse_requirements, safe_name, parse_version, safe_version, yield_lines, EntryPoint, iter_entry_points, to_filename) @@ -61,8 +65,6 @@ class egg_info(Command): self.vtags = None def save_version_info(self, filename): - from setuptools.command.setopt import edit_config - values = dict( egg_info=dict( tag_svn_revision=0, @@ -189,8 +191,6 @@ class egg_info(Command): if self.tag_svn_revision: version += '-r%s' % self.get_svn_revision() if self.tag_date: - import time - version += time.strftime("-%Y%m%d") return version @@ -391,7 +391,6 @@ def write_pkg_info(cmd, basename, filename): metadata.name, metadata.version = oldname, oldver safe = getattr(cmd.distribution, 'zip_safe', None) - from setuptools.command import bdist_egg bdist_egg.write_safety_flag(cmd.egg_info, safe) -- cgit v1.2.1 From 76ffa368456be9ecbcb81a8ba3196f1246e444c0 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 11 Dec 2015 10:04:44 -0500 Subject: Use context manager for opening file --- setuptools/command/develop.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/develop.py b/setuptools/command/develop.py index 3a16cdc7..85118767 100755 --- a/setuptools/command/develop.py +++ b/setuptools/command/develop.py @@ -125,9 +125,8 @@ class develop(easy_install): # create an .egg-link in the installation dir, pointing to our egg log.info("Creating %s (link to %s)", self.egg_link, self.egg_base) if not self.dry_run: - f = open(self.egg_link, "w") - f.write(self.egg_path + "\n" + self.setup_path) - f.close() + with open(self.egg_link, "w") as f: + f.write(self.egg_path + "\n" + self.setup_path) # postprocess the installed distro, fixing up .pth, installing scripts, # and handling requirements self.process_distribution(None, self.dist, not self.no_deps) -- cgit v1.2.1 From 07037d10760792ffe616349ab7642b2fce0a0527 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 11 Dec 2015 10:07:13 -0500 Subject: Extract variable, avoiding hanging indent. --- setuptools/command/develop.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/develop.py b/setuptools/command/develop.py index 85118767..07b66ccb 100755 --- a/setuptools/command/develop.py +++ b/setuptools/command/develop.py @@ -54,8 +54,8 @@ class develop(easy_install): # pick up setup-dir .egg files only: no .egg-info self.package_index.scan(glob.glob('*.egg')) - self.egg_link = os.path.join(self.install_dir, ei.egg_name + - '.egg-link') + egg_link_fn = ei.egg_name + '.egg-link' + self.egg_link = os.path.join(self.install_dir, egg_link_fn) self.egg_base = ei.egg_base if self.egg_path is None: self.egg_path = os.path.abspath(ei.egg_base) -- cgit v1.2.1 From 5ba1d009e2c44b63fc2d2e1de09fd1d768c10fca Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 11 Dec 2015 10:13:30 -0500 Subject: Use context for opening file. --- setuptools/package_index.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'setuptools') diff --git a/setuptools/package_index.py b/setuptools/package_index.py index 525cb645..f81b8d78 100755 --- a/setuptools/package_index.py +++ b/setuptools/package_index.py @@ -359,8 +359,9 @@ class PackageIndex(Environment): self.scan_egg_link(item, entry) def scan_egg_link(self, path, entry): - lines = [_f for _f in map(str.strip, - open(os.path.join(path, entry))) if _f] + with open(os.path.join(path, entry)) as raw_lines: + # filter non-empty lines + lines = list(filter(None, map(str.strip, raw_lines))) if len(lines)==2: for dist in find_distributions(os.path.join(path, lines[0])): dist.location = os.path.join(path, *lines) -- cgit v1.2.1 From cd28f4e0eddf3f571cb0efe05a23fa4a7a254de7 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 11 Dec 2015 10:16:25 -0500 Subject: Replace nested code with short-circuit return. --- setuptools/package_index.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'setuptools') diff --git a/setuptools/package_index.py b/setuptools/package_index.py index f81b8d78..5adb8c2b 100755 --- a/setuptools/package_index.py +++ b/setuptools/package_index.py @@ -362,11 +362,15 @@ class PackageIndex(Environment): with open(os.path.join(path, entry)) as raw_lines: # filter non-empty lines lines = list(filter(None, map(str.strip, raw_lines))) - if len(lines)==2: - for dist in find_distributions(os.path.join(path, lines[0])): - dist.location = os.path.join(path, *lines) - dist.precedence = SOURCE_DIST - self.add(dist) + + if len(lines) != 2: + # format is not recognized; punt + return + + for dist in find_distributions(os.path.join(path, lines[0])): + dist.location = os.path.join(path, *lines) + dist.precedence = SOURCE_DIST + self.add(dist) def process_index(self,url,page): """Process the contents of a PyPI page""" -- cgit v1.2.1 From 2f7d95690e53fe92a82b055b82c4dc02b6a3339c Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 11 Dec 2015 10:18:38 -0500 Subject: Extract variables for improved documentation. --- setuptools/package_index.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/package_index.py b/setuptools/package_index.py index 5adb8c2b..36231f11 100755 --- a/setuptools/package_index.py +++ b/setuptools/package_index.py @@ -367,7 +367,9 @@ class PackageIndex(Environment): # format is not recognized; punt return - for dist in find_distributions(os.path.join(path, lines[0])): + egg_path, setup_path = lines + + for dist in find_distributions(os.path.join(path, egg_path)): dist.location = os.path.join(path, *lines) dist.precedence = SOURCE_DIST self.add(dist) -- cgit v1.2.1 From dacc24690e7c8503744ce433aae6dd74a50e2337 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 11 Dec 2015 10:26:16 -0500 Subject: Extract if in for loop --- setuptools/package_index.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'setuptools') diff --git a/setuptools/package_index.py b/setuptools/package_index.py index 36231f11..00ce3ea5 100755 --- a/setuptools/package_index.py +++ b/setuptools/package_index.py @@ -352,8 +352,8 @@ class PackageIndex(Environment): self.warn(msg, url) def scan_egg_links(self, search_path): - for item in search_path: - if os.path.isdir(item): + dirs = filter(os.path.isdir, search_path) + for item in dirs: for entry in os.listdir(item): if entry.endswith('.egg-link'): self.scan_egg_link(item, entry) -- cgit v1.2.1 From 6b8c9181fbb0ef5b223ba45ed361991c601d1d13 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 11 Dec 2015 10:28:36 -0500 Subject: Get filter from the future --- setuptools/compat.py | 4 ++++ setuptools/package_index.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/compat.py b/setuptools/compat.py index 73e6e4aa..68ec97d4 100644 --- a/setuptools/compat.py +++ b/setuptools/compat.py @@ -29,6 +29,8 @@ if PY2: from urllib2 import urlopen, HTTPError, URLError, unquote, splituser from urlparse import urlparse, urlunparse, urljoin, urlsplit, urlunsplit filterfalse = itertools.ifilterfalse + filter = itertools.ifilter + map = itertools.imap exec("""def reraise(tp, value, tb=None): raise tp, value, tb""") @@ -59,6 +61,8 @@ if PY3: urlunsplit, splittag, ) filterfalse = itertools.filterfalse + filter = filter + map = map def reraise(tp, value, tb=None): if value.__traceback__ is not tb: diff --git a/setuptools/package_index.py b/setuptools/package_index.py index 00ce3ea5..095688f9 100755 --- a/setuptools/package_index.py +++ b/setuptools/package_index.py @@ -20,7 +20,7 @@ from setuptools.compat import (urllib2, httplib, StringIO, HTTPError, urlparse, urlunparse, unquote, splituser, url2pathname, name2codepoint, unichr, urljoin, urlsplit, urlunsplit, - ConfigParser) + ConfigParser, filter) from setuptools.compat import filterfalse from fnmatch import translate from setuptools.py26compat import strip_fragment -- cgit v1.2.1 From 6667ea387d5694cf936644898acd20000ca7b1ec Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 11 Dec 2015 10:34:36 -0500 Subject: Replace nested for loop with dual-for generator expression. --- setuptools/package_index.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'setuptools') diff --git a/setuptools/package_index.py b/setuptools/package_index.py index 095688f9..3456f715 100755 --- a/setuptools/package_index.py +++ b/setuptools/package_index.py @@ -6,6 +6,7 @@ import shutil import socket import base64 import hashlib +import itertools from functools import wraps from pkg_resources import ( @@ -353,10 +354,13 @@ class PackageIndex(Environment): def scan_egg_links(self, search_path): dirs = filter(os.path.isdir, search_path) - for item in dirs: - for entry in os.listdir(item): - if entry.endswith('.egg-link'): - self.scan_egg_link(item, entry) + egg_links = ( + (path, entry) + for path in dirs + for entry in os.listdir(path) + if entry.endswith('.egg-link') + ) + list(itertools.starmap(self.scan_egg_link, egg_links)) def scan_egg_link(self, path, entry): with open(os.path.join(path, entry)) as raw_lines: -- cgit v1.2.1 From e99626c4eadf2e45ca5d729aaa3a5b4bb667536b Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 11 Dec 2015 10:36:25 -0500 Subject: Reclaim space from hanging indents --- setuptools/package_index.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'setuptools') diff --git a/setuptools/package_index.py b/setuptools/package_index.py index 3456f715..b0837628 100755 --- a/setuptools/package_index.py +++ b/setuptools/package_index.py @@ -17,11 +17,11 @@ from pkg_resources import ( from setuptools import ssl_support from distutils import log from distutils.errors import DistutilsError -from setuptools.compat import (urllib2, httplib, StringIO, HTTPError, - urlparse, urlunparse, unquote, splituser, - url2pathname, name2codepoint, - unichr, urljoin, urlsplit, urlunsplit, - ConfigParser, filter) +from setuptools.compat import ( + urllib2, httplib, StringIO, HTTPError, urlparse, urlunparse, unquote, + splituser, url2pathname, name2codepoint, unichr, urljoin, urlsplit, + urlunsplit, ConfigParser, filter, +) from setuptools.compat import filterfalse from fnmatch import translate from setuptools.py26compat import strip_fragment -- cgit v1.2.1 From 6a10b4afbad5dca346b7fc7a5d8bb6d08d3286b2 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 11 Dec 2015 10:37:09 -0500 Subject: Also use map from the future --- setuptools/package_index.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/package_index.py b/setuptools/package_index.py index b0837628..7c071457 100755 --- a/setuptools/package_index.py +++ b/setuptools/package_index.py @@ -20,7 +20,7 @@ from distutils.errors import DistutilsError from setuptools.compat import ( urllib2, httplib, StringIO, HTTPError, urlparse, urlunparse, unquote, splituser, url2pathname, name2codepoint, unichr, urljoin, urlsplit, - urlunsplit, ConfigParser, filter, + urlunsplit, ConfigParser, filter, map, ) from setuptools.compat import filterfalse from fnmatch import translate -- cgit v1.2.1 From f351891c97500738be1f23b5e83b955e2d5bdd23 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 11 Dec 2015 12:26:46 -0500 Subject: Bumped to 18.8 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index 5e40c658..aeb7307b 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '18.7.2' +__version__ = '18.8' -- cgit v1.2.1 From 7fd5df90d1f251a22bdb74bed21cebf298b6a8e8 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 11 Dec 2015 12:28:10 -0500 Subject: Bumped to 18.9 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index aeb7307b..9c79593e 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '18.8' +__version__ = '18.9' -- cgit v1.2.1 From a627cf9a72f8fca78b0520b72a5b44a0bbea9b8c Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 13 Dec 2015 10:05:24 -0500 Subject: Add test capturing infinite recursion. Ref #440. --- setuptools/tests/test_sandbox.py | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'setuptools') diff --git a/setuptools/tests/test_sandbox.py b/setuptools/tests/test_sandbox.py index 6e1e9e1c..624954df 100644 --- a/setuptools/tests/test_sandbox.py +++ b/setuptools/tests/test_sandbox.py @@ -100,3 +100,13 @@ class TestExceptionSaver: saved_exc.resume() assert str(caught.value) == "CantPickleThis('detail',)" + + def test_unpickleable_exception_when_hiding_setuptools(self): + """ + As revealed in #440, an infinite recursion can occur if an unpickleable + exception while setuptools is hidden. Ensure this doesn't happen. + """ + sandbox = setuptools.sandbox + with sandbox.save_modules(): + sandbox.hide_setuptools() + raise sandbox.SandboxViolation('test') -- cgit v1.2.1 From bf8331685d1d5bb88cc6cf09236601f0dbe62330 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 13 Dec 2015 10:45:04 -0500 Subject: Refine test to not make additional references to exceptions in setuptools.sandbox, but instead create a bespoke unpickleable exception. Ref #440. --- setuptools/tests/test_sandbox.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_sandbox.py b/setuptools/tests/test_sandbox.py index 624954df..a54c2fa0 100644 --- a/setuptools/tests/test_sandbox.py +++ b/setuptools/tests/test_sandbox.py @@ -106,7 +106,15 @@ class TestExceptionSaver: As revealed in #440, an infinite recursion can occur if an unpickleable exception while setuptools is hidden. Ensure this doesn't happen. """ - sandbox = setuptools.sandbox - with sandbox.save_modules(): - sandbox.hide_setuptools() - raise sandbox.SandboxViolation('test') + class ExceptionUnderTest(Exception): + """ + An unpickleable exception (not in globals). + """ + + with pytest.raises(setuptools.sandbox.UnpickleableException) as exc: + with setuptools.sandbox.save_modules(): + setuptools.sandbox.hide_setuptools() + raise ExceptionUnderTest() + + msg, = exc.value.args + assert msg == 'ExceptionUnderTest()' -- cgit v1.2.1 From 264b5dc6b9cf48b22bd2263d426026d7b8f45608 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 13 Dec 2015 10:48:20 -0500 Subject: Prevent infinite recursion when UnpickleableException occurs in a sandbox context. Fixes #440. --- setuptools/sandbox.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'setuptools') diff --git a/setuptools/sandbox.py b/setuptools/sandbox.py index 213cebff..b8b1bac1 100755 --- a/setuptools/sandbox.py +++ b/setuptools/sandbox.py @@ -98,8 +98,8 @@ class UnpickleableException(Exception): """ An exception representing another Exception that could not be pickled. """ - @classmethod - def dump(cls, type, exc): + @staticmethod + def dump(type, exc): """ Always return a dumped (pickled) type and exc. If exc can't be pickled, wrap it in UnpickleableException first. @@ -107,6 +107,8 @@ class UnpickleableException(Exception): try: return pickle.dumps(type), pickle.dumps(exc) except Exception: + # get UnpickleableException inside the sandbox + from setuptools.sandbox import UnpickleableException as cls return cls.dump(cls, cls(repr(exc))) -- cgit v1.2.1 From ce481836f31142b939f4b93a6eba90630ba354fd Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 13 Dec 2015 11:00:02 -0500 Subject: caught is a better name here --- setuptools/tests/test_sandbox.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_sandbox.py b/setuptools/tests/test_sandbox.py index a54c2fa0..40bd2ebe 100644 --- a/setuptools/tests/test_sandbox.py +++ b/setuptools/tests/test_sandbox.py @@ -111,10 +111,10 @@ class TestExceptionSaver: An unpickleable exception (not in globals). """ - with pytest.raises(setuptools.sandbox.UnpickleableException) as exc: + with pytest.raises(setuptools.sandbox.UnpickleableException) as caught: with setuptools.sandbox.save_modules(): setuptools.sandbox.hide_setuptools() raise ExceptionUnderTest() - msg, = exc.value.args + msg, = caught.value.args assert msg == 'ExceptionUnderTest()' -- cgit v1.2.1 From 3915be7722713c51aab291ed9720c7b83585d2b5 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 13 Dec 2015 11:10:33 -0500 Subject: Add another test capturing violated expectation that SandboxViolation would be raised in a sandbox/hidden_setuptools context. Ref #440. --- setuptools/tests/test_sandbox.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'setuptools') diff --git a/setuptools/tests/test_sandbox.py b/setuptools/tests/test_sandbox.py index 40bd2ebe..fefd46f7 100644 --- a/setuptools/tests/test_sandbox.py +++ b/setuptools/tests/test_sandbox.py @@ -118,3 +118,24 @@ class TestExceptionSaver: msg, = caught.value.args assert msg == 'ExceptionUnderTest()' + + def test_sandbox_violation_raised_hiding_setuptools(self, tmpdir): + """ + When in a sandbox with setuptools hidden, a SandboxViolation + should reflect a proper exception and not be wrapped in + an UnpickleableException. + """ + def write_file(): + "Trigger a SandboxViolation by writing outside the sandbox" + with open('/etc/foo', 'w'): + pass + sandbox = DirectorySandbox(str(tmpdir)) + with pytest.raises(setuptools.sandbox.SandboxViolation) as caught: + with setuptools.sandbox.save_modules(): + setuptools.sandbox.hide_setuptools() + sandbox.run(write_file) + + cmd, args, kwargs = caught.value.args + assert cmd == 'open' + assert args == ('/etc/foo', 'w') + assert kwargs == {} -- cgit v1.2.1 From 1d74aaab3372b6727158802c610043ca036ce5d3 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 13 Dec 2015 11:29:01 -0500 Subject: Always import for SandboxViolation so it's pickleable. Ref #440. --- setuptools/sandbox.py | 1 + 1 file changed, 1 insertion(+) (limited to 'setuptools') diff --git a/setuptools/sandbox.py b/setuptools/sandbox.py index b8b1bac1..85de85ff 100755 --- a/setuptools/sandbox.py +++ b/setuptools/sandbox.py @@ -384,6 +384,7 @@ class DirectorySandbox(AbstractSandbox): AbstractSandbox.__init__(self) def _violation(self, operation, *args, **kw): + from setuptools.sandbox import SandboxViolation raise SandboxViolation(operation, args, kw) if _file: -- cgit v1.2.1 From fa91749d1272c8a00c0c779a4ae9969ff277ee45 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 13 Dec 2015 11:57:40 -0500 Subject: Bumped to 18.8.1 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index 9c79593e..bd0d8b71 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '18.9' +__version__ = '18.8.1' -- cgit v1.2.1 From 17d7ac38c0570bee51f3f202138d522a4cdf5669 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 13 Dec 2015 11:58:57 -0500 Subject: Bumped to 18.8.2 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index bd0d8b71..067c5e37 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '18.8.1' +__version__ = '18.8.2' -- cgit v1.2.1 From 5eafe7644d18eddd77a5573ecc30b4c98efbb2c6 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Mon, 14 Dec 2015 04:12:53 -0500 Subject: Prefer setdefault to hasattr/setattr --- setuptools/dist.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'setuptools') diff --git a/setuptools/dist.py b/setuptools/dist.py index d7ad4655..b0c52838 100644 --- a/setuptools/dist.py +++ b/setuptools/dist.py @@ -267,8 +267,7 @@ class Distribution(_Distribution): if attrs and 'setup_requires' in attrs: self.fetch_build_eggs(attrs['setup_requires']) for ep in pkg_resources.iter_entry_points('distutils.setup_keywords'): - if not hasattr(self,ep.name): - setattr(self,ep.name,None) + vars(self).setdefault(ep.name, None) _Distribution.__init__(self,attrs) if isinstance(self.metadata.version, numbers.Number): # Some people apparently take "version number" too literally :) -- cgit v1.2.1 From 2f0e172bdab76b0c972b5d1480bcccc88f63c7ec Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Mon, 14 Dec 2015 04:48:26 -0500 Subject: Add test capturing InterpolationSyntaxError on Python 3 and KeyError on Python 2 --- setuptools/tests/test_packageindex.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'setuptools') diff --git a/setuptools/tests/test_packageindex.py b/setuptools/tests/test_packageindex.py index dcd90d6f..897590e8 100644 --- a/setuptools/tests/test_packageindex.py +++ b/setuptools/tests/test_packageindex.py @@ -1,7 +1,11 @@ +from __future__ import absolute_import + import sys +import os import distutils.errors from setuptools.compat import httplib, HTTPError, unicode, pathname2url +from .textwrap import DALS import pkg_resources import setuptools.package_index @@ -201,3 +205,20 @@ class TestContentCheckers: 'http://foo/bar#md5=f12895fdffbd45007040d2e44df98478') rep = checker.report(lambda x: x, 'My message about %s') assert rep == 'My message about md5' + + +class TestPyPIConfig: + def test_percent_in_password(self, tmpdir, monkeypatch): + monkeypatch.setitem(os.environ, 'HOME', str(tmpdir)) + pypirc = tmpdir / '.pypirc' + with pypirc.open('w') as strm: + strm.write(DALS(""" + [pypi] + repository=https://pypi.python.org + username=jaraco + password=pity% + """)) + cfg = setuptools.package_index.PyPIConfig() + cred = cfg.creds_by_repository['pypi'] + assert cred.username == 'jaraco' + assert cred.password == 'pity%' -- cgit v1.2.1 From 477fef2d71db14b82d74ea73f4f90e02876d1967 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Mon, 14 Dec 2015 04:51:03 -0500 Subject: Add test capturing InterpolationSyntaxError on Python 3. Ref #442 --- setuptools/tests/test_packageindex.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_packageindex.py b/setuptools/tests/test_packageindex.py index 897590e8..746860d5 100644 --- a/setuptools/tests/test_packageindex.py +++ b/setuptools/tests/test_packageindex.py @@ -219,6 +219,6 @@ class TestPyPIConfig: password=pity% """)) cfg = setuptools.package_index.PyPIConfig() - cred = cfg.creds_by_repository['pypi'] + cred = cfg.creds_by_repository['https://pypi.python.org'] assert cred.username == 'jaraco' assert cred.password == 'pity%' -- cgit v1.2.1 From ca4321bb5833e2daa7bee1a32a3dee37cb49f012 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Mon, 14 Dec 2015 04:55:43 -0500 Subject: Use the modern name for the configparser module --- setuptools/command/easy_install.py | 8 ++++---- setuptools/command/setopt.py | 4 ++-- setuptools/compat.py | 4 ++-- setuptools/package_index.py | 6 +++--- 4 files changed, 11 insertions(+), 11 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 79f068b1..9ca3b515 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -1402,7 +1402,7 @@ def expand_paths(inputs): def extract_wininst_cfg(dist_filename): """Extract configuration data from a bdist_wininst .exe - Returns a ConfigParser.RawConfigParser, or None + Returns a configparser.RawConfigParser, or None """ f = open(dist_filename, 'rb') try: @@ -1415,7 +1415,7 @@ def extract_wininst_cfg(dist_filename): return None f.seek(prepended - 12) - from setuptools.compat import StringIO, ConfigParser + from setuptools.compat import StringIO, configparser import struct tag, cfglen, bmlen = struct.unpack(" Date: Mon, 14 Dec 2015 05:31:46 -0500 Subject: Use SafeConfigParser in PyPIConfig file. Allows percent signs to be specified using two percent signs. Fixes #442. --- setuptools/package_index.py | 4 ++-- setuptools/tests/test_packageindex.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'setuptools') diff --git a/setuptools/package_index.py b/setuptools/package_index.py index a26b58bc..322f9a61 100755 --- a/setuptools/package_index.py +++ b/setuptools/package_index.py @@ -945,14 +945,14 @@ class Credential(object): def __str__(self): return '%(username)s:%(password)s' % vars(self) -class PyPIConfig(configparser.ConfigParser): +class PyPIConfig(configparser.SafeConfigParser): def __init__(self): """ Load from ~/.pypirc """ defaults = dict.fromkeys(['username', 'password', 'repository'], '') - configparser.ConfigParser.__init__(self, defaults) + configparser.SafeConfigParser.__init__(self, defaults) rc = os.path.join(os.path.expanduser('~'), '.pypirc') if os.path.exists(rc): diff --git a/setuptools/tests/test_packageindex.py b/setuptools/tests/test_packageindex.py index 746860d5..a3e45adc 100644 --- a/setuptools/tests/test_packageindex.py +++ b/setuptools/tests/test_packageindex.py @@ -216,7 +216,7 @@ class TestPyPIConfig: [pypi] repository=https://pypi.python.org username=jaraco - password=pity% + password=pity%% """)) cfg = setuptools.package_index.PyPIConfig() cred = cfg.creds_by_repository['https://pypi.python.org'] -- cgit v1.2.1 From fbcbb51009bc76df9f2c66547439474799b9ab15 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Mon, 14 Dec 2015 05:38:30 -0500 Subject: Use RawConfigParser instead of SafeConfigParser in PyPIConfig class. Interpolated values are no longer supported. Since backward compatibility could not be retained in either case, prefer the simpler, more direct format. Ref #442. --- setuptools/package_index.py | 4 ++-- setuptools/tests/test_packageindex.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'setuptools') diff --git a/setuptools/package_index.py b/setuptools/package_index.py index 322f9a61..2c565e88 100755 --- a/setuptools/package_index.py +++ b/setuptools/package_index.py @@ -945,14 +945,14 @@ class Credential(object): def __str__(self): return '%(username)s:%(password)s' % vars(self) -class PyPIConfig(configparser.SafeConfigParser): +class PyPIConfig(configparser.RawConfigParser): def __init__(self): """ Load from ~/.pypirc """ defaults = dict.fromkeys(['username', 'password', 'repository'], '') - configparser.SafeConfigParser.__init__(self, defaults) + configparser.RawConfigParser.__init__(self, defaults) rc = os.path.join(os.path.expanduser('~'), '.pypirc') if os.path.exists(rc): diff --git a/setuptools/tests/test_packageindex.py b/setuptools/tests/test_packageindex.py index a3e45adc..746860d5 100644 --- a/setuptools/tests/test_packageindex.py +++ b/setuptools/tests/test_packageindex.py @@ -216,7 +216,7 @@ class TestPyPIConfig: [pypi] repository=https://pypi.python.org username=jaraco - password=pity%% + password=pity% """)) cfg = setuptools.package_index.PyPIConfig() cred = cfg.creds_by_repository['https://pypi.python.org'] -- cgit v1.2.1 From 4765b89927b56b4ae8758b18d8cdd822d9007dae Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 15 Dec 2015 19:47:38 -0500 Subject: Bumped to 19.0 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index 067c5e37..3b7740f1 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '18.8.2' +__version__ = '19.0' -- cgit v1.2.1 From 627d4b47c20ca79cd3ce1bb99d1b54ccf457a561 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 15 Dec 2015 19:49:02 -0500 Subject: Bumped to 19.1 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index 3b7740f1..a4bfb3ca 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '19.0' +__version__ = '19.1' -- cgit v1.2.1 From cfcfccb6c78490ed368fa08d7ee84418ac4706a6 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 16 Dec 2015 08:19:26 -0500 Subject: Bumped to 19.2 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index a4bfb3ca..16f3f638 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '19.1' +__version__ = '19.2' -- cgit v1.2.1 From 79d6a93283b6fab9a1aa8f63a0024eff43f88716 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 16 Dec 2015 19:27:29 -0500 Subject: Bumped to 19.1.1 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index 16f3f638..1ed11507 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '19.2' +__version__ = '19.1.1' -- cgit v1.2.1 From 8a91baa090870aa3e70ea26c716ccde955ec1381 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 16 Dec 2015 19:29:18 -0500 Subject: Bumped to 19.1.2 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index 1ed11507..961ff96e 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '19.1.1' +__version__ = '19.1.2' -- cgit v1.2.1 From 3f4ef89512da6a3e89f27121446ec59773869017 Mon Sep 17 00:00:00 2001 From: Erik Bray Date: Wed, 23 Dec 2015 14:07:40 -0500 Subject: Fix failing test on Windows due to path separator --- setuptools/tests/test_setuptools.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_setuptools.py b/setuptools/tests/test_setuptools.py index 8aca593a..e59800d2 100644 --- a/setuptools/tests/test_setuptools.py +++ b/setuptools/tests/test_setuptools.py @@ -23,7 +23,7 @@ def test_findall(example_source): def test_findall_curdir(example_source): with example_source.as_cwd(): found = list(setuptools.findall()) - expected = ['readme.txt', 'foo/bar.py'] + expected = ['readme.txt', os.path.join('foo', 'bar.py')] assert found == expected -- cgit v1.2.1 From 2f2011b3d9e21861f003181ab0c3abb9701df83b Mon Sep 17 00:00:00 2001 From: Erik Bray Date: Thu, 24 Dec 2015 15:45:14 -0500 Subject: Fix failing test on Windows due to path formatting bugs --- setuptools/tests/test_easy_install.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py index 00e16b63..f0330f17 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -446,10 +446,15 @@ class TestScriptHeader: exe = tmpdir / 'exe.py' with exe.open('w') as f: f.write(header) - exe = str(exe) + + 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=exe) + executable=executable) assert header == '#!/usr/bin/env %s\n' % exe expect_out = 'stdout' if sys.version_info < (2,7) else 'stderr' @@ -458,7 +463,7 @@ class TestScriptHeader: # When options are included, generate a broken shebang line # with a warning emitted candidate = ei.ScriptWriter.get_script_header('#!/usr/bin/python -x', - executable=exe) + executable=executable) assert candidate == '#!%s -x\n' % exe output = locals()[expect_out] assert 'Unable to adapt shebang line' in output.getvalue() -- cgit v1.2.1 From 9578a0f640dac57f95a391c9f2a1ebdaba1a0846 Mon Sep 17 00:00:00 2001 From: Erik Bray Date: Thu, 24 Dec 2015 16:16:19 -0500 Subject: Prevent exception in atexit handlers when cert store's tempfile is already cleaned up by py.test. --- setuptools/ssl_support.py | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'setuptools') diff --git a/setuptools/ssl_support.py b/setuptools/ssl_support.py index cc7db067..7394f4f5 100644 --- a/setuptools/ssl_support.py +++ b/setuptools/ssl_support.py @@ -223,6 +223,12 @@ def get_win_certfile(): self.addcerts(certs) atexit.register(self.close) + def close(self): + try: + super(MyCertFile, self).close() + except OSError: + pass + _wincerts = MyCertFile(stores=['CA', 'ROOT']) return _wincerts.name -- cgit v1.2.1 From f4ad85091ab6a78134de046ef5c7a57cffa273ac Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 25 Dec 2015 10:28:25 -0500 Subject: Wrap the result in a DirList to avoid tuple unpacking and unused variables --- setuptools/tests/test_egg_info.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_egg_info.py b/setuptools/tests/test_egg_info.py index 74beb7f5..333d11d6 100644 --- a/setuptools/tests/test_egg_info.py +++ b/setuptools/tests/test_egg_info.py @@ -60,7 +60,7 @@ class TestEggInfo(object): self._create_project() self._run_install_command(tmpdir_cwd, env) - _, actual = self._find_egg_info_files(env.paths['lib']) + actual = self._find_egg_info_files(env.paths['lib']) expected = [ 'PKG-INFO', @@ -83,7 +83,7 @@ class TestEggInfo(object): } }) self._run_install_command(tmpdir_cwd, env) - egg_info_dir, _ = self._find_egg_info_files(env.paths['lib']) + egg_info_dir = self._find_egg_info_files(env.paths['lib']).base sources_txt = os.path.join(egg_info_dir, 'SOURCES.txt') assert 'docs/usage.rst' in open(sources_txt).read().split('\n') @@ -108,8 +108,13 @@ class TestEggInfo(object): raise AssertionError(data) def _find_egg_info_files(self, root): + class DirList(list): + def __init__(self, files, base): + super(DirList, self).__init__(files) + self.base = base + results = ( - (dirpath, filenames) + DirList(filenames, dirpath) for dirpath, dirnames, filenames in os.walk(root) if os.path.basename(dirpath) == 'EGG-INFO' ) -- cgit v1.2.1 From c8deca55f387fe2be58842a610aea761d642725c Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 25 Dec 2015 10:52:52 -0500 Subject: Bumped to 19.2 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index 961ff96e..16f3f638 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '19.1.2' +__version__ = '19.2' -- cgit v1.2.1 From 6bdbe8957d8c8d293e3fea3fa4baf45eb7c3a3a4 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 25 Dec 2015 10:54:28 -0500 Subject: Bumped to 19.3 in preparation for next release. --- setuptools/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/version.py b/setuptools/version.py index 16f3f638..09bbb730 100644 --- a/setuptools/version.py +++ b/setuptools/version.py @@ -1 +1 @@ -__version__ = '19.2' +__version__ = '19.3' -- cgit v1.2.1