From 67ee093341a7342fcbe29dd99800c373abd872a0 Mon Sep 17 00:00:00 2001 From: Paulo Koch Date: Tue, 11 Oct 2011 18:25:09 +0100 Subject: Add support for git URLs. --HG-- branch : distribute extra : rebase_source : f664e8cf2b7b6f78096cd00463f4e2009bdeb3ac --- setuptools/package_index.py | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'setuptools') diff --git a/setuptools/package_index.py b/setuptools/package_index.py index d0896feb..da586a27 100755 --- a/setuptools/package_index.py +++ b/setuptools/package_index.py @@ -657,6 +657,8 @@ class PackageIndex(Environment): # if scheme=='svn' or scheme.startswith('svn+'): return self._download_svn(url, filename) + elif scheme=='git' or scheme.startswith('git+'): + return self._download_git(url, filename) elif scheme=='file': return urllib.url2pathname(urlparse.urlparse(url)[2]) else: @@ -697,6 +699,15 @@ class PackageIndex(Environment): os.system("svn checkout -q %s %s" % (url, filename)) return filename + def _download_git(self, url, filename): + if url.startswith('git+'): + url = url[4:] + url = url.split('#',1)[0] # remove any fragment for svn's sake + filename = filename.split('#',1)[0] # remove any fragment to get a decent name. + self.info("Doing git clone from %s to %s", url, filename) + os.system("git clone -q %s %s" % (url, filename)) + return filename + def debug(self, msg, *args): log.debug(msg, *args) -- cgit v1.2.3 From 930b2596aaa267e9ba28bb5a1066b20d9e0fcfeb Mon Sep 17 00:00:00 2001 From: Paulo Koch Date: Tue, 11 Oct 2011 20:08:25 +0100 Subject: Add support for Mercurial URLs. --HG-- branch : distribute extra : rebase_source : 7c33d5bea70d9300cff635646988b13c007e24c9 --- setuptools/package_index.py | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'setuptools') diff --git a/setuptools/package_index.py b/setuptools/package_index.py index da586a27..cd89e9a6 100755 --- a/setuptools/package_index.py +++ b/setuptools/package_index.py @@ -659,6 +659,8 @@ class PackageIndex(Environment): return self._download_svn(url, filename) elif scheme=='git' or scheme.startswith('git+'): return self._download_git(url, filename) + elif scheme.startswith('hg+'): + return self._download_hg(url, filename) elif scheme=='file': return urllib.url2pathname(urlparse.urlparse(url)[2]) else: @@ -708,6 +710,15 @@ class PackageIndex(Environment): os.system("git clone -q %s %s" % (url, filename)) return filename + def _download_hg(self, url, filename): + if url.startswith('hg+'): + url = url[3:] + url = url.split('#',1)[0] # remove any fragment for svn's sake + filename = filename.split('#',1)[0] # remove any fragment to get a decent name. + self.info("Doing hg clone from %s to %s", url, filename) + os.system("hg clone --quiet %s %s" % (url, filename)) + return filename + def debug(self, msg, *args): log.debug(msg, *args) -- cgit v1.2.3 From ad445467dd7ddd5e69165fa38b83d303c096f132 Mon Sep 17 00:00:00 2001 From: Jonathan Lange Date: Fri, 10 Aug 2012 12:49:20 +0100 Subject: Set permissions when extracting from zipfile. --HG-- branch : distribute extra : rebase_source : 68b7fd4d6cc28f77a7202c5e7f63121d721be624 --- setuptools/archive_util.py | 1 + 1 file changed, 1 insertion(+) (limited to 'setuptools') diff --git a/setuptools/archive_util.py b/setuptools/archive_util.py index 5787753f..8ad14752 100755 --- a/setuptools/archive_util.py +++ b/setuptools/archive_util.py @@ -158,6 +158,7 @@ def unpack_zipfile(filename, extract_dir, progress_filter=default_filter): finally: f.close() del data + os.chmod(target, info.external_attr >> 16) finally: z.close() -- cgit v1.2.3 From dbbfab8fe8a8c146c2353f751d617c8761f6ddc4 Mon Sep 17 00:00:00 2001 From: Erik Bray Date: Tue, 11 Sep 2012 13:53:29 -0400 Subject: Fixes and adds a regression test for #323; required adding some new keyword arguments to existing pkg_resources methods. Also had to update how __path__ is handled for namespace packages to ensure that when a new egg distribution containing a namespace package is placed on sys.path, the entries in __path__ are in the same order they would have been in had that egg been on the path when pkg_resources was first imported --HG-- branch : distribute extra : rebase_source : 63a120c9397f6619d2768ec982e5c6b664c97e40 --- setuptools/dist.py | 5 +- setuptools/tests/test_easy_install.py | 142 +++++++++++++++++++++++++--------- 2 files changed, 107 insertions(+), 40 deletions(-) (limited to 'setuptools') diff --git a/setuptools/dist.py b/setuptools/dist.py index 6607cf7b..2061c0a2 100644 --- a/setuptools/dist.py +++ b/setuptools/dist.py @@ -242,9 +242,10 @@ class Distribution(_Distribution): """Resolve pre-setup requirements""" from pkg_resources import working_set, parse_requirements for dist in working_set.resolve( - parse_requirements(requires), installer=self.fetch_build_egg + parse_requirements(requires), installer=self.fetch_build_egg, + replace_conflicting=True ): - working_set.add(dist) + working_set.add(dist, replace=True) def finalize_options(self): _Distribution.finalize_options(self) diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py index e49c6f49..1540bdc6 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -17,8 +17,10 @@ from setuptools.command.easy_install import easy_install, get_script_args, main 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 Distribution as PRDistribution import setuptools.tests.server +import pkg_resources try: # import multiprocessing solely for the purpose of testing its existence @@ -273,48 +275,16 @@ class TestUserInstallTest(unittest.TestCase): SandboxViolation. """ - test_setup_attrs = { - 'name': 'test_pkg', 'version': '0.0', - 'setup_requires': ['foobar'], - 'dependency_links': [os.path.abspath(self.dir)] - } - - test_pkg = os.path.join(self.dir, 'test_pkg') + test_pkg = create_setup_requires_package(self.dir) test_setup_py = os.path.join(test_pkg, 'setup.py') - test_setup_cfg = os.path.join(test_pkg, 'setup.cfg') - os.mkdir(test_pkg) - f = open(test_setup_py, 'w') - f.write(textwrap.dedent("""\ - import setuptools - setuptools.setup(**%r) - """ % test_setup_attrs)) - f.close() - - foobar_path = os.path.join(self.dir, 'foobar-0.1.tar.gz') - make_trivial_sdist( - foobar_path, - textwrap.dedent("""\ - import setuptools - setuptools.setup( - name='foobar', - version='0.1' - ) - """)) - - old_stdout = sys.stdout - old_stderr = sys.stderr - sys.stdout = StringIO.StringIO() - sys.stderr = StringIO.StringIO() try: - reset_setup_stop_context( - lambda: run_setup(test_setup_py, ['install']) - ) + quiet_context( + lambda: reset_setup_stop_context( + lambda: run_setup(test_setup_py, ['install']) + )) except SandboxViolation: self.fail('Installation caused SandboxViolation') - finally: - sys.stdout = old_stdout - sys.stderr = old_stderr class TestSetupRequires(unittest.TestCase): @@ -360,7 +330,7 @@ class TestSetupRequires(unittest.TestCase): tempdir_context(install_at) # create an sdist that has a build-time dependency. - self.create_sdist(install) + quiet_context(lambda: self.create_sdist(install)) # there should have been two or three requests to the server # (three happens on Python 3.3a) @@ -387,6 +357,81 @@ class TestSetupRequires(unittest.TestCase): installer(dist_path) tempdir_context(build_sdist) + def test_setup_requires_overrides_version_conflict(self): + """ + Regression test for issue #323. + + Ensures that a distribution's setup_requires requirements can still be + installed and used locally even if a conflicting version of that + requirement is already on the path. + """ + + pr_state = pkg_resources.__getstate__() + fake_dist = PRDistribution('does-not-matter', project_name='foobar', + version='0.0') + working_set.add(fake_dist) + + def setup_and_run(temp_dir): + test_pkg = create_setup_requires_package(temp_dir) + test_setup_py = os.path.join(test_pkg, 'setup.py') + try: + stdout, stderr = quiet_context( + lambda: reset_setup_stop_context( + # Don't even need to install the package, just running + # the setup.py at all is sufficient + lambda: run_setup(test_setup_py, ['--name']) + )) + except VersionConflict: + self.fail('Installing setup.py requirements caused ' + 'VersionConflict') + + lines = stdout.splitlines() + self.assertGreater(len(lines), 0) + self.assert_(lines[-1].strip(), 'test_pkg') + + try: + tempdir_context(setup_and_run) + finally: + pkg_resources.__setstate__(pr_state) + + +def create_setup_requires_package(path): + """Creates a source tree under path for a trivial test package that has a + single requirement in setup_requires--a tarball for that requirement is + also created and added to the dependency_links argument. + """ + + test_setup_attrs = { + 'name': 'test_pkg', 'version': '0.0', + 'setup_requires': ['foobar==0.1'], + 'dependency_links': [os.path.abspath(path)] + } + + test_pkg = os.path.join(path, 'test_pkg') + test_setup_py = os.path.join(test_pkg, 'setup.py') + test_setup_cfg = os.path.join(test_pkg, 'setup.cfg') + os.mkdir(test_pkg) + + f = open(test_setup_py, 'w') + f.write(textwrap.dedent("""\ + import setuptools + setuptools.setup(**%r) + """ % test_setup_attrs)) + f.close() + + foobar_path = os.path.join(path, 'foobar-0.1.tar.gz') + make_trivial_sdist( + foobar_path, + textwrap.dedent("""\ + import setuptools + setuptools.setup( + name='foobar', + version='0.1' + ) + """)) + + return test_pkg + def make_trivial_sdist(dist_path, setup_py): """Create a simple sdist tarball at dist_path, containing just a @@ -421,6 +466,7 @@ def tempdir_context(f, cd=lambda dir:None): cd(orig_dir) shutil.rmtree(temp_dir) + def environment_context(f, **updates): """ Invoke f in the context @@ -434,6 +480,7 @@ def environment_context(f, **updates): del os.environ[key] os.environ.update(old_env) + def argv_context(f, repl): """ Invoke f in the context @@ -445,6 +492,7 @@ def argv_context(f, repl): finally: sys.argv[:] = old_argv + def reset_setup_stop_context(f): """ When the distribute tests are run using setup.py test, and then @@ -458,3 +506,21 @@ def reset_setup_stop_context(f): f() finally: distutils.core._setup_stop_after = setup_stop_after + + +def quiet_context(f): + """ + Redirect stdout/stderr to StringIO objects to prevent console output from + distutils commands. + """ + + old_stdout = sys.stdout + old_stderr = sys.stderr + new_stdout = sys.stdout = StringIO.StringIO() + new_stderr = sys.stderr = StringIO.StringIO() + try: + f() + finally: + sys.stdout = old_stdout + sys.stderr = old_stderr + return new_stdout.getvalue(), new_stderr.getvalue() -- cgit v1.2.3 From 85097e081f3d987c7acf6ab51e29a307f4f8f167 Mon Sep 17 00:00:00 2001 From: Paulo Koch Date: Thu, 13 Sep 2012 00:19:08 +0100 Subject: Make revision specifiable. --HG-- branch : distribute extra : rebase_source : 059208b9bdcd9a0cf2c2f654f25b638a65f2d9d1 --- setuptools/package_index.py | 49 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 40 insertions(+), 9 deletions(-) (limited to 'setuptools') diff --git a/setuptools/package_index.py b/setuptools/package_index.py index cd89e9a6..e085732d 100755 --- a/setuptools/package_index.py +++ b/setuptools/package_index.py @@ -701,22 +701,53 @@ class PackageIndex(Environment): os.system("svn checkout -q %s %s" % (url, filename)) return filename + def _vcs_split_rev_from_url(self, url, pop_prefix=False): + scheme, netloc, path, query, frag = urlparse.urlsplit(url) + + scheme = scheme.split('+', 1)[-1] + + # Some fragment identification fails + path = path.split('#',1)[0] + + rev = None + if '@' in path: + path, rev = path.rsplit('@', 1) + + # Also, discard fragment + url = urlparse.urlunsplit((scheme, netloc, path, query, '')) + + return url, rev + def _download_git(self, url, filename): - if url.startswith('git+'): - url = url[4:] - url = url.split('#',1)[0] # remove any fragment for svn's sake - filename = filename.split('#',1)[0] # remove any fragment to get a decent name. + filename = filename.split('#',1)[0] + url, rev = self._vcs_split_rev_from_url(url, pop_prefix=True) + self.info("Doing git clone from %s to %s", url, filename) - os.system("git clone -q %s %s" % (url, filename)) + os.system("git clone --quiet %s %s" % (url, filename)) + + if rev is not None: + self.info("Checking out %s", rev) + os.system("(cd %s && git checkout --quiet %s)" % ( + filename, + rev, + )) + return filename def _download_hg(self, url, filename): - if url.startswith('hg+'): - url = url[3:] - url = url.split('#',1)[0] # remove any fragment for svn's sake - filename = filename.split('#',1)[0] # remove any fragment to get a decent name. + filename = filename.split('#',1)[0] + url, rev = self._vcs_split_rev_from_url(url, pop_prefix=True) + self.info("Doing hg clone from %s to %s", url, filename) os.system("hg clone --quiet %s %s" % (url, filename)) + + if rev is not None: + self.info("Updating to %s", rev) + os.system("(cd %s && hg up -C -r %s >&-)" % ( + filename, + rev, + )) + return filename def debug(self, msg, *args): -- cgit v1.2.3 From 6cfedcaaf8d8e65a0686b2d856d2eb95fd6c85bf Mon Sep 17 00:00:00 2001 From: Jonathan Lange Date: Wed, 19 Sep 2012 11:17:36 +0100 Subject: Guard the chmod in case external_attr is 0. --HG-- branch : distribute extra : rebase_source : 79d8c285c70c3cf44273439c5178cfa54b0c3b21 --- setuptools/archive_util.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/archive_util.py b/setuptools/archive_util.py index 8ad14752..e22b25c0 100755 --- a/setuptools/archive_util.py +++ b/setuptools/archive_util.py @@ -158,7 +158,9 @@ def unpack_zipfile(filename, extract_dir, progress_filter=default_filter): finally: f.close() del data - os.chmod(target, info.external_attr >> 16) + unix_attributes = info.external_attr >> 16 + if unix_attributes: + os.chmod(target, unix_attributes) finally: z.close() -- cgit v1.2.3 From 21ead63de1689b99007d0ab9b41a19b09543e7b3 Mon Sep 17 00:00:00 2001 From: "Stefan H. Holek" Date: Mon, 15 Oct 2012 14:48:49 +0200 Subject: Revert 86d7748 drive-by commit because of unclear BBB consequences. --HG-- branch : distribute extra : rebase_source : 2fb9a6ec09184e238551be4d0ea908e719badd27 --- setuptools/command/egg_info.py | 14 -------------- setuptools/tests/test_sdist.py | 38 ++++++++++++-------------------------- 2 files changed, 12 insertions(+), 40 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/egg_info.py b/setuptools/command/egg_info.py index 2dc59187..e1a8c9ad 100755 --- a/setuptools/command/egg_info.py +++ b/setuptools/command/egg_info.py @@ -292,19 +292,6 @@ class FileList(FileList): -def compose(path): - # Apple's HFS Plus returns decomposed UTF-8. Since just about - # everyone else chokes on it, we must make sure to return fully - # composed UTF-8 only. - if sys.getfilesystemencoding().lower() == 'utf-8': - from unicodedata import normalize - if sys.version_info >= (3,): - path = normalize('NFC', path) - else: - path = normalize('NFC', path.decode('utf-8')).encode('utf-8') - return path - - class manifest_maker(sdist): template = "MANIFEST.in" @@ -329,7 +316,6 @@ class manifest_maker(sdist): self.prune_file_list() self.filelist.sort() self.filelist.remove_duplicates() - self.filelist.files = [compose(path) for path in self.filelist.files] self.write_manifest() def write_manifest (self): diff --git a/setuptools/tests/test_sdist.py b/setuptools/tests/test_sdist.py index 7e2f0a49..4478d438 100644 --- a/setuptools/tests/test_sdist.py +++ b/setuptools/tests/test_sdist.py @@ -29,6 +29,17 @@ setup(**%r) """ % SETUP_ATTRS +def compose(path): + # HFS Plus returns decomposed UTF-8 + if sys.platform == 'darwin': + from unicodedata import normalize + if sys.version_info >= (3,): + path = normalize('NFC', path) + else: + path = normalize('NFC', path.decode('utf-8')).encode('utf-8') + return path + + class TestSdistTest(unittest.TestCase): def setUp(self): self.temp_dir = tempfile.mkdtemp() @@ -79,31 +90,6 @@ class TestSdistTest(unittest.TestCase): self.assertTrue(os.path.join('sdist_test', 'b.txt') in manifest) self.assertTrue(os.path.join('sdist_test', 'c.rst') not in manifest) - def test_filelist_is_fully_composed(self): - # Test for #303. Requires HFS Plus to fail. - - # Add file with non-ASCII filename - filename = os.path.join('sdist_test', 'smörbröd.py') - open(filename, 'w').close() - - dist = Distribution(SETUP_ATTRS) - dist.script_name = 'setup.py' - cmd = sdist(dist) - cmd.ensure_finalized() - - # squelch output - old_stdout = sys.stdout - old_stderr = sys.stderr - sys.stdout = StringIO() - sys.stderr = StringIO() - try: - cmd.run() - finally: - sys.stdout = old_stdout - sys.stderr = old_stderr - - self.assertTrue(filename in cmd.filelist.files) - def test_manifest_is_written_in_utf8(self): # Test for #303. @@ -162,7 +148,7 @@ class TestSdistTest(unittest.TestCase): cmd.manifest = os.path.join('sdist_test.egg-info', 'SOURCES.txt') cmd.read_manifest() - self.assertTrue(filename in cmd.filelist.files) + self.assertTrue(filename in [compose(x) for x in cmd.filelist.files]) def test_suite(): -- cgit v1.2.3 From 422682d8c44fb310e3431d56b2ee0a991ced72db Mon Sep 17 00:00:00 2001 From: "Stefan H. Holek" Date: Tue, 16 Oct 2012 13:08:55 +0200 Subject: Don't re-use FileList global name in egg_info.py. --HG-- branch : distribute extra : rebase_source : ac180d4a23ab4fc03c243aa92dd8e6bc42bdabeb --- setuptools/command/egg_info.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/egg_info.py b/setuptools/command/egg_info.py index e1a8c9ad..e1aaa491 100755 --- a/setuptools/command/egg_info.py +++ b/setuptools/command/egg_info.py @@ -9,7 +9,7 @@ from distutils.errors import * from distutils import log from setuptools.command.sdist import sdist from distutils.util import convert_path -from distutils.filelist import FileList +from distutils.filelist import FileList as _FileList from pkg_resources import parse_requirements, safe_name, parse_version, \ safe_version, yield_lines, EntryPoint, iter_entry_points, to_filename from sdist import walk_revctrl @@ -274,7 +274,7 @@ class egg_info(Command): self.broken_egg_info = self.egg_info self.egg_info = bei # make it work for now -class FileList(FileList): +class FileList(_FileList): """File list that accepts only existing, platform-independent paths""" def append(self, item): -- cgit v1.2.3 From b68c62e1cd28a9bedf6c6b8f65c5428361e644a9 Mon Sep 17 00:00:00 2001 From: "Stefan H. Holek" Date: Tue, 16 Oct 2012 17:12:58 +0200 Subject: Fix Python 2.4 incompatibility in test_easy_install.py. --HG-- branch : distribute extra : rebase_source : ba9360ee8ff6c69f2ef589ef7c920fc0c8219b61 --- setuptools/tests/test_easy_install.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py index e49c6f49..64cf1ca4 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -307,11 +307,12 @@ class TestUserInstallTest(unittest.TestCase): sys.stdout = StringIO.StringIO() sys.stderr = StringIO.StringIO() try: - reset_setup_stop_context( - lambda: run_setup(test_setup_py, ['install']) - ) - except SandboxViolation: - self.fail('Installation caused SandboxViolation') + try: + reset_setup_stop_context( + lambda: run_setup(test_setup_py, ['install']) + ) + except SandboxViolation: + self.fail('Installation caused SandboxViolation') finally: sys.stdout = old_stdout sys.stderr = old_stderr -- cgit v1.2.3 From 9d66fb61d9579516c5333d51eb85dc3495e6032f Mon Sep 17 00:00:00 2001 From: "Stefan H. Holek" Date: Wed, 17 Oct 2012 10:54:39 +0200 Subject: Use surrogateescape error handler when reading and writing the manifest. Refs #303. --HG-- branch : distribute extra : rebase_source : f0231cf87e2478f988f798dfe579f28e7561aeff --- setuptools/command/egg_info.py | 2 +- setuptools/command/sdist.py | 2 +- setuptools/tests/test_sdist.py | 256 ++++++++++++++++++++++++++++++++++------- 3 files changed, 214 insertions(+), 46 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/egg_info.py b/setuptools/command/egg_info.py index e1aaa491..9955c8ef 100755 --- a/setuptools/command/egg_info.py +++ b/setuptools/command/egg_info.py @@ -360,7 +360,7 @@ def write_file (filename, contents): """ contents = "\n".join(contents) if sys.version_info >= (3,): - contents = contents.encode("utf-8") + contents = contents.encode("utf-8", "surrogateescape") f = open(filename, "wb") # always write POSIX-style manifest f.write(contents) f.close() diff --git a/setuptools/command/sdist.py b/setuptools/command/sdist.py index d5259c2b..42558143 100755 --- a/setuptools/command/sdist.py +++ b/setuptools/command/sdist.py @@ -283,7 +283,7 @@ class sdist(_sdist): manifest = open(self.manifest, 'rbU') for line in manifest: if sys.version_info >= (3,): - line = line.decode('UTF-8') + line = line.decode('UTF-8', 'surrogateescape') # ignore comments and blank lines line = line.strip() if line.startswith('#') or not line: diff --git a/setuptools/tests/test_sdist.py b/setuptools/tests/test_sdist.py index 4478d438..65b83b6e 100644 --- a/setuptools/tests/test_sdist.py +++ b/setuptools/tests/test_sdist.py @@ -7,10 +7,13 @@ import shutil import sys import tempfile import unittest +import urllib +import unicodedata from StringIO import StringIO from setuptools.command.sdist import sdist +from setuptools.command.egg_info import manifest_maker from setuptools.dist import Distribution @@ -29,18 +32,58 @@ setup(**%r) """ % SETUP_ATTRS -def compose(path): - # HFS Plus returns decomposed UTF-8 - if sys.platform == 'darwin': - from unicodedata import normalize +if sys.version_info >= (3,): + LATIN1_FILENAME = 'smörbröd.py'.encode('latin-1') +else: + LATIN1_FILENAME = 'sm\xf6rbr\xf6d.py' + + +# Cannot use context manager because of Python 2.4 +def quiet(): + global old_stdout, old_stderr + old_stdout, old_stderr = sys.stdout, sys.stderr + sys.stdout, sys.stderr = StringIO(), StringIO() + +def unquiet(): + sys.stdout, sys.stderr = old_stdout, old_stderr + + +# Fake byte literals to shut up Python <= 2.5 +def b(s, encoding='utf-8'): + if sys.version_info >= (3,): + return s.encode(encoding) + return s + + +# HFS Plus returns decomposed UTF-8 +def decompose(path): + if isinstance(path, unicode): + return unicodedata.normalize('NFD', path) + try: + path = path.decode('utf-8') + path = unicodedata.normalize('NFD', path) + path = path.encode('utf-8') + except UnicodeError: + pass # Not UTF-8 + return path + + +# HFS Plus quotes unknown bytes like so: %F6 +def hfs_quote(path): + if isinstance(path, unicode): + raise TypeError('bytes are required') + try: + u = path.decode('utf-8') + except UnicodeDecodeError: + path = urllib.quote(path) # Not UTF-8 + else: if sys.version_info >= (3,): - path = normalize('NFC', path) - else: - path = normalize('NFC', path.decode('utf-8')).encode('utf-8') + path = u return path class TestSdistTest(unittest.TestCase): + def setUp(self): self.temp_dir = tempfile.mkdtemp() f = open(os.path.join(self.temp_dir, 'setup.py'), 'w') @@ -74,81 +117,206 @@ class TestSdistTest(unittest.TestCase): cmd.ensure_finalized() # squelch output - old_stdout = sys.stdout - old_stderr = sys.stderr - sys.stdout = StringIO() - sys.stderr = StringIO() + quiet() try: cmd.run() finally: - sys.stdout = old_stdout - sys.stderr = old_stderr + unquiet() manifest = cmd.filelist.files - self.assertTrue(os.path.join('sdist_test', 'a.txt') in manifest) self.assertTrue(os.path.join('sdist_test', 'b.txt') in manifest) self.assertTrue(os.path.join('sdist_test', 'c.rst') not in manifest) - def test_manifest_is_written_in_utf8(self): + def test_manifest_is_written_with_utf8_encoding(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') - # Add file with non-ASCII filename + # UTF-8 filename filename = os.path.join('sdist_test', 'smörbröd.py') - open(filename, 'w').close() + # Add UTF-8 filename and write manifest + quiet() + try: + mm.run() + mm.filelist.files.append(filename) + mm.write_manifest() + finally: + unquiet() + + manifest = open(mm.manifest, 'rbU') + contents = manifest.read() + manifest.close() + + # The manifest should be UTF-8 encoded + try: + u = contents.decode('UTF-8') + except UnicodeDecodeError, e: + self.fail(e) + + # The manifest should contain the UTF-8 filename + if sys.version_info >= (3,): + self.assertTrue(filename in u) + else: + self.assertTrue(filename in contents) + + def test_manifest_is_written_with_surrogateescape_error_handler(self): + # Test for #303. dist = Distribution(SETUP_ATTRS) dist.script_name = 'setup.py' - cmd = sdist(dist) - cmd.ensure_finalized() + mm = manifest_maker(dist) + mm.manifest = os.path.join('sdist_test.egg-info', 'SOURCES.txt') + os.mkdir('sdist_test.egg-info') - # squelch output - old_stdout = sys.stdout - old_stderr = sys.stderr - sys.stdout = StringIO() - sys.stderr = StringIO() + # Latin-1 filename + filename = os.path.join(b('sdist_test'), LATIN1_FILENAME) + + # Add filename with surrogates and write manifest + quiet() try: - cmd.run() + mm.run() + if sys.version_info >= (3,): + u = filename.decode('utf-8', 'surrogateescape') + mm.filelist.files.append(u) + else: + mm.filelist.files.append(filename) + mm.write_manifest() finally: - sys.stdout = old_stdout - sys.stderr = old_stderr + unquiet() - manifest = open(os.path.join('sdist_test.egg-info', 'SOURCES.txt'), 'rbU') + manifest = open(mm.manifest, 'rbU') contents = manifest.read() manifest.close() - self.assertTrue(len(contents)) - # This must not fail: - contents.decode('UTF-8') + # The manifest should contain the Latin-1 filename + self.assertTrue(filename in contents) - def test_manifest_is_read_in_utf8(self): + def test_manifest_is_read_with_utf8_encoding(self): # Test for #303. + dist = Distribution(SETUP_ATTRS) + dist.script_name = 'setup.py' + cmd = sdist(dist) + cmd.ensure_finalized() - # Add file with non-ASCII filename + # UTF-8 filename filename = os.path.join('sdist_test', 'smörbröd.py') open(filename, 'w').close() + quiet() + try: + cmd.run() + finally: + unquiet() + + # The filelist should contain the UTF-8 filename + if sys.platform == 'darwin': + filename = decompose(filename) + self.assertTrue(filename in cmd.filelist.files) + + def test_manifest_is_read_with_surrogateescape_error_handler(self): + # Test for #303. + + # This is hard to test on HFS Plus because it quotes unknown + # bytes (see previous test). Furthermore, egg_info.FileList + # only appends filenames that os.path.exist. + + # We therefore write the manifest file by hand and check whether + # read_manifest produces a UnicodeDecodeError. + dist = Distribution(SETUP_ATTRS) + dist.script_name = 'setup.py' + cmd = sdist(dist) + cmd.ensure_finalized() + + filename = os.path.join(b('sdist_test'), LATIN1_FILENAME) + + quiet() + try: + cmd.run() + # Add Latin-1 filename to manifest + cmd.manifest = os.path.join('sdist_test.egg-info', 'SOURCES.txt') + manifest = open(cmd.manifest, 'ab') + manifest.write(filename+b('\n')) + manifest.close() + # Re-read manifest + try: + cmd.read_manifest() + except UnicodeDecodeError, e: + self.fail(e) + finally: + unquiet() + + def test_sdist_with_utf8_encoded_filename(self): + # Test for #303. + dist = Distribution(SETUP_ATTRS) + dist.script_name = 'setup.py' + cmd = sdist(dist) + cmd.ensure_finalized() + + # UTF-8 filename + filename = os.path.join(b('sdist_test'), b('smörbröd.py')) + open(filename, 'w').close() + + quiet() + try: + cmd.run() + finally: + unquiet() + + # The filelist should contain the UTF-8 filename + # (in one representation or other) + if sys.version_info >= (3,): + filename = filename.decode(sys.getfilesystemencoding(), 'surrogateescape') + if sys.platform == 'darwin': + filename = decompose(filename) + self.assertTrue(filename in cmd.filelist.files) + + def test_sdist_with_latin1_encoded_filename(self): + # Test for #303. dist = Distribution(SETUP_ATTRS) dist.script_name = 'setup.py' cmd = sdist(dist) cmd.ensure_finalized() - # squelch output - old_stdout = sys.stdout - old_stderr = sys.stderr - sys.stdout = StringIO() - sys.stderr = StringIO() + # Latin-1 filename + filename = os.path.join(b('sdist_test'), LATIN1_FILENAME) + open(filename, 'w').close() + + quiet() try: cmd.run() finally: - sys.stdout = old_stdout - sys.stderr = old_stderr + unquiet() + + # The filelist should contain the Latin-1 filename + # (in one representation or other) + if sys.platform == 'darwin': + filename = hfs_quote(filename) + elif sys.version_info >= (3,): + filename = filename.decode(sys.getfilesystemencoding(), 'surrogateescape') + self.assertTrue(filename in cmd.filelist.files) + + def test_decompose(self): + self.assertNotEqual('smörbröd.py', decompose('smörbröd.py')) - cmd.filelist.files = [] - cmd.manifest = os.path.join('sdist_test.egg-info', 'SOURCES.txt') - cmd.read_manifest() + if sys.version_info >= (3,): + self.assertEqual(len('smörbröd.py'), 11) + self.assertEqual(len(decompose('smörbröd.py')), 13) + else: + self.assertEqual(len('smörbröd.py'), 13) + self.assertEqual(len(decompose('smörbröd.py')), 15) + + def test_hfs_quote(self): + self.assertEqual(hfs_quote(LATIN1_FILENAME), 'sm%F6rbr%F6d.py') - self.assertTrue(filename in [compose(x) for x in cmd.filelist.files]) + # Bytes are required + if sys.version_info >= (3,): + self.assertRaises(TypeError, hfs_quote, 'smörbröd.py') + else: + self.assertRaises(TypeError, hfs_quote, 'smörbröd.py'.decode('utf-8')) def test_suite(): -- cgit v1.2.3 From 197c1c33644d1bae8e58f0fbdbd33b387d8ec0bb Mon Sep 17 00:00:00 2001 From: "Stefan H. Holek" Date: Fri, 19 Oct 2012 04:15:20 +0200 Subject: Miscellaneous updates to the upload_docs command. a) upload_docs now runs build_sphinx to generate documentation. b) The temporary ZIP file is properly disposed of. c) Auth credentials now work under Python 3. Fixes #326. hg record cannot split hunks, thus the large commit. --HG-- branch : distribute extra : rebase_source : 76d81880a2aaeb5b94a1d2388cb838068e4f64e3 --- setuptools/command/upload_docs.py | 128 ++++++++++++++++++++++---------------- 1 file changed, 74 insertions(+), 54 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/upload_docs.py b/setuptools/command/upload_docs.py index 213f7b58..c43b0f42 100644 --- a/setuptools/command/upload_docs.py +++ b/setuptools/command/upload_docs.py @@ -9,10 +9,13 @@ import os import socket import zipfile import httplib -import base64 import urlparse import tempfile import sys +import shutil + +from base64 import standard_b64encode +from pkg_resources import iter_entry_points from distutils import log from distutils.errors import DistutilsOptionError @@ -22,20 +25,18 @@ try: except ImportError: from setuptools.command.upload import upload -_IS_PYTHON3 = sys.version > '3' +if sys.version_info >= (3,): + errors = 'surrogateescape' +else: + errors = 'strict' -try: - bytes -except NameError: - bytes = str -def b(str_or_bytes): - """Return bytes by either encoding the argument as ASCII or simply return - the argument as-is.""" - if not isinstance(str_or_bytes, bytes): - return str_or_bytes.encode('ascii') - else: - return str_or_bytes +# This is not just a replacement for byte literals +# but works as a general purpose encoder +def b(s, encoding='utf-8'): + if isinstance(s, unicode): + return s.encode(encoding, errors) + return s class upload_docs(upload): @@ -51,40 +52,62 @@ class upload_docs(upload): ] boolean_options = upload.boolean_options + def has_sphinx(self): + if self.upload_dir is None: + for ep in iter_entry_points('distutils.commands', 'build_sphinx'): + return True + + sub_commands = [('build_sphinx', has_sphinx)] + def initialize_options(self): upload.initialize_options(self) self.upload_dir = None + self.target_dir = None def finalize_options(self): upload.finalize_options(self) if self.upload_dir is None: - build = self.get_finalized_command('build') - self.upload_dir = os.path.join(build.build_base, 'docs') - self.mkpath(self.upload_dir) - self.ensure_dirname('upload_dir') - self.announce('Using upload directory %s' % self.upload_dir) + if self.has_sphinx(): + build_sphinx = self.get_finalized_command('build_sphinx') + self.target_dir = build_sphinx.builder_target_dir + else: + build = self.get_finalized_command('build') + self.target_dir = os.path.join(build.build_base, 'docs') + else: + self.ensure_dirname('upload_dir') + self.target_dir = self.upload_dir + self.announce('Using upload directory %s' % self.target_dir) - def create_zipfile(self): - name = self.distribution.metadata.get_name() - tmp_dir = tempfile.mkdtemp() - tmp_file = os.path.join(tmp_dir, "%s.zip" % name) - zip_file = zipfile.ZipFile(tmp_file, "w") - for root, dirs, files in os.walk(self.upload_dir): - if root == self.upload_dir and not files: - raise DistutilsOptionError( - "no files found in upload directory '%s'" - % self.upload_dir) - for name in files: - full = os.path.join(root, name) - relative = root[len(self.upload_dir):].lstrip(os.path.sep) - dest = os.path.join(relative, name) - zip_file.write(full, dest) - zip_file.close() - return tmp_file + def create_zipfile(self, filename): + zip_file = zipfile.ZipFile(filename, "w") + try: + self.mkpath(self.target_dir) # just in case + for root, dirs, files in os.walk(self.target_dir): + if root == self.target_dir and not files: + raise DistutilsOptionError( + "no files found in upload directory '%s'" + % self.target_dir) + for name in files: + full = os.path.join(root, name) + relative = root[len(self.target_dir):].lstrip(os.path.sep) + dest = os.path.join(relative, name) + zip_file.write(full, dest) + finally: + zip_file.close() def run(self): - zip_file = self.create_zipfile() - self.upload_file(zip_file) + # Run sub commands + for cmd_name in self.get_sub_commands(): + self.run_command(cmd_name) + + tmp_dir = tempfile.mkdtemp() + name = self.distribution.metadata.get_name() + zip_file = os.path.join(tmp_dir, "%s.zip" % name) + try: + self.create_zipfile(zip_file) + self.upload_file(zip_file) + finally: + shutil.rmtree(tmp_dir) def upload_file(self, filename): content = open(filename, 'rb').read() @@ -95,36 +118,33 @@ class upload_docs(upload): 'content': (os.path.basename(filename), content), } # set up the authentication - credentials = self.username + ':' + self.password - if _IS_PYTHON3: # base64 only works with bytes in Python 3. - encoded_creds = base64.encodebytes(credentials.encode('utf8')) - auth = bytes("Basic ") - else: - encoded_creds = base64.encodestring(credentials) - auth = "Basic " - auth += encoded_creds.strip() + credentials = b(self.username + ':' + self.password) + credentials = standard_b64encode(credentials) + if sys.version_info >= (3,): + credentials = credentials.decode('ascii') + auth = "Basic " + credentials # Build up the MIME payload for the POST data - boundary = b('--------------GHSKFJDLGDS7543FJKLFHRE75642756743254') - sep_boundary = b('\n--') + boundary + boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254' + sep_boundary = b('\n--') + b(boundary) end_boundary = sep_boundary + b('--') body = [] - for key, values in data.items(): + for key, values in data.iteritems(): + title = '\nContent-Disposition: form-data; name="%s"' % key # handle multiple entries for the same name if type(values) != type([]): values = [values] for value in values: if type(value) is tuple: - fn = b(';filename="%s"' % value[0]) + title += '; filename="%s"' % value[0] value = value[1] else: - fn = b("") + value = b(value) body.append(sep_boundary) - body.append(b('\nContent-Disposition: form-data; name="%s"'%key)) - body.append(fn) + body.append(b(title)) body.append(b("\n\n")) - body.append(b(value)) - if value and value[-1] == b('\r'): + body.append(value) + if value and value[-1:] == b('\r'): body.append(b('\n')) # write an extra newline (lurve Macs) body.append(end_boundary) body.append(b("\n")) -- cgit v1.2.3 From 47598ca259c8870efa3061144493758c187deb3d Mon Sep 17 00:00:00 2001 From: "Stefan H. Holek" Date: Fri, 19 Oct 2012 11:35:52 +0200 Subject: Fix a test broken by 984cedb. --HG-- branch : distribute extra : rebase_source : f9fe65a5b00a1a64f812aa99716cc913a4b39188 --- setuptools/tests/test_upload_docs.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_upload_docs.py b/setuptools/tests/test_upload_docs.py index 8b2dc892..fddb755d 100644 --- a/setuptools/tests/test_upload_docs.py +++ b/setuptools/tests/test_upload_docs.py @@ -54,12 +54,17 @@ class TestUploadDocsTest(unittest.TestCase): cmd = upload_docs(dist) cmd.upload_dir = self.upload_dir - zip_file = cmd.create_zipfile() + cmd.target_dir = self.upload_dir + tmp_dir = tempfile.mkdtemp() + tmp_file = os.path.join(tmp_dir, 'foo.zip') + try: + zip_file = cmd.create_zipfile(tmp_file) - assert zipfile.is_zipfile(zip_file) + assert zipfile.is_zipfile(tmp_file) - zip_f = zipfile.ZipFile(zip_file) # woh... - - assert zip_f.namelist() == ['index.html'] + zip_file = zipfile.ZipFile(tmp_file) # woh... + assert zip_file.namelist() == ['index.html'] + finally: + shutil.rmtree(tmp_dir) -- cgit v1.2.3 From 152931a9f0fc509eab7d3c10934f6d3137651104 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 21 Oct 2012 03:38:07 -0400 Subject: Fix failing test case on Windows (can't rmtree if a file is open in that tree) --HG-- branch : distribute extra : rebase_source : 99e78b88c18007b410c0be28237db8341413e334 --- setuptools/tests/test_upload_docs.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'setuptools') diff --git a/setuptools/tests/test_upload_docs.py b/setuptools/tests/test_upload_docs.py index fddb755d..769f16cc 100644 --- a/setuptools/tests/test_upload_docs.py +++ b/setuptools/tests/test_upload_docs.py @@ -65,6 +65,8 @@ class TestUploadDocsTest(unittest.TestCase): zip_file = zipfile.ZipFile(tmp_file) # woh... assert zip_file.namelist() == ['index.html'] + + zip_file.close() finally: shutil.rmtree(tmp_dir) -- cgit v1.2.3 From 44db905fd2d3c3a8cd7218a1c45cf54d353ed9ea Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 21 Oct 2012 03:49:51 -0400 Subject: Fix two failing tests on Windows (paths separated by backslash didn't match manifest paths separated by slash). --HG-- branch : distribute extra : rebase_source : f8cd5491fcfe18f687a67423bb8ccc43d3d76672 --- setuptools/tests/test_sdist.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_sdist.py b/setuptools/tests/test_sdist.py index 65b83b6e..347e0085 100644 --- a/setuptools/tests/test_sdist.py +++ b/setuptools/tests/test_sdist.py @@ -9,6 +9,7 @@ import tempfile import unittest import urllib import unicodedata +import posixpath from StringIO import StringIO @@ -137,7 +138,7 @@ class TestSdistTest(unittest.TestCase): os.mkdir('sdist_test.egg-info') # UTF-8 filename - filename = os.path.join('sdist_test', 'smörbröd.py') + filename = posixpath.join('sdist_test', 'smörbröd.py') # Add UTF-8 filename and write manifest quiet() @@ -173,7 +174,7 @@ class TestSdistTest(unittest.TestCase): os.mkdir('sdist_test.egg-info') # Latin-1 filename - filename = os.path.join(b('sdist_test'), LATIN1_FILENAME) + filename = posixpath.join(b('sdist_test'), LATIN1_FILENAME) # Add filename with surrogates and write manifest quiet() -- cgit v1.2.3 From a3966d17f6f7f0769b83d5ef56fc8f97f6a4b415 Mon Sep 17 00:00:00 2001 From: Arfrever Frehtes Taifersar Arahesis Date: Wed, 24 Oct 2012 03:19:23 +0200 Subject: Issue #329: Properly close files created by tests for compatibility with Jython. --HG-- branch : distribute extra : rebase_source : 09c503106ef73b7694e13443ae899666652922a4 --- setuptools/tests/test_dist_info.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_dist_info.py b/setuptools/tests/test_dist_info.py index 623ccc47..fcb78c36 100644 --- a/setuptools/tests/test_dist_info.py +++ b/setuptools/tests/test_dist_info.py @@ -50,7 +50,8 @@ class TestDistInfo(unittest.TestCase): versioned = os.path.join(self.tmpdir, 'VersionedDistribution-2.718.dist-info') os.mkdir(versioned) - open(os.path.join(versioned, 'METADATA'), 'w+').write(DALS( + metadata_file = open(os.path.join(versioned, 'METADATA'), 'w+') + metadata_file.write(DALS( """ Metadata-Version: 1.2 Name: VersionedDistribution @@ -58,11 +59,13 @@ class TestDistInfo(unittest.TestCase): Provides-Extra: baz Requires-Dist: quux (>=1.1); extra == 'baz' """)) + metadata_file.close() unversioned = os.path.join(self.tmpdir, 'UnversionedDistribution.dist-info') os.mkdir(unversioned) - open(os.path.join(unversioned, 'METADATA'), 'w+').write(DALS( + metadata_file = open(os.path.join(unversioned, 'METADATA'), 'w+') + metadata_file.write(DALS( """ Metadata-Version: 1.2 Name: UnversionedDistribution @@ -71,6 +74,7 @@ class TestDistInfo(unittest.TestCase): Provides-Extra: baz Requires-Dist: quux (>=1.1); extra == 'baz' """)) + metadata_file.close() def tearDown(self): shutil.rmtree(self.tmpdir) -- cgit v1.2.3 From 3b26424a5a614cbed17f17591f91ec453be9d038 Mon Sep 17 00:00:00 2001 From: "Stefan H. Holek" Date: Thu, 25 Oct 2012 23:45:25 +0200 Subject: When writing the manifest under Python 3, skip filenames that cannot be encoded to UTF-8. --HG-- branch : distribute extra : rebase_source : f1b439267fce37754aac49af15a9e26346950a26 --- setuptools/command/egg_info.py | 14 +++++++++++++- setuptools/command/sdist.py | 2 +- 2 files changed, 14 insertions(+), 2 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/egg_info.py b/setuptools/command/egg_info.py index 9955c8ef..6e3d67af 100755 --- a/setuptools/command/egg_info.py +++ b/setuptools/command/egg_info.py @@ -323,6 +323,18 @@ class manifest_maker(sdist): by 'add_defaults()' and 'read_template()') to the manifest file named by 'self.manifest'. """ + # The manifest must be UTF-8 encodable. See #303. + if sys.version_info >= (3,): + files = [] + for file in self.filelist.files: + try: + file.encode("utf-8") + except UnicodeEncodeError: + log.warn("'%s' not UTF-8 encodable -- skipping" % file) + else: + files.append(file) + self.filelist.files = files + files = self.filelist.files if os.sep!='/': files = [f.replace(os.sep,'/') for f in files] @@ -360,7 +372,7 @@ def write_file (filename, contents): """ contents = "\n".join(contents) if sys.version_info >= (3,): - contents = contents.encode("utf-8", "surrogateescape") + contents = contents.encode("utf-8") f = open(filename, "wb") # always write POSIX-style manifest f.write(contents) f.close() diff --git a/setuptools/command/sdist.py b/setuptools/command/sdist.py index 42558143..d5259c2b 100755 --- a/setuptools/command/sdist.py +++ b/setuptools/command/sdist.py @@ -283,7 +283,7 @@ class sdist(_sdist): manifest = open(self.manifest, 'rbU') for line in manifest: if sys.version_info >= (3,): - line = line.decode('UTF-8', 'surrogateescape') + line = line.decode('UTF-8') # ignore comments and blank lines line = line.strip() if line.startswith('#') or not line: -- cgit v1.2.3 From 383ad7a4f7a1832cf74c250cdae5b63fa4ad61bb Mon Sep 17 00:00:00 2001 From: "Stefan H. Holek" Date: Thu, 25 Oct 2012 23:45:35 +0200 Subject: Update tests. --HG-- branch : distribute extra : rebase_source : 831e694725e5db1bc360298fbc4b7b58db836bdd --- setuptools/tests/test_sdist.py | 220 ++++++++++++++++++++++------------------- 1 file changed, 121 insertions(+), 99 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_sdist.py b/setuptools/tests/test_sdist.py index 347e0085..a3fde026 100644 --- a/setuptools/tests/test_sdist.py +++ b/setuptools/tests/test_sdist.py @@ -9,7 +9,6 @@ import tempfile import unittest import urllib import unicodedata -import posixpath from StringIO import StringIO @@ -49,14 +48,22 @@ def unquiet(): sys.stdout, sys.stderr = old_stdout, old_stderr -# Fake byte literals to shut up Python <= 2.5 +# Fake byte literals for Python <= 2.5 def b(s, encoding='utf-8'): if sys.version_info >= (3,): return s.encode(encoding) return s -# HFS Plus returns decomposed UTF-8 +# Convert to POSIX path +def posix(path): + if sys.version_info >= (3,) and not isinstance(path, str): + return path.replace(os.sep.encode('ascii'), b('/')) + else: + return path.replace(os.sep, '/') + + +# HFS Plus uses decomposed UTF-8 def decompose(path): if isinstance(path, unicode): return unicodedata.normalize('NFD', path) @@ -69,20 +76,6 @@ def decompose(path): return path -# HFS Plus quotes unknown bytes like so: %F6 -def hfs_quote(path): - if isinstance(path, unicode): - raise TypeError('bytes are required') - try: - u = path.decode('utf-8') - except UnicodeDecodeError: - path = urllib.quote(path) # Not UTF-8 - else: - if sys.version_info >= (3,): - path = u - return path - - class TestSdistTest(unittest.TestCase): def setUp(self): @@ -138,7 +131,7 @@ class TestSdistTest(unittest.TestCase): os.mkdir('sdist_test.egg-info') # UTF-8 filename - filename = posixpath.join('sdist_test', 'smörbröd.py') + filename = os.path.join('sdist_test', 'smörbröd.py') # Add UTF-8 filename and write manifest quiet() @@ -155,46 +148,94 @@ class TestSdistTest(unittest.TestCase): # The manifest should be UTF-8 encoded try: - u = contents.decode('UTF-8') + u_contents = contents.decode('UTF-8') except UnicodeDecodeError, e: self.fail(e) # The manifest should contain the UTF-8 filename if sys.version_info >= (3,): - self.assertTrue(filename in u) + self.assertTrue(posix(filename) in u_contents) else: - self.assertTrue(filename in contents) + self.assertTrue(posix(filename) in contents) - def test_manifest_is_written_with_surrogateescape_error_handler(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') + # Python 3 only + if sys.version_info >= (3,): - # Latin-1 filename - filename = posixpath.join(b('sdist_test'), LATIN1_FILENAME) + 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') - # Add filename with surrogates and write manifest - quiet() - try: - mm.run() - if sys.version_info >= (3,): - u = filename.decode('utf-8', 'surrogateescape') - mm.filelist.files.append(u) - else: - mm.filelist.files.append(filename) - mm.write_manifest() - finally: - unquiet() + # UTF-8 filename + filename = os.path.join(b('sdist_test'), b('smörbröd.py')) - manifest = open(mm.manifest, 'rbU') - contents = manifest.read() - manifest.close() + # Add filename and write manifest + quiet() + try: + mm.run() + u_filename = filename.decode('utf-8') + mm.filelist.files.append(u_filename) + # Re-write manifest + mm.write_manifest() + finally: + unquiet() + + manifest = open(mm.manifest, 'rbU') + contents = manifest.read() + manifest.close() + + # The manifest should be UTF-8 encoded + try: + contents.decode('UTF-8') + except UnicodeDecodeError, e: + self.fail(e) + + # The manifest should contain the UTF-8 filename + self.assertTrue(posix(filename) in contents) + + # The filelist should have been updated as well + self.assertTrue(u_filename in mm.filelist.files) - # The manifest should contain the Latin-1 filename - self.assertTrue(filename in contents) + def test_write_manifest_skips_non_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') + + # Latin-1 filename + filename = os.path.join(b('sdist_test'), LATIN1_FILENAME) + + # Add filename with surrogates and write manifest + quiet() + try: + mm.run() + u_filename = filename.decode('utf-8', 'surrogateescape') + mm.filelist.files.append(u_filename) + # Re-write manifest + mm.write_manifest() + finally: + unquiet() + + manifest = open(mm.manifest, 'rbU') + contents = manifest.read() + manifest.close() + + # The manifest should be UTF-8 encoded + try: + contents.decode('UTF-8') + except UnicodeDecodeError, e: + self.fail(e) + + # The Latin-1 filename should have been skipped + self.assertFalse(posix(filename) in contents) + + # The filelist should have been updated as well + self.assertFalse(u_filename in mm.filelist.files) def test_manifest_is_read_with_utf8_encoding(self): # Test for #303. @@ -218,37 +259,37 @@ class TestSdistTest(unittest.TestCase): filename = decompose(filename) self.assertTrue(filename in cmd.filelist.files) - def test_manifest_is_read_with_surrogateescape_error_handler(self): - # Test for #303. + # Python 3 only + if sys.version_info >= (3,): - # This is hard to test on HFS Plus because it quotes unknown - # bytes (see previous test). Furthermore, egg_info.FileList - # only appends filenames that os.path.exist. + def test_read_manifest_rejects_surrogates(self): + # Test for #303. - # We therefore write the manifest file by hand and check whether - # read_manifest produces a UnicodeDecodeError. - dist = Distribution(SETUP_ATTRS) - dist.script_name = 'setup.py' - cmd = sdist(dist) - cmd.ensure_finalized() + # This is hard to test on HFS Plus because it quotes unknown + # bytes (see previous test). Furthermore, egg_info.FileList + # only appends filenames that os.path.exist. - filename = os.path.join(b('sdist_test'), LATIN1_FILENAME) + # We therefore write the manifest file by hand and check whether + # read_manifest produces a UnicodeDecodeError. + dist = Distribution(SETUP_ATTRS) + dist.script_name = 'setup.py' + cmd = sdist(dist) + cmd.ensure_finalized() - quiet() - try: - cmd.run() - # Add Latin-1 filename to manifest - cmd.manifest = os.path.join('sdist_test.egg-info', 'SOURCES.txt') - manifest = open(cmd.manifest, 'ab') - manifest.write(filename+b('\n')) - manifest.close() - # Re-read manifest + filename = os.path.join(b('sdist_test'), LATIN1_FILENAME) + + quiet() try: - cmd.read_manifest() - except UnicodeDecodeError, e: - self.fail(e) - finally: - unquiet() + cmd.run() + # Add Latin-1 filename to manifest + cmd.manifest = os.path.join('sdist_test.egg-info', 'SOURCES.txt') + manifest = open(cmd.manifest, 'ab') + manifest.write(filename+b('\n')) + manifest.close() + finally: + unquiet() + + self.assertRaises(UnicodeDecodeError, cmd.read_manifest) def test_sdist_with_utf8_encoded_filename(self): # Test for #303. @@ -268,9 +309,8 @@ class TestSdistTest(unittest.TestCase): unquiet() # The filelist should contain the UTF-8 filename - # (in one representation or other) if sys.version_info >= (3,): - filename = filename.decode(sys.getfilesystemencoding(), 'surrogateescape') + filename = filename.decode('utf-8') if sys.platform == 'darwin': filename = decompose(filename) self.assertTrue(filename in cmd.filelist.files) @@ -292,32 +332,14 @@ class TestSdistTest(unittest.TestCase): finally: unquiet() - # The filelist should contain the Latin-1 filename - # (in one representation or other) - if sys.platform == 'darwin': - filename = hfs_quote(filename) - elif sys.version_info >= (3,): - filename = filename.decode(sys.getfilesystemencoding(), 'surrogateescape') - self.assertTrue(filename in cmd.filelist.files) - - def test_decompose(self): - self.assertNotEqual('smörbröd.py', decompose('smörbröd.py')) - - if sys.version_info >= (3,): - self.assertEqual(len('smörbröd.py'), 11) - self.assertEqual(len(decompose('smörbröd.py')), 13) - else: - self.assertEqual(len('smörbröd.py'), 13) - self.assertEqual(len(decompose('smörbröd.py')), 15) - - def test_hfs_quote(self): - self.assertEqual(hfs_quote(LATIN1_FILENAME), 'sm%F6rbr%F6d.py') - - # Bytes are required + # The Latin-1 filename should have been skipped if sys.version_info >= (3,): - self.assertRaises(TypeError, hfs_quote, 'smörbröd.py') + filename = filename.decode('latin-1') + self.assertFalse(filename in cmd.filelist.files) else: - self.assertRaises(TypeError, hfs_quote, 'smörbröd.py'.decode('utf-8')) + # No conversion takes place under Python 2 and the + # filename is included. We shall keep it that way for BBB. + self.assertTrue(filename in cmd.filelist.files) def test_suite(): -- cgit v1.2.3 From 22882958087e20839daf0139a94f8411d17d6a2c Mon Sep 17 00:00:00 2001 From: "Stefan H. Holek" Date: Fri, 26 Oct 2012 02:10:14 +0200 Subject: Make sdist tests pass on Windows. --HG-- branch : distribute extra : rebase_source : 9fb51372737224be8d5c50265b04a36f19543572 --- setuptools/tests/test_sdist.py | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_sdist.py b/setuptools/tests/test_sdist.py index a3fde026..378015a8 100644 --- a/setuptools/tests/test_sdist.py +++ b/setuptools/tests/test_sdist.py @@ -308,12 +308,19 @@ class TestSdistTest(unittest.TestCase): finally: unquiet() - # The filelist should contain the UTF-8 filename - if sys.version_info >= (3,): - filename = filename.decode('utf-8') if sys.platform == 'darwin': filename = decompose(filename) - self.assertTrue(filename in cmd.filelist.files) + + if sys.version_info >= (3,): + if sys.platform == 'win32': + # Python 3 mangles the UTF-8 filename + filename = filename.decode('cp1252') + self.assertTrue(filename in cmd.filelist.files) + else: + filename = filename.decode('utf-8') + self.assertTrue(filename in cmd.filelist.files) + else: + self.assertTrue(filename in cmd.filelist.files) def test_sdist_with_latin1_encoded_filename(self): # Test for #303. @@ -332,13 +339,17 @@ class TestSdistTest(unittest.TestCase): finally: unquiet() - # The Latin-1 filename should have been skipped if sys.version_info >= (3,): filename = filename.decode('latin-1') - self.assertFalse(filename in cmd.filelist.files) + if sys.platform == 'win32': + # Latin-1 is similar to Windows-1252 + self.assertTrue(filename in cmd.filelist.files) + else: + # The Latin-1 filename should have been skipped + self.assertFalse(filename in cmd.filelist.files) else: - # No conversion takes place under Python 2 and the - # filename is included. We shall keep it that way for BBB. + # No conversion takes place under Python 2 and the file + # is included. We shall keep it that way for BBB. self.assertTrue(filename in cmd.filelist.files) -- cgit v1.2.3 From f8481f4b522f0fbeafbb36a20dd105497f2623ac Mon Sep 17 00:00:00 2001 From: "Stefan H. Holek" Date: Fri, 26 Oct 2012 02:10:48 +0200 Subject: This one also failed on Windows. --HG-- branch : distribute extra : rebase_source : c26a4318302d55dfdd67d379525e84172b440b82 --- setuptools/package_index.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'setuptools') diff --git a/setuptools/package_index.py b/setuptools/package_index.py index 7a954e21..0ee21e3b 100755 --- a/setuptools/package_index.py +++ b/setuptools/package_index.py @@ -834,9 +834,8 @@ def open_with_auth(url): # Double scheme does not raise on Mac OS X as revealed by a # failing test. We would expect "nonnumeric port". Refs #20. - if sys.platform == 'darwin': - if netloc.endswith(':'): - raise httplib.InvalidURL("nonnumeric port: ''") + if netloc.endswith(':'): + raise httplib.InvalidURL("nonnumeric port: ''") if scheme in ('http', 'https'): auth, host = urllib2.splituser(netloc) -- cgit v1.2.3 From e485c19015d4fced68b25c09ca66a1743d3ab27c Mon Sep 17 00:00:00 2001 From: "Stefan H. Holek" Date: Fri, 26 Oct 2012 12:46:41 +0200 Subject: Keep 'surrogateescape' when reading the manifest, to avoid breaking on bad input. --HG-- branch : distribute extra : rebase_source : 6f894cd508e73fae0ad02860654df5181055ba4d --- setuptools/command/sdist.py | 3 ++- setuptools/tests/test_sdist.py | 9 ++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/sdist.py b/setuptools/command/sdist.py index d5259c2b..79eed214 100755 --- a/setuptools/command/sdist.py +++ b/setuptools/command/sdist.py @@ -283,7 +283,8 @@ class sdist(_sdist): manifest = open(self.manifest, 'rbU') for line in manifest: if sys.version_info >= (3,): - line = line.decode('UTF-8') + # Don't break if surrogates have crept into the manifest + line = line.decode('UTF-8', 'surrogateescape') # ignore comments and blank lines line = line.strip() if line.startswith('#') or not line: diff --git a/setuptools/tests/test_sdist.py b/setuptools/tests/test_sdist.py index 378015a8..04b3db66 100644 --- a/setuptools/tests/test_sdist.py +++ b/setuptools/tests/test_sdist.py @@ -262,7 +262,7 @@ class TestSdistTest(unittest.TestCase): # Python 3 only if sys.version_info >= (3,): - def test_read_manifest_rejects_surrogates(self): + def test_manifest_is_read_with_surrogateescape_error_handler(self): # Test for #303. # This is hard to test on HFS Plus because it quotes unknown @@ -286,11 +286,14 @@ class TestSdistTest(unittest.TestCase): manifest = open(cmd.manifest, 'ab') manifest.write(filename+b('\n')) manifest.close() + # Re-read manifest + try: + cmd.read_manifest() + except UnicodeDecodeError, e: + self.fail(e) finally: unquiet() - self.assertRaises(UnicodeDecodeError, cmd.read_manifest) - def test_sdist_with_utf8_encoded_filename(self): # Test for #303. dist = Distribution(SETUP_ATTRS) -- cgit v1.2.3 From f266bc3745169122fcfcacb781e7e3c70fc58bfb Mon Sep 17 00:00:00 2001 From: "Stefan H. Holek" Date: Thu, 1 Nov 2012 11:47:24 +0100 Subject: Skip undecodable filenames in read_manifest as well. --HG-- branch : distribute extra : rebase_source : 2dda494b1a4758e84dde81cc61170acd0e55d2f2 --- setuptools/command/sdist.py | 7 +++++-- setuptools/tests/test_sdist.py | 8 ++++++-- 2 files changed, 11 insertions(+), 4 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/sdist.py b/setuptools/command/sdist.py index 79eed214..7a6d2b7d 100755 --- a/setuptools/command/sdist.py +++ b/setuptools/command/sdist.py @@ -283,8 +283,11 @@ class sdist(_sdist): manifest = open(self.manifest, 'rbU') for line in manifest: if sys.version_info >= (3,): - # Don't break if surrogates have crept into the manifest - line = line.decode('UTF-8', 'surrogateescape') + try: + line = line.decode('UTF-8') + except UnicodeDecodeError: + log.warn("%r not UTF-8 decodable -- skipping" % line) + continue # ignore comments and blank lines line = line.strip() if line.startswith('#') or not line: diff --git a/setuptools/tests/test_sdist.py b/setuptools/tests/test_sdist.py index 04b3db66..a596f4bd 100644 --- a/setuptools/tests/test_sdist.py +++ b/setuptools/tests/test_sdist.py @@ -262,7 +262,7 @@ class TestSdistTest(unittest.TestCase): # Python 3 only if sys.version_info >= (3,): - def test_manifest_is_read_with_surrogateescape_error_handler(self): + def test_read_manifest_skips_non_utf8_filenames(self): # Test for #303. # This is hard to test on HFS Plus because it quotes unknown @@ -277,6 +277,7 @@ class TestSdistTest(unittest.TestCase): cmd.ensure_finalized() filename = os.path.join(b('sdist_test'), LATIN1_FILENAME) + u_filename = filename.decode('latin-1') quiet() try: @@ -284,7 +285,7 @@ class TestSdistTest(unittest.TestCase): # Add Latin-1 filename to manifest cmd.manifest = os.path.join('sdist_test.egg-info', 'SOURCES.txt') manifest = open(cmd.manifest, 'ab') - manifest.write(filename+b('\n')) + manifest.write(b('\n')+filename) manifest.close() # Re-read manifest try: @@ -294,6 +295,9 @@ class TestSdistTest(unittest.TestCase): finally: unquiet() + # The Latin-1 filename should have been skipped + self.assertFalse(u_filename in cmd.filelist.files) + def test_sdist_with_utf8_encoded_filename(self): # Test for #303. dist = Distribution(SETUP_ATTRS) -- cgit v1.2.3 From 945189affe2ec3d2e25a9255a73bf05b828ab7c3 Mon Sep 17 00:00:00 2001 From: "stefan@epy" Date: Mon, 5 Nov 2012 00:20:39 +0100 Subject: Rewrite tests for read_manifest. --HG-- branch : distribute extra : rebase_source : 8e52687fae6a06e1421c51ddec62870ef7499676 --- setuptools/tests/test_sdist.py | 58 +++++++++++++++++++++++++++--------------- 1 file changed, 38 insertions(+), 20 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_sdist.py b/setuptools/tests/test_sdist.py index a596f4bd..9d2c382f 100644 --- a/setuptools/tests/test_sdist.py +++ b/setuptools/tests/test_sdist.py @@ -57,7 +57,7 @@ def b(s, encoding='utf-8'): # Convert to POSIX path def posix(path): - if sys.version_info >= (3,) and not isinstance(path, str): + if sys.version_info >= (3,) and not isinstance(path, unicode): return path.replace(os.sep.encode('ascii'), b('/')) else: return path.replace(os.sep, '/') @@ -244,19 +244,35 @@ class TestSdistTest(unittest.TestCase): cmd = sdist(dist) cmd.ensure_finalized() - # UTF-8 filename - filename = os.path.join('sdist_test', 'smörbröd.py') + # Create manifest + quiet() + try: + cmd.run() + finally: + unquiet() + + # Add UTF-8 filename to manifest + filename = os.path.join(b('sdist_test'), b('smörbröd.py')) + 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 quiet() try: - cmd.run() + cmd.read_manifest() finally: unquiet() # The filelist should contain the UTF-8 filename if sys.platform == 'darwin': filename = decompose(filename) + if sys.version_info >= (3,): + filename = filename.decode('utf-8') self.assertTrue(filename in cmd.filelist.files) # Python 3 only @@ -264,30 +280,31 @@ class TestSdistTest(unittest.TestCase): def test_read_manifest_skips_non_utf8_filenames(self): # Test for #303. - - # This is hard to test on HFS Plus because it quotes unknown - # bytes (see previous test). Furthermore, egg_info.FileList - # only appends filenames that os.path.exist. - - # We therefore write the manifest file by hand and check whether - # read_manifest produces a UnicodeDecodeError. dist = Distribution(SETUP_ATTRS) dist.script_name = 'setup.py' cmd = sdist(dist) cmd.ensure_finalized() + # Create manifest + quiet() + try: + cmd.run() + finally: + unquiet() + + # Add Latin-1 filename to manifest filename = os.path.join(b('sdist_test'), LATIN1_FILENAME) - u_filename = filename.decode('latin-1') + 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 quiet() try: - cmd.run() - # Add Latin-1 filename to manifest - cmd.manifest = os.path.join('sdist_test.egg-info', 'SOURCES.txt') - manifest = open(cmd.manifest, 'ab') - manifest.write(b('\n')+filename) - manifest.close() - # Re-read manifest try: cmd.read_manifest() except UnicodeDecodeError, e: @@ -296,7 +313,8 @@ class TestSdistTest(unittest.TestCase): unquiet() # The Latin-1 filename should have been skipped - self.assertFalse(u_filename in cmd.filelist.files) + filename = filename.decode('latin-1') + self.assertFalse(filename in cmd.filelist.files) def test_sdist_with_utf8_encoded_filename(self): # Test for #303. -- cgit v1.2.3 From 739d56cdb4f18829de123379488a78cf52e0a6d1 Mon Sep 17 00:00:00 2001 From: "Stefan H. Holek" Date: Mon, 5 Nov 2012 00:26:25 +0100 Subject: No longer decompose filename for comparison. --HG-- branch : distribute extra : rebase_source : 02265fdf50dbe58c41b98e575f1d0d71c95e4bcf --- setuptools/tests/test_sdist.py | 2 -- 1 file changed, 2 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_sdist.py b/setuptools/tests/test_sdist.py index 9d2c382f..cb601d8c 100644 --- a/setuptools/tests/test_sdist.py +++ b/setuptools/tests/test_sdist.py @@ -269,8 +269,6 @@ class TestSdistTest(unittest.TestCase): unquiet() # The filelist should contain the UTF-8 filename - if sys.platform == 'darwin': - filename = decompose(filename) if sys.version_info >= (3,): filename = filename.decode('utf-8') self.assertTrue(filename in cmd.filelist.files) -- cgit v1.2.3 From 19a723890b724f92b8c42b162cea2a4052a746f2 Mon Sep 17 00:00:00 2001 From: "stefan@epy" Date: Mon, 5 Nov 2012 01:35:25 +0100 Subject: Warn if filenames cannot be added to the filelist. --HG-- branch : distribute extra : rebase_source : 9fdc3c28b097e191db384cd81319c7a4edccf52b --- setuptools/command/egg_info.py | 10 ++++++++-- setuptools/tests/test_sdist.py | 2 ++ 2 files changed, 10 insertions(+), 2 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/egg_info.py b/setuptools/command/egg_info.py index 6e3d67af..cf6ef63c 100755 --- a/setuptools/command/egg_info.py +++ b/setuptools/command/egg_info.py @@ -281,8 +281,14 @@ class FileList(_FileList): if item.endswith('\r'): # Fix older sdists built on Windows item = item[:-1] path = convert_path(item) - if os.path.exists(path): - self.files.append(path) + try: + if os.path.exists(path): + self.files.append(path) + else: + log.warn("%r not found -- skipping", path) + except UnicodeEncodeError: + log.warn("%r not %s encodable -- skipping", path, + sys.getfilesystemencoding()) diff --git a/setuptools/tests/test_sdist.py b/setuptools/tests/test_sdist.py index cb601d8c..a9d5d6e5 100644 --- a/setuptools/tests/test_sdist.py +++ b/setuptools/tests/test_sdist.py @@ -262,6 +262,7 @@ class TestSdistTest(unittest.TestCase): open(filename, 'w').close() # Re-read manifest + cmd.filelist.files = [] quiet() try: cmd.read_manifest() @@ -301,6 +302,7 @@ class TestSdistTest(unittest.TestCase): open(filename, 'w').close() # Re-read manifest + cmd.filelist.files = [] quiet() try: try: -- cgit v1.2.3 From 397eda9b80e96fbd1a9fa494e34b6bfda963cdc1 Mon Sep 17 00:00:00 2001 From: "stefan@epy" Date: Mon, 5 Nov 2012 02:21:15 +0100 Subject: Python 3.0 has no surrogateescape. --HG-- branch : distribute extra : rebase_source : 83635f70b89fafb65f630947430b5c315cd9c80a --- setuptools/command/upload_docs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/command/upload_docs.py b/setuptools/command/upload_docs.py index c43b0f42..e21a88ce 100644 --- a/setuptools/command/upload_docs.py +++ b/setuptools/command/upload_docs.py @@ -25,7 +25,7 @@ try: except ImportError: from setuptools.command.upload import upload -if sys.version_info >= (3,): +if sys.version_info >= (3, 1): errors = 'surrogateescape' else: errors = 'strict' -- cgit v1.2.3 From 924d4355aeacd172c32ce6a894f3c141bc363991 Mon Sep 17 00:00:00 2001 From: "Stefan H. Holek" Date: Mon, 5 Nov 2012 11:44:41 +0100 Subject: Don't warn about a missing MANIFEST.in. --HG-- branch : distribute extra : rebase_source : 219c8a4e10da4a319a736c728d162528220d36e1 --- setuptools/command/egg_info.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/command/egg_info.py b/setuptools/command/egg_info.py index cf6ef63c..098dfe84 100755 --- a/setuptools/command/egg_info.py +++ b/setuptools/command/egg_info.py @@ -284,7 +284,7 @@ class FileList(_FileList): try: if os.path.exists(path): self.files.append(path) - else: + elif path != manifest_maker.template: log.warn("%r not found -- skipping", path) except UnicodeEncodeError: log.warn("%r not %s encodable -- skipping", path, -- cgit v1.2.3 From e69eb1098a650ba05b6ef998d8a118cbc10365a7 Mon Sep 17 00:00:00 2001 From: "Stefan H. Holek" Date: Sat, 10 Nov 2012 02:05:17 +0100 Subject: Never skip because of encoding in append. --HG-- branch : distribute extra : rebase_source : 89414e7f828ed2ca2b7118dfd5e17c72ccc44f5b --- 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 098dfe84..ad02cec8 100755 --- a/setuptools/command/egg_info.py +++ b/setuptools/command/egg_info.py @@ -281,14 +281,15 @@ class FileList(_FileList): if item.endswith('\r'): # Fix older sdists built on Windows item = item[:-1] path = convert_path(item) + # Filter unused template files all of which have ASCII names try: + if sys.version_info >= (3,): + path.encode('ascii') + except UnicodeEncodeError: + self.files.append(path) + else: if os.path.exists(path): self.files.append(path) - elif path != manifest_maker.template: - log.warn("%r not found -- skipping", path) - except UnicodeEncodeError: - log.warn("%r not %s encodable -- skipping", path, - sys.getfilesystemencoding()) -- cgit v1.2.3 From 057a7d98522cfb5fbee1c183b9922c919fb782b9 Mon Sep 17 00:00:00 2001 From: "Stefan H. Holek" Date: Sat, 10 Nov 2012 14:18:53 +0100 Subject: Revert yesterday's misguided attempt at being smart. --HG-- branch : distribute extra : rebase_source : 224fb95e8c8ad385a35187c49a102259e03e89a6 --- 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 ad02cec8..098dfe84 100755 --- a/setuptools/command/egg_info.py +++ b/setuptools/command/egg_info.py @@ -281,15 +281,14 @@ class FileList(_FileList): if item.endswith('\r'): # Fix older sdists built on Windows item = item[:-1] path = convert_path(item) - # Filter unused template files all of which have ASCII names try: - if sys.version_info >= (3,): - path.encode('ascii') - except UnicodeEncodeError: - self.files.append(path) - else: if os.path.exists(path): self.files.append(path) + elif path != manifest_maker.template: + log.warn("%r not found -- skipping", path) + except UnicodeEncodeError: + log.warn("%r not %s encodable -- skipping", path, + sys.getfilesystemencoding()) -- cgit v1.2.3 From 98c3a5e71e558a80dafce9b5bb7baf8da9da7ec6 Mon Sep 17 00:00:00 2001 From: "Stefan H. Holek" Date: Sat, 10 Nov 2012 14:47:30 +0100 Subject: Log file not found message at debug level. --HG-- branch : distribute extra : rebase_source : 2c3afe957adc1b3c83f1dfba3d30adf7b0d7b3f3 --- setuptools/command/egg_info.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/command/egg_info.py b/setuptools/command/egg_info.py index 098dfe84..8b29e672 100755 --- a/setuptools/command/egg_info.py +++ b/setuptools/command/egg_info.py @@ -285,7 +285,7 @@ class FileList(_FileList): if os.path.exists(path): self.files.append(path) elif path != manifest_maker.template: - log.warn("%r not found -- skipping", path) + log.debug("%r not found -- skipping", path) except UnicodeEncodeError: log.warn("%r not %s encodable -- skipping", path, sys.getfilesystemencoding()) -- cgit v1.2.3 From b7c5bd34a32f20e54100fd88ede20c136571b1cf Mon Sep 17 00:00:00 2001 From: "Stefan H. Holek" Date: Sat, 10 Nov 2012 17:22:59 +0100 Subject: Windows can store UTF-8 bytes as is. --HG-- branch : distribute extra : rebase_source : 99e089901a7dac003a53d53e85b0c08480c86e27 --- setuptools/command/egg_info.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/egg_info.py b/setuptools/command/egg_info.py index 8b29e672..9695627b 100755 --- a/setuptools/command/egg_info.py +++ b/setuptools/command/egg_info.py @@ -281,15 +281,19 @@ class FileList(_FileList): if item.endswith('\r'): # Fix older sdists built on Windows item = item[:-1] path = convert_path(item) - try: + if sys.version_info >= (3,): + try: + if os.path.exists(path): + self.files.append(path) + elif sys.platform == 'win32': + if os.path.exists(path.encode('utf-8')): + self.files.append(path) + except UnicodeEncodeError: + log.warn("%r not %s encodable -- skipping", path, + sys.getfilesystemencoding()) + else: if os.path.exists(path): self.files.append(path) - elif path != manifest_maker.template: - log.debug("%r not found -- skipping", path) - except UnicodeEncodeError: - log.warn("%r not %s encodable -- skipping", path, - sys.getfilesystemencoding()) - -- cgit v1.2.3 From 91379d9c17d2ac432f64e1952e2b3d47c83eedcc Mon Sep 17 00:00:00 2001 From: "Stefan H. Holek" Date: Sat, 10 Nov 2012 18:45:20 +0100 Subject: Add comments. --HG-- branch : distribute extra : rebase_source : 2d4ac9964b247122715c8296158c97d1f11adf89 --- setuptools/command/egg_info.py | 1 + setuptools/command/sdist.py | 1 + 2 files changed, 2 insertions(+) (limited to 'setuptools') diff --git a/setuptools/command/egg_info.py b/setuptools/command/egg_info.py index 9695627b..d37ba900 100755 --- a/setuptools/command/egg_info.py +++ b/setuptools/command/egg_info.py @@ -286,6 +286,7 @@ class FileList(_FileList): if os.path.exists(path): self.files.append(path) elif sys.platform == 'win32': + # NTFS can store UTF-8 filenames as is if os.path.exists(path.encode('utf-8')): self.files.append(path) except UnicodeEncodeError: diff --git a/setuptools/command/sdist.py b/setuptools/command/sdist.py index 7a6d2b7d..2fa3771a 100755 --- a/setuptools/command/sdist.py +++ b/setuptools/command/sdist.py @@ -282,6 +282,7 @@ class sdist(_sdist): log.info("reading manifest file '%s'", self.manifest) manifest = open(self.manifest, 'rbU') for line in manifest: + # The manifest must contain UTF-8. See #303. if sys.version_info >= (3,): try: line = line.decode('UTF-8') -- cgit v1.2.3 From be8173d7f6e5e971c5f028d5049d932cf5043efb Mon Sep 17 00:00:00 2001 From: "Stefan H. Holek" Date: Sat, 10 Nov 2012 22:14:57 +0100 Subject: Accept UTF-8 filenames into the filelist even if LANG=C. --HG-- branch : distribute extra : rebase_source : 499443a97846396e5790d80af32050f57f4aa43d --- setuptools/command/egg_info.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/egg_info.py b/setuptools/command/egg_info.py index d37ba900..085a499b 100755 --- a/setuptools/command/egg_info.py +++ b/setuptools/command/egg_info.py @@ -281,17 +281,18 @@ class FileList(_FileList): if item.endswith('\r'): # Fix older sdists built on Windows item = item[:-1] path = convert_path(item) + if sys.version_info >= (3,): try: - if os.path.exists(path): + if os.path.exists(path) or os.path.exists(path.encode('utf-8')): self.files.append(path) - elif sys.platform == 'win32': - # NTFS can store UTF-8 filenames as is - if os.path.exists(path.encode('utf-8')): - self.files.append(path) except UnicodeEncodeError: - log.warn("%r not %s encodable -- skipping", path, - sys.getfilesystemencoding()) + # Support UTF-8 filenames even if LANG=C + if os.path.exists(path.encode('utf-8')): + self.files.append(path) + else: + log.warn("%r not %s encodable -- skipping", path, + sys.getfilesystemencoding()) else: if os.path.exists(path): self.files.append(path) -- cgit v1.2.3 From 89e72217be0c95226fa6db0062f3a58298f3e7c2 Mon Sep 17 00:00:00 2001 From: "Stefan H. Holek" Date: Mon, 12 Nov 2012 13:54:37 +0100 Subject: Can't use 'surrogateescape' in upload_docs either. --HG-- branch : distribute extra : rebase_source : 6e262cc5a15434bda3543868b29ea9d69c51e238 --- setuptools/command/upload_docs.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/upload_docs.py b/setuptools/command/upload_docs.py index e21a88ce..41d7f055 100644 --- a/setuptools/command/upload_docs.py +++ b/setuptools/command/upload_docs.py @@ -18,6 +18,7 @@ from base64 import standard_b64encode from pkg_resources import iter_entry_points from distutils import log +from distutils.errors import DistutilsError from distutils.errors import DistutilsOptionError try: @@ -25,17 +26,12 @@ try: except ImportError: from setuptools.command.upload import upload -if sys.version_info >= (3, 1): - errors = 'surrogateescape' -else: - errors = 'strict' - # This is not just a replacement for byte literals # but works as a general purpose encoder def b(s, encoding='utf-8'): if isinstance(s, unicode): - return s.encode(encoding, errors) + return s.encode(encoding) return s -- cgit v1.2.3 From e0742352f7db736eb8fcb40a1b11f49f09b9ba10 Mon Sep 17 00:00:00 2001 From: "Stefan H. Holek" Date: Mon, 12 Nov 2012 13:56:00 +0100 Subject: Rid unused import. --HG-- branch : distribute extra : rebase_source : 5d7f72cc77b6143cc4f36cb111a39c8af62f5b1e --- setuptools/command/upload_docs.py | 1 - 1 file changed, 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/command/upload_docs.py b/setuptools/command/upload_docs.py index 41d7f055..98fb7233 100644 --- a/setuptools/command/upload_docs.py +++ b/setuptools/command/upload_docs.py @@ -18,7 +18,6 @@ from base64 import standard_b64encode from pkg_resources import iter_entry_points from distutils import log -from distutils.errors import DistutilsError from distutils.errors import DistutilsOptionError try: -- cgit v1.2.3 From cdb51001a8302e2948a42c68654550be1e2f941d Mon Sep 17 00:00:00 2001 From: "Stefan H. Holek" Date: Mon, 12 Nov 2012 22:56:15 +0100 Subject: No need for repr as path is always str. --HG-- branch : distribute extra : rebase_source : 6784f7ac37d43a341bb8b2466fbf68a082af2bee --- setuptools/command/egg_info.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/command/egg_info.py b/setuptools/command/egg_info.py index 085a499b..6145d6ea 100755 --- a/setuptools/command/egg_info.py +++ b/setuptools/command/egg_info.py @@ -291,7 +291,7 @@ class FileList(_FileList): if os.path.exists(path.encode('utf-8')): self.files.append(path) else: - log.warn("%r not %s encodable -- skipping", path, + log.warn("'%s' not %s encodable -- skipping", path, sys.getfilesystemencoding()) else: if os.path.exists(path): -- cgit v1.2.3 From 12599860ec654a39179704ce02323718c987114c Mon Sep 17 00:00:00 2001 From: "Stefan H. Holek" Date: Tue, 13 Nov 2012 14:01:29 +0100 Subject: Don't claim support for LANG=C. --HG-- branch : distribute extra : rebase_source : a366e936bfbce0c92831114e92a9d2c015841b5d --- setuptools/command/egg_info.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/command/egg_info.py b/setuptools/command/egg_info.py index 6145d6ea..0c2ea0cc 100755 --- a/setuptools/command/egg_info.py +++ b/setuptools/command/egg_info.py @@ -287,7 +287,7 @@ class FileList(_FileList): if os.path.exists(path) or os.path.exists(path.encode('utf-8')): self.files.append(path) except UnicodeEncodeError: - # Support UTF-8 filenames even if LANG=C + # Accept UTF-8 filenames even if LANG=C if os.path.exists(path.encode('utf-8')): self.files.append(path) else: -- cgit v1.2.3 From 36d2b289f92919582dff786969b41d7c6a6dd92f Mon Sep 17 00:00:00 2001 From: Pete Hollobon Date: Thu, 22 Nov 2012 08:41:56 +0000 Subject: Decode contents of pth file within self-extracting exe on Python 3+ --HG-- branch : distribute extra : rebase_source : 3b29e7832874265eddf3a29b4a64e588c17d20e3 --- setuptools/command/easy_install.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index f2260236..337532bc 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -1522,7 +1522,10 @@ def get_exe_prefixes(exe_filename): if name.endswith('-nspkg.pth'): continue if parts[0].upper() in ('PURELIB','PLATLIB'): - for pth in yield_lines(z.read(name)): + contents = z.read(name) + if sys.version_info >= (3,): + contents = contents.decode() + for pth in yield_lines(contents): pth = pth.strip().replace('\\','/') if not pth.startswith('import'): prefixes.append((('%s/%s/' % (parts[0],pth)), '')) -- cgit v1.2.3 From 7fbee015f7d31185ccfc890c59dbfab1c699db82 Mon Sep 17 00:00:00 2001 From: Gabriel Date: Fri, 23 Nov 2012 22:38:55 +0100 Subject: Don't wrap sys.stdout if it's in the correct encoding already. --HG-- branch : distribute extra : rebase_source : 314a8be1a2e63ceaf501ecb047a29f62302be0a0 --- setuptools/dist.py | 3 +++ 1 file changed, 3 insertions(+) (limited to 'setuptools') diff --git a/setuptools/dist.py b/setuptools/dist.py index afac180e..3e9e0254 100644 --- a/setuptools/dist.py +++ b/setuptools/dist.py @@ -657,6 +657,9 @@ class Distribution(_Distribution): if not isinstance(sys.stdout, io.TextIOWrapper): return _Distribution.handle_display_options(self, option_order) + if sys.stdout.encoding.lower() in ('utf-8', 'utf8'): + return _Distribution.handle_display_options(self, option_order) + # Print metadata in UTF-8 no matter the platform encoding = sys.stdout.encoding errors = sys.stdout.errors -- cgit v1.2.3 From 9d1e4a7a1f340147dca2f215dc33485c31f1834e Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 24 Nov 2012 10:23:09 -0500 Subject: Added comment and updated CHANGES --HG-- branch : distribute extra : rebase_source : 4c828b71eced1215219f5b16d881fa1f35972744 --- setuptools/dist.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'setuptools') diff --git a/setuptools/dist.py b/setuptools/dist.py index 3e9e0254..998a4dbe 100644 --- a/setuptools/dist.py +++ b/setuptools/dist.py @@ -657,6 +657,8 @@ class Distribution(_Distribution): if not isinstance(sys.stdout, io.TextIOWrapper): return _Distribution.handle_display_options(self, option_order) + # Don't wrap stdout if utf-8 is already the encoding. Provides + # workaround for #334. if sys.stdout.encoding.lower() in ('utf-8', 'utf8'): return _Distribution.handle_display_options(self, option_order) -- cgit v1.2.3 From cbcd321ebc204d04a4460ecc3accfb245b9ffacd Mon Sep 17 00:00:00 2001 From: Arfrever Frehtes Taifersar Arahesis Date: Mon, 26 Nov 2012 03:59:17 +0100 Subject: Do not use assertGreater(), which was introduced in Python 2.7 and 3.1. --HG-- branch : distribute extra : rebase_source : b0d3166887c9a287fd885e19f804e9d254b8dbc8 --- 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 1540bdc6..7ed0cd37 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -386,7 +386,7 @@ class TestSetupRequires(unittest.TestCase): 'VersionConflict') lines = stdout.splitlines() - self.assertGreater(len(lines), 0) + self.assertTrue(len(lines) > 0) self.assert_(lines[-1].strip(), 'test_pkg') try: -- cgit v1.2.3 From f31fb0ff20c63dd9bb82f91af45c12e97428e38c Mon Sep 17 00:00:00 2001 From: Arfrever Frehtes Taifersar Arahesis Date: Mon, 26 Nov 2012 07:27:32 +0100 Subject: Fix some DeprecationWarnings and ResourceWarnings. --HG-- branch : distribute extra : rebase_source : 1293f856181d35c735670b021e8745208103f640 --- setuptools/tests/test_easy_install.py | 4 ++-- setuptools/tests/test_markerlib.py | 18 +++++++++--------- 2 files changed, 11 insertions(+), 11 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py index 7ed0cd37..2f295b5c 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -236,7 +236,7 @@ class TestUserInstallTest(unittest.TestCase): f = open(egg_file, 'w') try: f.write('Name: foo\n') - except: + finally: f.close() sys.path.append(target) @@ -387,7 +387,7 @@ class TestSetupRequires(unittest.TestCase): lines = stdout.splitlines() self.assertTrue(len(lines) > 0) - self.assert_(lines[-1].strip(), 'test_pkg') + self.assertTrue(lines[-1].strip(), 'test_pkg') try: tempdir_context(setup_and_run) diff --git a/setuptools/tests/test_markerlib.py b/setuptools/tests/test_markerlib.py index 7ff2f584..aa461846 100644 --- a/setuptools/tests/test_markerlib.py +++ b/setuptools/tests/test_markerlib.py @@ -16,15 +16,15 @@ class TestMarkerlib(unittest.TestCase): os_name = os.name - self.assert_(interpret("")) + self.assertTrue(interpret("")) - self.assert_(interpret("os.name != 'buuuu'")) - self.assert_(interpret("python_version > '1.0'")) - self.assert_(interpret("python_version < '5.0'")) - self.assert_(interpret("python_version <= '5.0'")) - self.assert_(interpret("python_version >= '1.0'")) - self.assert_(interpret("'%s' in os.name" % os_name)) - self.assert_(interpret("'buuuu' not in os.name")) + self.assertTrue(interpret("os.name != 'buuuu'")) + self.assertTrue(interpret("python_version > '1.0'")) + self.assertTrue(interpret("python_version < '5.0'")) + self.assertTrue(interpret("python_version <= '5.0'")) + self.assertTrue(interpret("python_version >= '1.0'")) + self.assertTrue(interpret("'%s' in os.name" % os_name)) + self.assertTrue(interpret("'buuuu' not in os.name")) self.assertFalse(interpret("os.name == 'buuuu'")) self.assertFalse(interpret("python_version < '1.0'")) @@ -36,7 +36,7 @@ class TestMarkerlib(unittest.TestCase): environment = default_environment() environment['extra'] = 'test' - self.assert_(interpret("extra == 'test'", environment)) + self.assertTrue(interpret("extra == 'test'", environment)) self.assertFalse(interpret("extra == 'doc'", environment)) def raises_nameError(): -- cgit v1.2.3 From ceb03af882740ae02ef4be004a30b45c7b25b9ce Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Mon, 26 Nov 2012 09:20:11 -0500 Subject: Backed out changeset: 98a9f9dcce0e; Fixes #335. --HG-- branch : distribute extra : rebase_source : 3f4ff1c880688e6dd72d2fa8fab3c07e7f486a7e --- setuptools/dist.py | 5 +- setuptools/tests/test_easy_install.py | 142 +++++++++------------------------- 2 files changed, 40 insertions(+), 107 deletions(-) (limited to 'setuptools') diff --git a/setuptools/dist.py b/setuptools/dist.py index 6236d5be..998a4dbe 100644 --- a/setuptools/dist.py +++ b/setuptools/dist.py @@ -242,10 +242,9 @@ class Distribution(_Distribution): """Resolve pre-setup requirements""" from pkg_resources import working_set, parse_requirements for dist in working_set.resolve( - parse_requirements(requires), installer=self.fetch_build_egg, - replace_conflicting=True + parse_requirements(requires), installer=self.fetch_build_egg ): - working_set.add(dist, replace=True) + working_set.add(dist) def finalize_options(self): _Distribution.finalize_options(self) diff --git a/setuptools/tests/test_easy_install.py b/setuptools/tests/test_easy_install.py index 2f295b5c..b1799a5a 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -17,10 +17,8 @@ from setuptools.command.easy_install import easy_install, get_script_args, main 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 Distribution as PRDistribution import setuptools.tests.server -import pkg_resources try: # import multiprocessing solely for the purpose of testing its existence @@ -275,16 +273,48 @@ class TestUserInstallTest(unittest.TestCase): SandboxViolation. """ - test_pkg = create_setup_requires_package(self.dir) + test_setup_attrs = { + 'name': 'test_pkg', 'version': '0.0', + 'setup_requires': ['foobar'], + 'dependency_links': [os.path.abspath(self.dir)] + } + + test_pkg = os.path.join(self.dir, 'test_pkg') test_setup_py = os.path.join(test_pkg, 'setup.py') + test_setup_cfg = os.path.join(test_pkg, 'setup.cfg') + os.mkdir(test_pkg) + f = open(test_setup_py, 'w') + f.write(textwrap.dedent("""\ + import setuptools + setuptools.setup(**%r) + """ % test_setup_attrs)) + f.close() + + foobar_path = os.path.join(self.dir, 'foobar-0.1.tar.gz') + make_trivial_sdist( + foobar_path, + textwrap.dedent("""\ + import setuptools + setuptools.setup( + name='foobar', + version='0.1' + ) + """)) + + old_stdout = sys.stdout + old_stderr = sys.stderr + sys.stdout = StringIO.StringIO() + sys.stderr = StringIO.StringIO() try: - quiet_context( - lambda: reset_setup_stop_context( - lambda: run_setup(test_setup_py, ['install']) - )) + reset_setup_stop_context( + lambda: run_setup(test_setup_py, ['install']) + ) except SandboxViolation: self.fail('Installation caused SandboxViolation') + finally: + sys.stdout = old_stdout + sys.stderr = old_stderr class TestSetupRequires(unittest.TestCase): @@ -330,7 +360,7 @@ class TestSetupRequires(unittest.TestCase): tempdir_context(install_at) # create an sdist that has a build-time dependency. - quiet_context(lambda: self.create_sdist(install)) + self.create_sdist(install) # there should have been two or three requests to the server # (three happens on Python 3.3a) @@ -357,81 +387,6 @@ class TestSetupRequires(unittest.TestCase): installer(dist_path) tempdir_context(build_sdist) - def test_setup_requires_overrides_version_conflict(self): - """ - Regression test for issue #323. - - Ensures that a distribution's setup_requires requirements can still be - installed and used locally even if a conflicting version of that - requirement is already on the path. - """ - - pr_state = pkg_resources.__getstate__() - fake_dist = PRDistribution('does-not-matter', project_name='foobar', - version='0.0') - working_set.add(fake_dist) - - def setup_and_run(temp_dir): - test_pkg = create_setup_requires_package(temp_dir) - test_setup_py = os.path.join(test_pkg, 'setup.py') - try: - stdout, stderr = quiet_context( - lambda: reset_setup_stop_context( - # Don't even need to install the package, just running - # the setup.py at all is sufficient - lambda: run_setup(test_setup_py, ['--name']) - )) - except VersionConflict: - self.fail('Installing setup.py requirements caused ' - 'VersionConflict') - - lines = stdout.splitlines() - self.assertTrue(len(lines) > 0) - self.assertTrue(lines[-1].strip(), 'test_pkg') - - try: - tempdir_context(setup_and_run) - finally: - pkg_resources.__setstate__(pr_state) - - -def create_setup_requires_package(path): - """Creates a source tree under path for a trivial test package that has a - single requirement in setup_requires--a tarball for that requirement is - also created and added to the dependency_links argument. - """ - - test_setup_attrs = { - 'name': 'test_pkg', 'version': '0.0', - 'setup_requires': ['foobar==0.1'], - 'dependency_links': [os.path.abspath(path)] - } - - test_pkg = os.path.join(path, 'test_pkg') - test_setup_py = os.path.join(test_pkg, 'setup.py') - test_setup_cfg = os.path.join(test_pkg, 'setup.cfg') - os.mkdir(test_pkg) - - f = open(test_setup_py, 'w') - f.write(textwrap.dedent("""\ - import setuptools - setuptools.setup(**%r) - """ % test_setup_attrs)) - f.close() - - foobar_path = os.path.join(path, 'foobar-0.1.tar.gz') - make_trivial_sdist( - foobar_path, - textwrap.dedent("""\ - import setuptools - setuptools.setup( - name='foobar', - version='0.1' - ) - """)) - - return test_pkg - def make_trivial_sdist(dist_path, setup_py): """Create a simple sdist tarball at dist_path, containing just a @@ -466,7 +421,6 @@ def tempdir_context(f, cd=lambda dir:None): cd(orig_dir) shutil.rmtree(temp_dir) - def environment_context(f, **updates): """ Invoke f in the context @@ -480,7 +434,6 @@ def environment_context(f, **updates): del os.environ[key] os.environ.update(old_env) - def argv_context(f, repl): """ Invoke f in the context @@ -492,7 +445,6 @@ def argv_context(f, repl): finally: sys.argv[:] = old_argv - def reset_setup_stop_context(f): """ When the distribute tests are run using setup.py test, and then @@ -506,21 +458,3 @@ def reset_setup_stop_context(f): f() finally: distutils.core._setup_stop_after = setup_stop_after - - -def quiet_context(f): - """ - Redirect stdout/stderr to StringIO objects to prevent console output from - distutils commands. - """ - - old_stdout = sys.stdout - old_stderr = sys.stderr - new_stdout = sys.stdout = StringIO.StringIO() - new_stderr = sys.stderr = StringIO.StringIO() - try: - f() - finally: - sys.stdout = old_stdout - sys.stderr = old_stderr - return new_stdout.getvalue(), new_stderr.getvalue() -- cgit v1.2.3 From 3b6b1d147dae6ba825d0597d88abfda4cc3d295a Mon Sep 17 00:00:00 2001 From: Arfrever Frehtes Taifersar Arahesis Date: Mon, 26 Nov 2012 22:24:45 +0100 Subject: Fix 2 errors with Jython 2.5. (Now there remain 1 failure and 2 errors with Jython 2.5 and 1 failure and 5 errors with Jython 2.7.) --HG-- branch : distribute extra : rebase_source : c245820df5090ac5d005ebb7d6c4419145afce53 --- setuptools/sandbox.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/sandbox.py b/setuptools/sandbox.py index 64f725e7..1583b81f 100755 --- a/setuptools/sandbox.py +++ b/setuptools/sandbox.py @@ -1,5 +1,8 @@ import os, sys, __builtin__, tempfile, operator, pkg_resources -_os = sys.modules[os.name] +if os.name == "java": + import org.python.modules.posix.PosixModule as _os +else: + _os = sys.modules[os.name] try: _file = file except NameError: -- cgit v1.2.3 From 753f783100cf598316e9030dcf59b24772819504 Mon Sep 17 00:00:00 2001 From: Arfrever Frehtes Taifersar Arahesis Date: Tue, 27 Nov 2012 00:40:15 +0100 Subject: Fix 1 failure with Jython 2.5 and 2.7. (Now there remain 0 failures and 2 errors with Jython 2.5 and 0 failures and 5 errors with Jython 2.7.) --HG-- branch : distribute extra : rebase_source : 319071404608c4f34616df74bfeaa28d590edd0c --- 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 b1799a5a..582219ce 100644 --- a/setuptools/tests/test_easy_install.py +++ b/setuptools/tests/test_easy_install.py @@ -13,7 +13,7 @@ import StringIO import distutils.core from setuptools.sandbox import run_setup, SandboxViolation -from setuptools.command.easy_install import easy_install, get_script_args, main +from setuptools.command.easy_install import easy_install, fix_jython_executable, get_script_args, main from setuptools.command.easy_install import PthDistributions from setuptools.command import easy_install as easy_install_pkg from setuptools.dist import Distribution @@ -51,7 +51,7 @@ if __name__ == '__main__': sys.exit( load_entry_point('spec', 'console_scripts', 'name')() ) -""" % sys.executable +""" % fix_jython_executable(sys.executable, "") SETUP_PY = """\ from setuptools import setup -- cgit v1.2.3 From 11491404365ba925bb36935a9f7a14c1afe003cc Mon Sep 17 00:00:00 2001 From: Arfrever Frehtes Taifersar Arahesis Date: Tue, 27 Nov 2012 00:44:17 +0100 Subject: Disable workaround for Jython scripts on Linux systems. --HG-- branch : distribute extra : rebase_source : 289980b084c335029d93732feb8e02da94472795 --- setuptools/command/easy_install.py | 5 +++++ setuptools/tests/test_resources.py | 10 ++++++++++ 2 files changed, 15 insertions(+) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 337532bc..cb911173 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -1788,6 +1788,11 @@ 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 + if java.lang.System.getProperty("os.name") == "Linux": + return executable + # Workaround Jython's sys.executable being a .sh (an invalid # shebang line interpreter) if options: diff --git a/setuptools/tests/test_resources.py b/setuptools/tests/test_resources.py index d08fa325..0bc1a095 100644 --- a/setuptools/tests/test_resources.py +++ b/setuptools/tests/test_resources.py @@ -561,6 +561,15 @@ class ScriptHeaderTests(TestCase): if (sys.version_info >= (3,) and os.environ.get("LC_CTYPE") in (None, "C", "POSIX")): return + + class java: + class lang: + class System: + @staticmethod + def getProperty(property): + return "" + sys.modules["java"] = java + platform = sys.platform sys.platform = 'java1.5.0_13' stdout = sys.stdout @@ -584,6 +593,7 @@ class ScriptHeaderTests(TestCase): '#!%s -x\n' % self.non_ascii_exe) self.assertTrue('Unable to adapt shebang line' in sys.stdout.getvalue()) finally: + del sys.modules["java"] sys.platform = platform sys.stdout = stdout -- cgit v1.2.3 From 721559fe76a1cda3de639ee2aaa446595169d26b Mon Sep 17 00:00:00 2001 From: Arfrever Frehtes Taifersar Arahesis Date: Sat, 29 Dec 2012 06:23:09 +0100 Subject: Fix some ResourceWarnings. --HG-- branch : distribute extra : rebase_source : 31ac3f0135d8cfe0fabc274f1649d1c99eba2868 --- setuptools/command/develop.py | 4 +++- setuptools/command/easy_install.py | 2 +- setuptools/command/upload.py | 5 +++-- setuptools/command/upload_docs.py | 4 +++- setuptools/tests/doctest.py | 8 ++++++-- setuptools/tests/test_develop.py | 8 ++++++-- setuptools/tests/win_script_wrapper.txt | 28 +++++++++++++++++++++------- 7 files changed, 43 insertions(+), 16 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/develop.py b/setuptools/command/develop.py index 709e349c..1d500040 100755 --- a/setuptools/command/develop.py +++ b/setuptools/command/develop.py @@ -132,7 +132,9 @@ class develop(easy_install): def uninstall_link(self): if os.path.exists(self.egg_link): log.info("Removing %s (link to %s)", self.egg_link, self.egg_base) - contents = [line.rstrip() for line in open(self.egg_link)] + egg_link_file = open(self.egg_link) + contents = [line.rstrip() for line in egg_link_file] + egg_link_file.close() if contents not in ([self.egg_path], [self.egg_path, self.setup_path]): log.warn("Link points to %s: uninstall aborted", contents) return diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index cb911173..0d72f758 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -491,7 +491,7 @@ Please make the appropriate changes for your system and try again. self.cant_write_to_target() else: try: - f.write("import os;open(%r,'w').write('OK')\n" % (ok_file,)) + f.write("import os; f = open(%r, 'w'); f.write('OK'); f.close()\n" % (ok_file,)) f.close(); f=None executable = sys.executable if os.name=='nt': diff --git a/setuptools/command/upload.py b/setuptools/command/upload.py index 9f9366b5..21b9615c 100755 --- a/setuptools/command/upload.py +++ b/setuptools/command/upload.py @@ -109,8 +109,9 @@ class upload(Command): data['comment'] = comment if self.sign: - data['gpg_signature'] = (os.path.basename(filename) + ".asc", - open(filename+".asc").read()) + asc_file = open(filename + ".asc") + data['gpg_signature'] = (os.path.basename(filename) + ".asc", asc_file.read()) + asc_file.close() # set up the authentication auth = "Basic " + base64.encodestring(self.username + ":" + self.password).strip() diff --git a/setuptools/command/upload_docs.py b/setuptools/command/upload_docs.py index 98fb7233..1d5a7445 100644 --- a/setuptools/command/upload_docs.py +++ b/setuptools/command/upload_docs.py @@ -105,7 +105,9 @@ class upload_docs(upload): shutil.rmtree(tmp_dir) def upload_file(self, filename): - content = open(filename, 'rb').read() + f = open(filename, 'rb') + content = f.read() + f.close() meta = self.distribution.metadata data = { ':action': 'doc_upload', diff --git a/setuptools/tests/doctest.py b/setuptools/tests/doctest.py index be399a9d..cc1e06c3 100644 --- a/setuptools/tests/doctest.py +++ b/setuptools/tests/doctest.py @@ -1968,7 +1968,9 @@ def testfile(filename, module_relative=True, name=None, package=None, runner = DocTestRunner(verbose=verbose, optionflags=optionflags) # Read the file, convert it to a test, and run it. - s = open(filename).read() + f = open(filename) + s = f.read() + f.close() test = parser.get_doctest(s, globs, name, filename, 0) runner.run(test) @@ -2353,7 +2355,9 @@ def DocFileTest(path, module_relative=True, package=None, # Find the file and read it. name = os.path.basename(path) - doc = open(path).read() + f = open(path) + doc = f.read() + f.close() # Convert it to a test, and wrap it in a DocFileCase. test = parser.get_doctest(doc, globs, name, path, 0) diff --git a/setuptools/tests/test_develop.py b/setuptools/tests/test_develop.py index 3e071dad..315058c5 100644 --- a/setuptools/tests/test_develop.py +++ b/setuptools/tests/test_develop.py @@ -89,8 +89,12 @@ class TestDevelopTest(unittest.TestCase): self.assertEqual(content, ['easy-install.pth', 'foo.egg-link']) # Check that we are using the right code. - path = open(os.path.join(site.USER_SITE, 'foo.egg-link'), 'rt').read().split()[0].strip() - init = open(os.path.join(path, 'foo', '__init__.py'), 'rt').read().strip() + egg_link_file = open(os.path.join(site.USER_SITE, 'foo.egg-link'), 'rt') + path = egg_link_file.read().split()[0].strip() + egg_link_file.close() + init_file = open(os.path.join(path, 'foo', '__init__.py'), 'rt') + init = init_file.read().strip() + init_file.close() if sys.version < "3": self.assertEqual(init, 'print "foo"') else: diff --git a/setuptools/tests/win_script_wrapper.txt b/setuptools/tests/win_script_wrapper.txt index 2e1bff74..9f7c81d6 100644 --- a/setuptools/tests/win_script_wrapper.txt +++ b/setuptools/tests/win_script_wrapper.txt @@ -16,7 +16,8 @@ Let's create a simple script, foo-script.py: >>> import os, sys, tempfile >>> from setuptools.command.easy_install import nt_quote_arg >>> sample_directory = tempfile.mkdtemp() - >>> open(os.path.join(sample_directory, 'foo-script.py'), 'w').write( + >>> f = open(os.path.join(sample_directory, 'foo-script.py'), 'w') + >>> f.write( ... """#!%(python_exe)s ... import sys ... input = repr(sys.stdin.read()) @@ -26,6 +27,7 @@ Let's create a simple script, foo-script.py: ... if __debug__: ... print 'non-optimized' ... """ % dict(python_exe=nt_quote_arg(sys.executable))) + >>> f.close() Note that the script starts with a Unix-style '#!' line saying which Python executable to run. The wrapper will use this to find the @@ -34,9 +36,11 @@ correct Python executable. We'll also copy cli.exe to the sample-directory with the name foo.exe: >>> import pkg_resources - >>> open(os.path.join(sample_directory, 'foo.exe'), 'wb').write( + >>> f = open(os.path.join(sample_directory, 'foo.exe'), 'wb') + >>> f.write( ... pkg_resources.resource_string('setuptools', 'cli.exe') ... ) + >>> f.close() When the copy of cli.exe, foo.exe in this example, runs, it examines the path name it was run with and computes a Python script path name @@ -77,7 +81,8 @@ to start the interactive interpreter. You can combine multiple options as usual. For example, to run in optimized mode and enter the interpreter after running the script, you could use -Oi: - >>> open(os.path.join(sample_directory, 'foo-script.py'), 'w').write( + >>> f = open(os.path.join(sample_directory, 'foo-script.py'), 'w') + >>> f.write( ... """#!%(python_exe)s -Oi ... import sys ... input = repr(sys.stdin.read()) @@ -88,6 +93,7 @@ enter the interpreter after running the script, you could use -Oi: ... print 'non-optimized' ... sys.ps1 = '---' ... """ % dict(python_exe=nt_quote_arg(sys.executable))) + >>> f.close() >>> input, output = os.popen4(nt_quote_arg(os.path.join(sample_directory, 'foo.exe'))) >>> input.close() @@ -105,18 +111,24 @@ Now let's test the GUI version with the simple scipt, bar-script.py: >>> import os, sys, tempfile >>> from setuptools.command.easy_install import nt_quote_arg >>> sample_directory = tempfile.mkdtemp() - >>> open(os.path.join(sample_directory, 'bar-script.pyw'), 'w').write( + >>> f = open(os.path.join(sample_directory, 'bar-script.pyw'), 'w') + >>> f.write( ... """#!%(python_exe)s ... import sys - ... open(sys.argv[1], 'wb').write(repr(sys.argv[2])) + ... f = open(sys.argv[1], 'wb') + ... f.write(repr(sys.argv[2])) + ... f.close() ... """ % dict(python_exe=nt_quote_arg(sys.executable))) + >>> f.close() We'll also copy gui.exe to the sample-directory with the name bar.exe: >>> import pkg_resources - >>> open(os.path.join(sample_directory, 'bar.exe'), 'wb').write( + >>> f = open(os.path.join(sample_directory, 'bar.exe'), 'wb') + >>> f.write( ... pkg_resources.resource_string('setuptools', 'gui.exe') ... ) + >>> f.close() Finally, we'll run the script and check the result: @@ -126,8 +138,10 @@ Finally, we'll run the script and check the result: >>> input.close() >>> print output.read() - >>> print open(os.path.join(sample_directory, 'test_output.txt'), 'rb').read() + >>> f = open(os.path.join(sample_directory, 'test_output.txt'), 'rb') + >>> print f.read() 'Test Argument' + >>> f.close() We're done with the sample_directory: -- cgit v1.2.3 From b5cd47fbd96ae900dd835b68484084ab1219f260 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 16 Feb 2013 02:13:45 -0500 Subject: Backed out changeset: d0a8d1a83053 In the discussion in #278, it became clear that the deviance in behavior from setuptools is problemmatic. For compatibility, defer to the setuptools version scheme as specifically intended. --HG-- branch : distribute extra : rebase_source : 1d5cc8c216f974b247e2dc84d8d40c868d6d3639 --- setuptools/tests/test_resources.py | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_resources.py b/setuptools/tests/test_resources.py index 0bc1a095..292b78d1 100644 --- a/setuptools/tests/test_resources.py +++ b/setuptools/tests/test_resources.py @@ -477,13 +477,14 @@ class ParseTests(TestCase): p1, p2 = parse_version(s1),parse_version(s2) self.assertEqual(p1,p2, (s1,s2,p1,p2)) + c('1.2-rc1', '1.2rc1') c('0.4', '0.4.0') c('0.4.0.0', '0.4.0') c('0.4.0-0', '0.4-0') c('0pl1', '0.0pl1') c('0pre1', '0.0c1') c('0.0.0preview1', '0c1') - c('0.0c1', '0rc1') + c('0.0c1', '0-rc1') c('1.2a1', '1.2.a.1'); c('1.2...a', '1.2a') def testVersionOrdering(self): @@ -492,14 +493,11 @@ class ParseTests(TestCase): self.assertTrue(p1 Date: Tue, 19 Feb 2013 09:16:13 +0100 Subject: Fix for PermissionError when installing on Python 3.3: __pycache__ dir inside distutils scripts metadata directory --HG-- branch : distribute extra : rebase_source : e6761715dec0e43a90b54c26f25fa68d97c97938 --- setuptools/command/easy_install.py | 3 +++ 1 file changed, 3 insertions(+) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 0d72f758..ba98fa13 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -522,6 +522,9 @@ Please make the appropriate changes for your system and try again. """Write all the scripts for `dist`, unless scripts are excluded""" if not self.exclude_scripts and dist.metadata_isdir('scripts'): for script_name in dist.metadata_listdir('scripts'): + if dist.metadata_isdir('scripts/' + script_name): + # Probably Python 3 __pycache__ directory. + continue self.install_script( dist, script_name, dist.get_metadata('scripts/'+script_name) -- cgit v1.2.3 From d9c4d3c51e93c08a76d310e549c6d5de260667bb Mon Sep 17 00:00:00 2001 From: Grigory Petrov Date: Wed, 3 Apr 2013 02:02:44 +0400 Subject: Added support for Windows RT (arm). --HG-- branch : distribute extra : rebase_source : c181b8cc551936e48bdc88d9435018d0d9de00b2 --- setuptools/cli-arm-32.exe | Bin 0 -> 9216 bytes setuptools/command/easy_install.py | 3 +++ setuptools/gui-arm-32.exe | Bin 0 -> 9216 bytes 3 files changed, 3 insertions(+) create mode 100644 setuptools/cli-arm-32.exe create mode 100644 setuptools/gui-arm-32.exe (limited to 'setuptools') diff --git a/setuptools/cli-arm-32.exe b/setuptools/cli-arm-32.exe new file mode 100644 index 00000000..e2d4c322 Binary files /dev/null and b/setuptools/cli-arm-32.exe differ diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 0d72f758..b675e559 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -19,6 +19,7 @@ import zipfile import re import stat import random +import platform from glob import glob from setuptools import Command, _dont_write_bytecode from setuptools.sandbox import run_setup @@ -1834,6 +1835,8 @@ def get_script_args(dist, executable=sys_executable, wininst=False): ext, launcher = '-script.py', 'cli.exe' old = ['.py','.pyc','.pyo'] new_header = re.sub('(?i)pythonw.exe','python.exe',header) + if platform.machine().lower() == 'arm' : + launcher = launcher.replace(".", "-arm.") if is_64bit(): launcher = launcher.replace(".", "-64.") else: diff --git a/setuptools/gui-arm-32.exe b/setuptools/gui-arm-32.exe new file mode 100644 index 00000000..01863fa6 Binary files /dev/null and b/setuptools/gui-arm-32.exe differ -- cgit v1.2.3 From 15c27d768157550dd606e3a407eebb19c06c3823 Mon Sep 17 00:00:00 2001 From: Grigory Petrov Date: Wed, 3 Apr 2013 02:05:53 +0400 Subject: Respected PEP-8. --HG-- branch : distribute extra : rebase_source : 58252278f993ece0a9b96c58c58f2851fa07e048 --- 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 b675e559..3a848269 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -1835,7 +1835,7 @@ def get_script_args(dist, executable=sys_executable, wininst=False): ext, launcher = '-script.py', 'cli.exe' old = ['.py','.pyc','.pyo'] new_header = re.sub('(?i)pythonw.exe','python.exe',header) - if platform.machine().lower() == 'arm' : + if platform.machine().lower() == 'arm': launcher = launcher.replace(".", "-arm.") if is_64bit(): launcher = launcher.replace(".", "-64.") -- cgit v1.2.3 From d8189bb53bbd7b3c38ee6c31844087f100143f51 Mon Sep 17 00:00:00 2001 From: Grigory Petrov Date: Wed, 3 Apr 2013 02:06:39 +0400 Subject: Respected project coding standard. --HG-- branch : distribute extra : rebase_source : ca79464fdbf6a8765b8928b99c8ef2ab69e35e42 --- 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 3a848269..a6ca741f 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -1835,7 +1835,7 @@ def get_script_args(dist, executable=sys_executable, wininst=False): ext, launcher = '-script.py', 'cli.exe' old = ['.py','.pyc','.pyo'] new_header = re.sub('(?i)pythonw.exe','python.exe',header) - if platform.machine().lower() == 'arm': + if platform.machine().lower()=='arm': launcher = launcher.replace(".", "-arm.") if is_64bit(): launcher = launcher.replace(".", "-64.") -- cgit v1.2.3 From 463e07e68ee64bb15aea8516239908e3f6d4f40f Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 5 Apr 2013 17:10:55 -0400 Subject: Update release notes and comment to provide a bit more detail about the issue and to be more consistent with the solution. --HG-- branch : distribute extra : rebase_source : c813a29e831f266d427d4a4bce3da97f475a8eee --- 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 ba98fa13..98af2620 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -523,8 +523,9 @@ Please make the appropriate changes for your system and try again. if not self.exclude_scripts and dist.metadata_isdir('scripts'): for script_name in dist.metadata_listdir('scripts'): if dist.metadata_isdir('scripts/' + script_name): - # Probably Python 3 __pycache__ directory. - continue + # The "script" is a directory, likely a Python 3 + # __pycache__ directory, so skip it. + continue self.install_script( dist, script_name, dist.get_metadata('scripts/'+script_name) -- cgit v1.2.3 From aa5a03972360fdd48530183a60171ecbf477d1e6 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 4 May 2013 22:05:52 -0400 Subject: Include a launcher manifest for console scripts to prevent undesirable UAC elevation for scripts detected as installers (such as easy_install). Fixes #143. --HG-- branch : distribute extra : rebase_source : be6f65eea9c10ce78b6698d8c220b6e5de577292 --- setuptools/command/easy_install.py | 13 +++++++++++++ setuptools/command/launcher manifest.xml | 15 +++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 setuptools/command/launcher manifest.xml (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 98af2620..7281d92d 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -20,6 +20,7 @@ import re import stat import random from glob import glob +import pkg_resources from setuptools import Command, _dont_write_bytecode from setuptools.sandbox import run_setup from distutils import log, dir_util @@ -1851,11 +1852,23 @@ def get_script_args(dist, executable=sys_executable, wininst=False): name+'.exe', resource_string('setuptools', launcher), 'b' # write in binary mode ) + if not is_64bit(): + # install a manifest for the launcher to prevent Windows + # from detecting it as an installer (which it will for + # launchers like easy_install.exe). Consider only + # adding a manifest for launchers detected as installers. + # See Distribute #143 for details. + m_name = name + '.exe.manifest' + yield (m_name, load_launcher_manifest(name), 't') else: # On other platforms, we assume the right thing to do is to # just write the stub with no extension. yield (name, header+script_text) +def load_launcher_manifest(name): + manifest = pkg_resources.resource_string(__name__, 'launcher manifest.xml') + return manifest % vars() + def rmtree(path, ignore_errors=False, onerror=auto_chmod): """Recursively delete a directory tree. diff --git a/setuptools/command/launcher manifest.xml b/setuptools/command/launcher manifest.xml new file mode 100644 index 00000000..844d2264 --- /dev/null +++ b/setuptools/command/launcher manifest.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + -- cgit v1.2.3 From d7dec0f7e8cdc12ffc7c8ad42f8b0d4216d8864d Mon Sep 17 00:00:00 2001 From: "wyj1046@gmail.com" Date: Sun, 5 May 2013 17:07:31 +0800 Subject: decode manifest bytes(utf-8) to string first if py version is 3 --HG-- branch : distribute extra : rebase_source : 1038acda4912af8ac637d0e149630a95f3536dec --- setuptools/command/easy_install.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 7281d92d..dc851d1e 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -1867,7 +1867,10 @@ def get_script_args(dist, executable=sys_executable, wininst=False): def load_launcher_manifest(name): manifest = pkg_resources.resource_string(__name__, 'launcher manifest.xml') - return manifest % vars() + if sys.version_info[0] < 3: + return manifest % vars() + else: + return manifest.decode('utf-8') % vars() def rmtree(path, ignore_errors=False, onerror=auto_chmod): """Recursively delete a directory tree. -- cgit v1.2.3 From 328600bdabf9645cd6f8a16c9f735384c8bfb2b0 Mon Sep 17 00:00:00 2001 From: Grigory Petrov Date: Wed, 8 May 2013 00:56:39 +0400 Subject: ARM executables rebuilt. --HG-- branch : distribute extra : rebase_source : 385d71111170f3cb8fcdea2fc807d4e409621078 --- setuptools/cli-arm-32.exe | Bin 9216 -> 69120 bytes setuptools/gui-arm-32.exe | Bin 9216 -> 69120 bytes 2 files changed, 0 insertions(+), 0 deletions(-) (limited to 'setuptools') diff --git a/setuptools/cli-arm-32.exe b/setuptools/cli-arm-32.exe index e2d4c322..2f40402d 100644 Binary files a/setuptools/cli-arm-32.exe and b/setuptools/cli-arm-32.exe differ diff --git a/setuptools/gui-arm-32.exe b/setuptools/gui-arm-32.exe index 01863fa6..537aff37 100644 Binary files a/setuptools/gui-arm-32.exe and b/setuptools/gui-arm-32.exe differ -- cgit v1.2.3 From 254034545b0e936fec613ef964ceb43528330e58 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Wed, 8 May 2013 19:32:02 +0100 Subject: Rebuilt the launcher using MS Windows SDK 6.1 with the /SUBSYSTEM parameters --HG-- branch : distribute extra : rebase_source : 35455b8da14f931b6c4b77bb66b85416c3e13ec5 --- setuptools/cli-32.exe | Bin 69632 -> 65536 bytes setuptools/cli-64.exe | Bin 75264 -> 74752 bytes setuptools/gui-32.exe | Bin 65536 -> 65536 bytes setuptools/gui-64.exe | Bin 75264 -> 75264 bytes 4 files changed, 0 insertions(+), 0 deletions(-) (limited to 'setuptools') diff --git a/setuptools/cli-32.exe b/setuptools/cli-32.exe index 9b7717b7..3671e959 100644 Binary files a/setuptools/cli-32.exe and b/setuptools/cli-32.exe differ diff --git a/setuptools/cli-64.exe b/setuptools/cli-64.exe index 265585af..99e63a26 100644 Binary files a/setuptools/cli-64.exe and b/setuptools/cli-64.exe differ diff --git a/setuptools/gui-32.exe b/setuptools/gui-32.exe index 3f64af7d..53450281 100644 Binary files a/setuptools/gui-32.exe and b/setuptools/gui-32.exe differ diff --git a/setuptools/gui-64.exe b/setuptools/gui-64.exe index 3ab4378e..966409aa 100644 Binary files a/setuptools/gui-64.exe and b/setuptools/gui-64.exe differ -- cgit v1.2.3 From 23e024076a9902aa8aeedd9947c0fa5a4e5408f4 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Thu, 9 May 2013 15:23:44 +0100 Subject: Use x64 cross tools for building 64-bit launcher. I'm suspicious the only impact this will have is to enable building 64-bit launcher on 32-bit hosts. Also rebuilt launchers. --HG-- branch : distribute extra : rebase_source : 329591eb07b9d25717caee614012c8278926559d --- setuptools/cli-32.exe | Bin 65536 -> 65536 bytes setuptools/cli-64.exe | Bin 74752 -> 74752 bytes setuptools/gui-32.exe | Bin 65536 -> 65536 bytes setuptools/gui-64.exe | Bin 75264 -> 75264 bytes 4 files changed, 0 insertions(+), 0 deletions(-) (limited to 'setuptools') diff --git a/setuptools/cli-32.exe b/setuptools/cli-32.exe index 3671e959..b1487b78 100644 Binary files a/setuptools/cli-32.exe and b/setuptools/cli-32.exe differ diff --git a/setuptools/cli-64.exe b/setuptools/cli-64.exe index 99e63a26..675e6bf3 100644 Binary files a/setuptools/cli-64.exe and b/setuptools/cli-64.exe differ diff --git a/setuptools/gui-32.exe b/setuptools/gui-32.exe index 53450281..f8d35096 100644 Binary files a/setuptools/gui-32.exe and b/setuptools/gui-32.exe differ diff --git a/setuptools/gui-64.exe b/setuptools/gui-64.exe index 966409aa..330c51a5 100644 Binary files a/setuptools/gui-64.exe and b/setuptools/gui-64.exe differ -- cgit v1.2.3 From e16d0f5833d18c32f19cffe9c3fc6c6b69584c01 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Thu, 9 May 2013 15:24:43 +0100 Subject: Removing legacy word-size-agnostic launchers. --HG-- branch : distribute extra : rebase_source : 5c5d41bbbd0a6731f81cf48afd436be6e9524ec9 --- setuptools/cli.exe | Bin 69632 -> 0 bytes setuptools/gui.exe | Bin 65536 -> 0 bytes 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 setuptools/cli.exe delete mode 100644 setuptools/gui.exe (limited to 'setuptools') diff --git a/setuptools/cli.exe b/setuptools/cli.exe deleted file mode 100644 index 9b7717b7..00000000 Binary files a/setuptools/cli.exe and /dev/null differ diff --git a/setuptools/gui.exe b/setuptools/gui.exe deleted file mode 100644 index 3f64af7d..00000000 Binary files a/setuptools/gui.exe and /dev/null differ -- cgit v1.2.3 From a011aa8e2f3b911c809a5eb52f57e0584786ea4d Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sat, 11 May 2013 14:06:08 +0100 Subject: Updated tests of win_script_wrapper to use 32-bit wrappers --HG-- branch : distribute extra : source : 26421e9ba211b7e14171673c46c45692b6c8501d --- setuptools/tests/win_script_wrapper.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/win_script_wrapper.txt b/setuptools/tests/win_script_wrapper.txt index 9f7c81d6..9ccc96f0 100644 --- a/setuptools/tests/win_script_wrapper.txt +++ b/setuptools/tests/win_script_wrapper.txt @@ -38,7 +38,7 @@ We'll also copy cli.exe to the sample-directory with the name foo.exe: >>> import pkg_resources >>> f = open(os.path.join(sample_directory, 'foo.exe'), 'wb') >>> f.write( - ... pkg_resources.resource_string('setuptools', 'cli.exe') + ... pkg_resources.resource_string('setuptools', 'cli-32.exe') ... ) >>> f.close() @@ -83,7 +83,7 @@ enter the interpreter after running the script, you could use -Oi: >>> f = open(os.path.join(sample_directory, 'foo-script.py'), 'w') >>> f.write( - ... """#!%(python_exe)s -Oi + ... """#!%(python_exe)s -Oi ... import sys ... input = repr(sys.stdin.read()) ... print sys.argv[0][-14:] @@ -126,7 +126,7 @@ We'll also copy gui.exe to the sample-directory with the name bar.exe: >>> import pkg_resources >>> f = open(os.path.join(sample_directory, 'bar.exe'), 'wb') >>> f.write( - ... pkg_resources.resource_string('setuptools', 'gui.exe') + ... pkg_resources.resource_string('setuptools', 'gui-32.exe') ... ) >>> f.close() -- cgit v1.2.3 From 9c6e0172e04e260af141ddf0362c6141a375763a Mon Sep 17 00:00:00 2001 From: "guy@guyr-air.infinidat.com" Date: Mon, 13 May 2013 15:21:51 +0300 Subject: issue #376: copying cli-32.exe to cli.exe and gui-32.exe to gui.exe to prevent breakage of other modules that take the binaries from distribute --HG-- branch : distribute extra : rebase_source : fb86f5549568529753c0be2357128f41039ed740 --- setuptools/cli.exe | Bin 0 -> 65536 bytes setuptools/gui.exe | Bin 0 -> 65536 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 setuptools/cli.exe create mode 100644 setuptools/gui.exe (limited to 'setuptools') diff --git a/setuptools/cli.exe b/setuptools/cli.exe new file mode 100644 index 00000000..b1487b78 Binary files /dev/null and b/setuptools/cli.exe differ diff --git a/setuptools/gui.exe b/setuptools/gui.exe new file mode 100644 index 00000000..f8d35096 Binary files /dev/null and b/setuptools/gui.exe differ -- cgit v1.2.3 From 289b359721b9a717984c5200d7d5adbfccc8da20 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 19 May 2013 02:47:41 -0400 Subject: Extract get_win_launcher function --HG-- branch : distribute extra : rebase_source : 14dbef22dbc8376cc3632ce53be0d61b7976b889 --- setuptools/command/easy_install.py | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index 10a8f272..df6107d7 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -1833,26 +1833,22 @@ def get_script_args(dist, executable=sys_executable, wininst=False): if sys.platform=='win32' or wininst: # On Windows/wininst, add a .py extension and an .exe launcher if group=='gui_scripts': - ext, launcher = '-script.pyw', 'gui.exe' + launcher_type = 'gui' + ext = '-script.pyw' old = ['.pyw'] new_header = re.sub('(?i)python.exe','pythonw.exe',header) else: - ext, launcher = '-script.py', 'cli.exe' + launcher_type = 'cli' + ext = '-script.py' old = ['.py','.pyc','.pyo'] new_header = re.sub('(?i)pythonw.exe','python.exe',header) - if platform.machine().lower()=='arm': - launcher = launcher.replace(".", "-arm.") - if is_64bit(): - launcher = launcher.replace(".", "-64.") - else: - launcher = launcher.replace(".", "-32.") if os.path.exists(new_header[2:-1]) or sys.platform!='win32': hdr = new_header else: hdr = header yield (name+ext, hdr+script_text, 't', [name+x for x in old]) yield ( - name+'.exe', resource_string('setuptools', launcher), + name+'.exe', get_win_launcher(launcher_type), 'b' # write in binary mode ) if not is_64bit(): @@ -1868,6 +1864,23 @@ def get_script_args(dist, executable=sys_executable, wininst=False): # just write the stub with no extension. yield (name, header+script_text) +def get_win_launcher(type): + """ + Load the Windows launcher (executable) suitable for launching a script. + + `type` should be either 'cli' or 'gui' + + Returns the executable as a byte string. + """ + launcher_fn = '%s.exe' % type + if platform.machine().lower()=='arm': + launcher_fn = launcher_fn.replace(".", "-arm.") + if is_64bit(): + launcher_fn = launcher_fn.replace(".", "-64.") + else: + launcher_fn = launcher_fn.replace(".", "-32.") + return resource_string('setuptools', launcher_fn) + def load_launcher_manifest(name): manifest = pkg_resources.resource_string(__name__, 'launcher manifest.xml') if sys.version_info[0] < 3: -- cgit v1.2.3 From 4350a091eecb5af1dd461442c311d981550bedb5 Mon Sep 17 00:00:00 2001 From: Philip Thiem Date: Mon, 4 Feb 2013 23:43:35 -0600 Subject: A few non-python 3 print statements --HG-- branch : distribute extra : rebase_source : 75f0b0e993a44ccfef8292717af58943e187d4cd --- setuptools/tests/win_script_wrapper.txt | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/win_script_wrapper.txt b/setuptools/tests/win_script_wrapper.txt index 9ccc96f0..82719273 100644 --- a/setuptools/tests/win_script_wrapper.txt +++ b/setuptools/tests/win_script_wrapper.txt @@ -21,11 +21,11 @@ Let's create a simple script, foo-script.py: ... """#!%(python_exe)s ... import sys ... input = repr(sys.stdin.read()) - ... print sys.argv[0][-14:] - ... print sys.argv[1:] - ... print input + ... print(sys.argv[0][-14:]) + ... print(sys.argv[1:]) + ... print(input) ... if __debug__: - ... print 'non-optimized' + ... print('non-optimized') ... """ % dict(python_exe=nt_quote_arg(sys.executable))) >>> f.close() @@ -54,7 +54,7 @@ the wrapper: ... + r' arg1 "arg 2" "arg \"2\\\"" "arg 4\\" "arg5 a\\b"') >>> input.write('hello\nworld\n') >>> input.close() - >>> print output.read(), + >>> print(output.read(),) \foo-script.py ['arg1', 'arg 2', 'arg "2\\"', 'arg 4\\', 'arg5 a\\\\b'] 'hello\nworld\n' @@ -86,18 +86,18 @@ enter the interpreter after running the script, you could use -Oi: ... """#!%(python_exe)s -Oi ... import sys ... input = repr(sys.stdin.read()) - ... print sys.argv[0][-14:] - ... print sys.argv[1:] - ... print input + ... print(sys.argv[0][-14:]) + ... print(sys.argv[1:]) + ... print(input) ... if __debug__: - ... print 'non-optimized' + ... print('non-optimized') ... sys.ps1 = '---' ... """ % dict(python_exe=nt_quote_arg(sys.executable))) >>> f.close() >>> input, output = os.popen4(nt_quote_arg(os.path.join(sample_directory, 'foo.exe'))) >>> input.close() - >>> print output.read(), + >>> print(output.read(),) \foo-script.py [] '' @@ -136,10 +136,10 @@ Finally, we'll run the script and check the result: >>> input, output = os.popen4('"'+nt_quote_arg(os.path.join(sample_directory, 'bar.exe')) ... + r' "%s" "Test Argument"' % os.path.join(sample_directory, 'test_output.txt')) >>> input.close() - >>> print output.read() + >>> print(output.read()) >>> f = open(os.path.join(sample_directory, 'test_output.txt'), 'rb') - >>> print f.read() + >>> print(f.read()) 'Test Argument' >>> f.close() -- cgit v1.2.3 From 6f6de308e3ade9a262308297f0a96af261c9dde5 Mon Sep 17 00:00:00 2001 From: Philip Thiem Date: Sat, 16 Feb 2013 11:34:11 -0600 Subject: Backout the pkg_resources.py fix --HG-- branch : distribute extra : rebase_source : d144d2afc763c9ed6420d32bad3015075d265226 --- setuptools/tests/win_script_wrapper.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/win_script_wrapper.txt b/setuptools/tests/win_script_wrapper.txt index 82719273..3dc725c8 100644 --- a/setuptools/tests/win_script_wrapper.txt +++ b/setuptools/tests/win_script_wrapper.txt @@ -54,11 +54,12 @@ the wrapper: ... + r' arg1 "arg 2" "arg \"2\\\"" "arg 4\\" "arg5 a\\b"') >>> input.write('hello\nworld\n') >>> input.close() - >>> print(output.read(),) + >>> print(output.read()) \foo-script.py ['arg1', 'arg 2', 'arg "2\\"', 'arg 4\\', 'arg5 a\\\\b'] 'hello\nworld\n' non-optimized + This example was a little pathological in that it exercised windows (MS C runtime) quoting rules: @@ -97,11 +98,12 @@ enter the interpreter after running the script, you could use -Oi: >>> input, output = os.popen4(nt_quote_arg(os.path.join(sample_directory, 'foo.exe'))) >>> input.close() - >>> print(output.read(),) + >>> print(output.read()) \foo-script.py [] '' --- + Testing the GUI Version ----------------------- -- cgit v1.2.3 From 4bb7aab67a2ba4c890732d053a64737486b31b60 Mon Sep 17 00:00:00 2001 From: Philip Thiem Date: Sat, 16 Feb 2013 15:02:50 -0600 Subject: There were some failing tests on windows. I assume this is a NTFS vs FAT or NT versus 9x things... Seemed odd. In any case. My filesystem is deifnitely NOT cp1252. --HG-- branch : distribute extra : rebase_source : c4d64aff6b811ba36bbf33cd4cf2a12f563a6880 --- setuptools/tests/test_sdist.py | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_sdist.py b/setuptools/tests/test_sdist.py index a9d5d6e5..7e6c837c 100644 --- a/setuptools/tests/test_sdist.py +++ b/setuptools/tests/test_sdist.py @@ -337,10 +337,16 @@ class TestSdistTest(unittest.TestCase): filename = decompose(filename) if sys.version_info >= (3,): - if sys.platform == 'win32': - # Python 3 mangles the UTF-8 filename - filename = filename.decode('cp1252') - self.assertTrue(filename in cmd.filelist.files) + fs_enc = sys.getfilesystemencoding() + + if sys.platform == 'win32': + if fs_enc == 'cp1252': + # Python 3 mangles the UTF-8 filename + filename = filename.decode('cp1252') + self.assertTrue(filename in cmd.filelist.files) + else: + filename = filename.decode('mbcs') + self.assertTrue(filename in cmd.filelist.files) else: filename = filename.decode('utf-8') self.assertTrue(filename in cmd.filelist.files) @@ -357,6 +363,7 @@ class TestSdistTest(unittest.TestCase): # Latin-1 filename filename = os.path.join(b('sdist_test'), LATIN1_FILENAME) open(filename, 'w').close() + self.assertTrue(os.path.isfile(filename)) quiet() try: @@ -365,16 +372,27 @@ class TestSdistTest(unittest.TestCase): unquiet() if sys.version_info >= (3,): - filename = filename.decode('latin-1') + fs_enc = sys.getfilesystemencoding() + + + #not all windows systems have a default FS encoding of cp1252 if sys.platform == 'win32': - # Latin-1 is similar to Windows-1252 + # Latin-1 is similar to Windows-1252 however + # on mbcs filesys it is not in latin-1 encoding + if fs_enc == 'mbcs': + filename = filename.decode('mbcs') + else: + filename = filename.decode('latin-1') + self.assertTrue(filename in cmd.filelist.files) else: # The Latin-1 filename should have been skipped + filename = filename.decode('latin-1') self.assertFalse(filename in cmd.filelist.files) else: # No conversion takes place under Python 2 and the file # is included. We shall keep it that way for BBB. + filename = filename.decode('latin-1') self.assertTrue(filename in cmd.filelist.files) -- cgit v1.2.3 From 968ff8401b82ad8454191f564c903b137a8e8714 Mon Sep 17 00:00:00 2001 From: Philip Thiem Date: Sat, 16 Feb 2013 15:04:00 -0600 Subject: old win wrapper script not expecting return values from write() python 3 no longer has popen4 had some issue with ^M on end on line. --HG-- branch : distribute extra : rebase_source : 5b2c834e9a8dfd4027791cacef7c2bfe03652f31 --- setuptools/tests/win_script_wrapper.txt | 61 +++++++++++++++++++++++---------- 1 file changed, 43 insertions(+), 18 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/win_script_wrapper.txt b/setuptools/tests/win_script_wrapper.txt index 3dc725c8..db1daf6b 100644 --- a/setuptools/tests/win_script_wrapper.txt +++ b/setuptools/tests/win_script_wrapper.txt @@ -17,7 +17,7 @@ Let's create a simple script, foo-script.py: >>> from setuptools.command.easy_install import nt_quote_arg >>> sample_directory = tempfile.mkdtemp() >>> f = open(os.path.join(sample_directory, 'foo-script.py'), 'w') - >>> f.write( + >>> bytes_written = f.write( ... """#!%(python_exe)s ... import sys ... input = repr(sys.stdin.read()) @@ -37,7 +37,7 @@ We'll also copy cli.exe to the sample-directory with the name foo.exe: >>> import pkg_resources >>> f = open(os.path.join(sample_directory, 'foo.exe'), 'wb') - >>> f.write( + >>> bytes_written = f.write( ... pkg_resources.resource_string('setuptools', 'cli-32.exe') ... ) >>> f.close() @@ -49,12 +49,32 @@ GUI programs, the suffix '-script-pyw' is added.) This is why we named out script the way we did. Now we can run out script by running the wrapper: - >>> import os - >>> input, output = os.popen4('"'+nt_quote_arg(os.path.join(sample_directory, 'foo.exe')) - ... + r' arg1 "arg 2" "arg \"2\\\"" "arg 4\\" "arg5 a\\b"') - >>> input.write('hello\nworld\n') + >>> from subprocess import Popen, PIPE, STDOUT + >>> try: + ... unicode=unicode + ... except: + ... unicode=str + >>> def popen4(cmd, *args): + ... if hasattr(os, 'popen4'): + ... input, output = os.popen4(cmd + " ".join(args)) + ... return input, output + ... else: + ... #emulate popen4 in python 3 + ... if cmd[0] == '"' and cmd[-1] != '"': + ... cmd = cmd[1:] + ... cmd += " ".join(args) + ... p = Popen(cmd, shell=True, bufsize=0, + ... stdin=PIPE, stdout=PIPE, stderr=STDOUT) + ... return p.stdin, p.stdout + + >>> input, output = popen4('"' + nt_quote_arg(os.path.join(sample_directory, 'foo.exe')), + ... r' arg1', r'"arg 2"', r'"arg \"2\\\""', r'"arg 4\\"', r'"arg5 a\\b"') + >>> bytes_written = input.write('hello\nworld\n'.encode('utf-8')) >>> input.close() - >>> print(output.read()) + >>> # This is needed for line ending differences between py2 and py3 on win32 + >>> msg = unicode(output.read(), encoding='utf-8').split("\n") + >>> for line in msg: + ... print(line.strip()) \foo-script.py ['arg1', 'arg 2', 'arg "2\\"', 'arg 4\\', 'arg5 a\\\\b'] 'hello\nworld\n' @@ -83,7 +103,7 @@ options as usual. For example, to run in optimized mode and enter the interpreter after running the script, you could use -Oi: >>> f = open(os.path.join(sample_directory, 'foo-script.py'), 'w') - >>> f.write( + >>> bytes_written = f.write( ... """#!%(python_exe)s -Oi ... import sys ... input = repr(sys.stdin.read()) @@ -96,9 +116,12 @@ enter the interpreter after running the script, you could use -Oi: ... """ % dict(python_exe=nt_quote_arg(sys.executable))) >>> f.close() - >>> input, output = os.popen4(nt_quote_arg(os.path.join(sample_directory, 'foo.exe'))) + >>> input, output = popen4(nt_quote_arg(os.path.join(sample_directory, 'foo.exe'))) >>> input.close() - >>> print(output.read()) + >>> # This is needed for line ending differences between py2 and py3 on win32 + >>> msg = unicode(output.read(), encoding='utf-8').split("\n") + >>> for line in msg: + ... print(line.strip()) \foo-script.py [] '' @@ -114,11 +137,11 @@ Now let's test the GUI version with the simple scipt, bar-script.py: >>> from setuptools.command.easy_install import nt_quote_arg >>> sample_directory = tempfile.mkdtemp() >>> f = open(os.path.join(sample_directory, 'bar-script.pyw'), 'w') - >>> f.write( + >>> bytes_written = f.write( ... """#!%(python_exe)s ... import sys ... f = open(sys.argv[1], 'wb') - ... f.write(repr(sys.argv[2])) + ... bytes_written = f.write(repr(sys.argv[2]).encode('utf-8')) ... f.close() ... """ % dict(python_exe=nt_quote_arg(sys.executable))) >>> f.close() @@ -127,21 +150,23 @@ We'll also copy gui.exe to the sample-directory with the name bar.exe: >>> import pkg_resources >>> f = open(os.path.join(sample_directory, 'bar.exe'), 'wb') - >>> f.write( + >>> bytes_written = f.write( ... pkg_resources.resource_string('setuptools', 'gui-32.exe') ... ) >>> f.close() Finally, we'll run the script and check the result: - >>> import os - >>> input, output = os.popen4('"'+nt_quote_arg(os.path.join(sample_directory, 'bar.exe')) - ... + r' "%s" "Test Argument"' % os.path.join(sample_directory, 'test_output.txt')) + >>> input, output = popen4('"'+nt_quote_arg(os.path.join(sample_directory, 'bar.exe')), + ... r' "%s" "Test Argument"' % os.path.join(sample_directory, 'test_output.txt')) >>> input.close() - >>> print(output.read()) + >>> # This is needed for line ending differences between py2 and py3 on win32 + >>> msg = unicode(output.read(), encoding='utf-8').split("\n") + >>> for line in msg: + ... print(line.strip()) >>> f = open(os.path.join(sample_directory, 'test_output.txt'), 'rb') - >>> print(f.read()) + >>> print(unicode(f.read(), encoding='utf-8')) 'Test Argument' >>> f.close() -- cgit v1.2.3 From e9685aa408ac3d118890bd9944bd26260e519908 Mon Sep 17 00:00:00 2001 From: Philip Thiem Date: Sat, 16 Feb 2013 15:22:46 -0600 Subject: don't decode in python 2.x. that's my oops --HG-- branch : distribute extra : rebase_source : 4b981d54c6a171d7a6500c6c62838d8c368ae0b1 --- setuptools/tests/test_sdist.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'setuptools') diff --git a/setuptools/tests/test_sdist.py b/setuptools/tests/test_sdist.py index 7e6c837c..f51d4567 100644 --- a/setuptools/tests/test_sdist.py +++ b/setuptools/tests/test_sdist.py @@ -372,13 +372,11 @@ class TestSdistTest(unittest.TestCase): unquiet() if sys.version_info >= (3,): - fs_enc = sys.getfilesystemencoding() - - #not all windows systems have a default FS encoding of cp1252 if sys.platform == 'win32': # Latin-1 is similar to Windows-1252 however # on mbcs filesys it is not in latin-1 encoding + fs_enc = sys.getfilesystemencoding() if fs_enc == 'mbcs': filename = filename.decode('mbcs') else: @@ -392,7 +390,6 @@ class TestSdistTest(unittest.TestCase): else: # No conversion takes place under Python 2 and the file # is included. We shall keep it that way for BBB. - filename = filename.decode('latin-1') self.assertTrue(filename in cmd.filelist.files) -- cgit v1.2.3 From e3207bd63bcf365a1f91b7c3e75a4b3354435501 Mon Sep 17 00:00:00 2001 From: Dirley Rodrigues Date: Mon, 4 Feb 2013 11:30:58 -0200 Subject: Improve external links finder to not yield duplicate links. --HG-- branch : distribute extra : rebase_source : 78e932fca32ee0ee1f50794cf998f4e7db78131b --- setuptools/package_index.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'setuptools') diff --git a/setuptools/package_index.py b/setuptools/package_index.py index 0ee21e3b..4393c83a 100755 --- a/setuptools/package_index.py +++ b/setuptools/package_index.py @@ -139,20 +139,26 @@ REL = re.compile("""<([^>]*\srel\s*=\s*['"]?([^'">]+)[^>]*)>""", re.I) def find_external_links(url, page): """Find rel="homepage" and rel="download" links in `page`, yielding URLs""" + seen = set() for match in REL.finditer(page): tag, rel = match.groups() rels = map(str.strip, rel.lower().split(',')) if 'homepage' in rels or 'download' in rels: for match in HREF.finditer(tag): - yield urlparse.urljoin(url, htmldecode(match.group(1))) + url = urlparse.urljoin(url, htmldecode(match.group(1))) + if not url in seen: + yield url for tag in ("Home Page", "Download URL"): pos = page.find(tag) if pos!=-1: match = HREF.search(page,pos) if match: - yield urlparse.urljoin(url, htmldecode(match.group(1))) + url = urlparse.urljoin(url, htmldecode(match.group(1))) + if not url in seen: + yield url + user_agent = "Python-urllib/%s distribute/%s" % ( sys.version[:3], require('distribute')[0].version -- cgit v1.2.3 From 116420fe62842f18f2d37de46c2177028231755a Mon Sep 17 00:00:00 2001 From: Dirley Rodrigues Date: Mon, 4 Feb 2013 11:39:28 -0200 Subject: avoid naming problems --HG-- branch : distribute extra : rebase_source : 29eeb99013055b8d27cad7f7e8898d06a865b188 --- setuptools/package_index.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'setuptools') diff --git a/setuptools/package_index.py b/setuptools/package_index.py index 4393c83a..984feef4 100755 --- a/setuptools/package_index.py +++ b/setuptools/package_index.py @@ -139,25 +139,25 @@ REL = re.compile("""<([^>]*\srel\s*=\s*['"]?([^'">]+)[^>]*)>""", re.I) def find_external_links(url, page): """Find rel="homepage" and rel="download" links in `page`, yielding URLs""" - seen = set() + seen_links = set() for match in REL.finditer(page): tag, rel = match.groups() rels = map(str.strip, rel.lower().split(',')) if 'homepage' in rels or 'download' in rels: for match in HREF.finditer(tag): - url = urlparse.urljoin(url, htmldecode(match.group(1))) - if not url in seen: - yield url + link = urlparse.urljoin(url, htmldecode(match.group(1))) + if not link in seen_links: + yield link for tag in ("Home Page", "Download URL"): pos = page.find(tag) if pos!=-1: match = HREF.search(page,pos) if match: - url = urlparse.urljoin(url, htmldecode(match.group(1))) - if not url in seen: - yield url + link = urlparse.urljoin(url, htmldecode(match.group(1))) + if not link in seen_links: + yield link user_agent = "Python-urllib/%s distribute/%s" % ( -- cgit v1.2.3 From d7ba7ce3c4ce2427d78cb2393bd062aa3a8496b4 Mon Sep 17 00:00:00 2001 From: Dirley Rodrigues Date: Mon, 4 Feb 2013 11:54:53 -0200 Subject: actually filter the links --HG-- branch : distribute extra : rebase_source : cb6e3497e1f8594181f10110cbc833bd6c81f89e --- setuptools/package_index.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'setuptools') diff --git a/setuptools/package_index.py b/setuptools/package_index.py index 984feef4..8974a647 100755 --- a/setuptools/package_index.py +++ b/setuptools/package_index.py @@ -148,6 +148,7 @@ def find_external_links(url, page): for match in HREF.finditer(tag): link = urlparse.urljoin(url, htmldecode(match.group(1))) if not link in seen_links: + seen_links.add(link) yield link for tag in ("Home Page", "Download URL"): @@ -157,6 +158,7 @@ def find_external_links(url, page): if match: link = urlparse.urljoin(url, htmldecode(match.group(1))) if not link in seen_links: + seen_links.add(link) yield link -- cgit v1.2.3 From b8327d7f646141415beb30acd39ce8840ebc708b Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 24 May 2013 10:36:51 -0400 Subject: Add unique_everseen from Python 2.7 docs --HG-- branch : distribute --- setuptools/package_index.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'setuptools') diff --git a/setuptools/package_index.py b/setuptools/package_index.py index 8974a647..e542f586 100755 --- a/setuptools/package_index.py +++ b/setuptools/package_index.py @@ -1,5 +1,6 @@ """PyPI and direct package downloading""" import sys, os.path, re, urlparse, urllib, urllib2, shutil, random, socket, cStringIO +import itertools import base64 import httplib from pkg_resources import * @@ -134,6 +135,24 @@ def interpret_distro_name(location, basename, metadata, platform = platform ) +# From Python 2.7 docs +def unique_everseen(iterable, key=None): + "List unique elements, preserving order. Remember all elements ever seen." + # unique_everseen('AAAABBBCCDAABBB') --> A B C D + # unique_everseen('ABBCcAD', str.lower) --> A B C D + seen = set() + seen_add = seen.add + if key is None: + for element in itertools.ifilterfalse(seen.__contains__, iterable): + seen_add(element) + yield element + else: + for element in iterable: + k = key(element) + if k not in seen: + seen_add(k) + yield element + REL = re.compile("""<([^>]*\srel\s*=\s*['"]?([^'">]+)[^>]*)>""", re.I) # this line is here to fix emacs' cruddy broken syntax highlighting -- cgit v1.2.3 From 3b9a57a0c80ee11995fbe937e7dbeca3d83ec10a Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 24 May 2013 11:02:05 -0400 Subject: Use a wrapper to ensure unique values on find_external_links. Factors out uniqueness test into a re-usable decorator and simplifies the body of find_external_links. --HG-- branch : distribute --- setuptools/package_index.py | 24 +++++++++++++++--------- setuptools/py24compat.py | 11 +++++++++++ 2 files changed, 26 insertions(+), 9 deletions(-) create mode 100644 setuptools/py24compat.py (limited to 'setuptools') diff --git a/setuptools/package_index.py b/setuptools/package_index.py index e542f586..0a3f9e05 100755 --- a/setuptools/package_index.py +++ b/setuptools/package_index.py @@ -12,6 +12,8 @@ except ImportError: from md5 import md5 from fnmatch import translate +from .py24compat import wraps + EGG_FRAGMENT = re.compile(r'^egg=([-A-Za-z0-9_.]+)$') HREF = re.compile("""href\\s*=\\s*['"]?([^'"> ]+)""", re.I) # this is here to fix emacs' cruddy broken syntax highlighting @@ -153,32 +155,36 @@ def unique_everseen(iterable, key=None): seen_add(k) yield element +def unique_values(func): + """ + Wrap a function returning an iterable such that the resulting iterable + only ever yields unique items. + """ + @wraps(func) + def wrapper(*args, **kwargs): + return unique_everseen(func(*args, **kwargs)) + return wrapper + REL = re.compile("""<([^>]*\srel\s*=\s*['"]?([^'">]+)[^>]*)>""", re.I) # this line is here to fix emacs' cruddy broken syntax highlighting +@unique_values def find_external_links(url, page): """Find rel="homepage" and rel="download" links in `page`, yielding URLs""" - seen_links = set() for match in REL.finditer(page): tag, rel = match.groups() rels = map(str.strip, rel.lower().split(',')) if 'homepage' in rels or 'download' in rels: for match in HREF.finditer(tag): - link = urlparse.urljoin(url, htmldecode(match.group(1))) - if not link in seen_links: - seen_links.add(link) - yield link + yield urlparse.urljoin(url, htmldecode(match.group(1))) for tag in ("Home Page", "Download URL"): pos = page.find(tag) if pos!=-1: match = HREF.search(page,pos) if match: - link = urlparse.urljoin(url, htmldecode(match.group(1))) - if not link in seen_links: - seen_links.add(link) - yield link + yield urlparse.urljoin(url, htmldecode(match.group(1))) user_agent = "Python-urllib/%s distribute/%s" % ( diff --git a/setuptools/py24compat.py b/setuptools/py24compat.py new file mode 100644 index 00000000..c5d7d204 --- /dev/null +++ b/setuptools/py24compat.py @@ -0,0 +1,11 @@ +""" +Forward-compatibility support for Python 2.4 and earlier +""" + +# from jaraco.compat 1.2 +try: + from functools import wraps +except ImportError: + def wraps(func): + "Just return the function unwrapped" + return lambda x: x -- cgit v1.2.3 From 8c89c9438e9e461acc7587b60c79fb94b4d1f06d Mon Sep 17 00:00:00 2001 From: PJ Eby Date: Fri, 14 Apr 2006 19:38:38 +0000 Subject: First round of prepping setuptools for inclusion in Python 2.5: move site.py to setuptools/site-patch.py; reinstate 'python -m easy_install' support; use distutils' "upload" command when running under 2.5. --HG-- branch : distribute extra : source : fbb6c89a74aa47a556a936202d2e50051b067940 extra : histedit_source : 778122fc56bcca6f5a1dbd5a475df11d29028730 --- setuptools/command/easy_install.py | 2 +- setuptools/site-patch.py | 83 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 setuptools/site-patch.py (limited to 'setuptools') diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py index df6107d7..77b0bc31 100755 --- a/setuptools/command/easy_install.py +++ b/setuptools/command/easy_install.py @@ -1277,7 +1277,7 @@ Please make the appropriate changes for your system and try again.""" % ( return # already did it, or don't need to sitepy = os.path.join(self.install_dir, "site.py") - source = resource_string(Requirement.parse("distribute"), "site.py") + source = resource_string("setuptools", "site-patch.py") current = "" if os.path.exists(sitepy): diff --git a/setuptools/site-patch.py b/setuptools/site-patch.py new file mode 100644 index 00000000..a7166f14 --- /dev/null +++ b/setuptools/site-patch.py @@ -0,0 +1,83 @@ +def __boot(): + import sys, os, os.path + PYTHONPATH = os.environ.get('PYTHONPATH') + if PYTHONPATH is None or (sys.platform=='win32' and not PYTHONPATH): + PYTHONPATH = [] + else: + PYTHONPATH = PYTHONPATH.split(os.pathsep) + + pic = getattr(sys,'path_importer_cache',{}) + stdpath = sys.path[len(PYTHONPATH):] + mydir = os.path.dirname(__file__) + #print "searching",stdpath,sys.path + + for item in stdpath: + if item==mydir or not item: + continue # skip if current dir. on Windows, or my own directory + importer = pic.get(item) + if importer is not None: + loader = importer.find_module('site') + if loader is not None: + # This should actually reload the current module + loader.load_module('site') + break + else: + try: + import imp # Avoid import loop in Python >= 3.3 + stream, path, descr = imp.find_module('site',[item]) + except ImportError: + continue + if stream is None: + continue + try: + # This should actually reload the current module + imp.load_module('site',stream,path,descr) + finally: + stream.close() + break + else: + raise ImportError("Couldn't find the real 'site' module") + + #print "loaded", __file__ + + known_paths = dict([(makepath(item)[1],1) for item in sys.path]) # 2.2 comp + + oldpos = getattr(sys,'__egginsert',0) # save old insertion position + sys.__egginsert = 0 # and reset the current one + + for item in PYTHONPATH: + addsitedir(item) + + sys.__egginsert += oldpos # restore effective old position + + d,nd = makepath(stdpath[0]) + insert_at = None + new_path = [] + + for item in sys.path: + p,np = makepath(item) + + if np==nd and insert_at is None: + # We've hit the first 'system' path entry, so added entries go here + insert_at = len(new_path) + + if np in known_paths or insert_at is None: + new_path.append(item) + else: + # new path after the insert point, back-insert it + new_path.insert(insert_at, item) + insert_at += 1 + + sys.path[:] = new_path + +if __name__=='site': + __boot() + del __boot + + + + + + + + -- cgit v1.2.3 From 2b48816298bc0ad2632a393560176ed151149aa5 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Fri, 24 May 2013 20:37:47 -0400 Subject: Restore Python 2.4 compatible syntax --HG-- branch : distribute --- 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 0a3f9e05..b0388628 100755 --- a/setuptools/package_index.py +++ b/setuptools/package_index.py @@ -12,7 +12,7 @@ except ImportError: from md5 import md5 from fnmatch import translate -from .py24compat import wraps +from setuptools.py24compat import wraps EGG_FRAGMENT = re.compile(r'^egg=([-A-Za-z0-9_.]+)$') HREF = re.compile("""href\\s*=\\s*['"]?([^'"> ]+)""", re.I) -- cgit v1.2.3