Index: recipe_engine/third_party/setuptools/tests/test_resources.py |
diff --git a/recipe_engine/third_party/setuptools/tests/test_resources.py b/recipe_engine/third_party/setuptools/tests/test_resources.py |
new file mode 100644 |
index 0000000000000000000000000000000000000000..1902fb2ce4bc733f8aabe594a0fe33d0ea0fb544 |
--- /dev/null |
+++ b/recipe_engine/third_party/setuptools/tests/test_resources.py |
@@ -0,0 +1,655 @@ |
+#!/usr/bin/python |
+# -*- coding: utf-8 -*- |
+# NOTE: the shebang and encoding lines are for ScriptHeaderTests do not remove |
+ |
+import os |
+import sys |
+import tempfile |
+import shutil |
+from unittest import TestCase |
+ |
+import setuptools._vendor.packaging.version |
+import setuptools._vendor.packaging.specifiers |
+packaging = setuptools._vendor.packaging |
+ |
+import pkg_resources |
+from pkg_resources import (parse_requirements, VersionConflict, parse_version, |
+ Distribution, EntryPoint, Requirement, safe_version, safe_name, |
+ WorkingSet) |
+ |
+from setuptools.command.easy_install import (get_script_header, is_sh, |
+ nt_quote_arg) |
+from setuptools.compat import StringIO, iteritems, PY3 |
+from .py26compat import skipIf |
+ |
+def safe_repr(obj, short=False): |
+ """ copied from Python2.7""" |
+ try: |
+ result = repr(obj) |
+ except Exception: |
+ result = object.__repr__(obj) |
+ if not short or len(result) < pkg_resources._MAX_LENGTH: |
+ return result |
+ return result[:pkg_resources._MAX_LENGTH] + ' [truncated]...' |
+ |
+class Metadata(pkg_resources.EmptyProvider): |
+ """Mock object to return metadata as if from an on-disk distribution""" |
+ |
+ def __init__(self,*pairs): |
+ self.metadata = dict(pairs) |
+ |
+ def has_metadata(self,name): |
+ return name in self.metadata |
+ |
+ def get_metadata(self,name): |
+ return self.metadata[name] |
+ |
+ def get_metadata_lines(self,name): |
+ return pkg_resources.yield_lines(self.get_metadata(name)) |
+ |
+dist_from_fn = pkg_resources.Distribution.from_filename |
+ |
+class DistroTests(TestCase): |
+ |
+ def testCollection(self): |
+ # empty path should produce no distributions |
+ ad = pkg_resources.Environment([], platform=None, python=None) |
+ self.assertEqual(list(ad), []) |
+ self.assertEqual(ad['FooPkg'],[]) |
+ ad.add(dist_from_fn("FooPkg-1.3_1.egg")) |
+ ad.add(dist_from_fn("FooPkg-1.4-py2.4-win32.egg")) |
+ ad.add(dist_from_fn("FooPkg-1.2-py2.4.egg")) |
+ |
+ # Name is in there now |
+ self.assertTrue(ad['FooPkg']) |
+ # But only 1 package |
+ self.assertEqual(list(ad), ['foopkg']) |
+ |
+ # Distributions sort by version |
+ self.assertEqual( |
+ [dist.version for dist in ad['FooPkg']], ['1.4','1.3-1','1.2'] |
+ ) |
+ # Removing a distribution leaves sequence alone |
+ ad.remove(ad['FooPkg'][1]) |
+ self.assertEqual( |
+ [dist.version for dist in ad['FooPkg']], ['1.4','1.2'] |
+ ) |
+ # And inserting adds them in order |
+ ad.add(dist_from_fn("FooPkg-1.9.egg")) |
+ self.assertEqual( |
+ [dist.version for dist in ad['FooPkg']], ['1.9','1.4','1.2'] |
+ ) |
+ |
+ ws = WorkingSet([]) |
+ foo12 = dist_from_fn("FooPkg-1.2-py2.4.egg") |
+ foo14 = dist_from_fn("FooPkg-1.4-py2.4-win32.egg") |
+ req, = parse_requirements("FooPkg>=1.3") |
+ |
+ # Nominal case: no distros on path, should yield all applicable |
+ self.assertEqual(ad.best_match(req,ws).version, '1.9') |
+ # If a matching distro is already installed, should return only that |
+ ws.add(foo14) |
+ self.assertEqual(ad.best_match(req,ws).version, '1.4') |
+ |
+ # If the first matching distro is unsuitable, it's a version conflict |
+ ws = WorkingSet([]) |
+ ws.add(foo12) |
+ ws.add(foo14) |
+ self.assertRaises(VersionConflict, ad.best_match, req, ws) |
+ |
+ # If more than one match on the path, the first one takes precedence |
+ ws = WorkingSet([]) |
+ ws.add(foo14) |
+ ws.add(foo12) |
+ ws.add(foo14) |
+ self.assertEqual(ad.best_match(req,ws).version, '1.4') |
+ |
+ def checkFooPkg(self,d): |
+ self.assertEqual(d.project_name, "FooPkg") |
+ self.assertEqual(d.key, "foopkg") |
+ self.assertEqual(d.version, "1.3.post1") |
+ self.assertEqual(d.py_version, "2.4") |
+ self.assertEqual(d.platform, "win32") |
+ self.assertEqual(d.parsed_version, parse_version("1.3-1")) |
+ |
+ def testDistroBasics(self): |
+ d = Distribution( |
+ "/some/path", |
+ project_name="FooPkg",version="1.3-1",py_version="2.4",platform="win32" |
+ ) |
+ self.checkFooPkg(d) |
+ |
+ d = Distribution("/some/path") |
+ self.assertEqual(d.py_version, sys.version[:3]) |
+ self.assertEqual(d.platform, None) |
+ |
+ def testDistroParse(self): |
+ d = dist_from_fn("FooPkg-1.3.post1-py2.4-win32.egg") |
+ self.checkFooPkg(d) |
+ d = dist_from_fn("FooPkg-1.3.post1-py2.4-win32.egg-info") |
+ self.checkFooPkg(d) |
+ |
+ def testDistroMetadata(self): |
+ d = Distribution( |
+ "/some/path", project_name="FooPkg", py_version="2.4", platform="win32", |
+ metadata = Metadata( |
+ ('PKG-INFO',"Metadata-Version: 1.0\nVersion: 1.3-1\n") |
+ ) |
+ ) |
+ self.checkFooPkg(d) |
+ |
+ def distRequires(self, txt): |
+ return Distribution("/foo", metadata=Metadata(('depends.txt', txt))) |
+ |
+ def checkRequires(self, dist, txt, extras=()): |
+ self.assertEqual( |
+ list(dist.requires(extras)), |
+ list(parse_requirements(txt)) |
+ ) |
+ |
+ def testDistroDependsSimple(self): |
+ for v in "Twisted>=1.5", "Twisted>=1.5\nZConfig>=2.0": |
+ self.checkRequires(self.distRequires(v), v) |
+ |
+ def testResolve(self): |
+ ad = pkg_resources.Environment([]) |
+ ws = WorkingSet([]) |
+ # Resolving no requirements -> nothing to install |
+ self.assertEqual(list(ws.resolve([],ad)), []) |
+ # Request something not in the collection -> DistributionNotFound |
+ self.assertRaises( |
+ pkg_resources.DistributionNotFound, ws.resolve, parse_requirements("Foo"), ad |
+ ) |
+ Foo = Distribution.from_filename( |
+ "/foo_dir/Foo-1.2.egg", |
+ metadata=Metadata(('depends.txt', "[bar]\nBaz>=2.0")) |
+ ) |
+ ad.add(Foo) |
+ ad.add(Distribution.from_filename("Foo-0.9.egg")) |
+ |
+ # Request thing(s) that are available -> list to activate |
+ for i in range(3): |
+ targets = list(ws.resolve(parse_requirements("Foo"), ad)) |
+ self.assertEqual(targets, [Foo]) |
+ list(map(ws.add,targets)) |
+ self.assertRaises(VersionConflict, ws.resolve, |
+ parse_requirements("Foo==0.9"), ad) |
+ ws = WorkingSet([]) # reset |
+ |
+ # Request an extra that causes an unresolved dependency for "Baz" |
+ self.assertRaises( |
+ pkg_resources.DistributionNotFound, ws.resolve,parse_requirements("Foo[bar]"), ad |
+ ) |
+ Baz = Distribution.from_filename( |
+ "/foo_dir/Baz-2.1.egg", metadata=Metadata(('depends.txt', "Foo")) |
+ ) |
+ ad.add(Baz) |
+ |
+ # Activation list now includes resolved dependency |
+ self.assertEqual( |
+ list(ws.resolve(parse_requirements("Foo[bar]"), ad)), [Foo,Baz] |
+ ) |
+ # Requests for conflicting versions produce VersionConflict |
+ self.assertRaises(VersionConflict, |
+ ws.resolve, parse_requirements("Foo==1.2\nFoo!=1.2"), ad) |
+ |
+ def testDistroDependsOptions(self): |
+ d = self.distRequires(""" |
+ Twisted>=1.5 |
+ [docgen] |
+ ZConfig>=2.0 |
+ docutils>=0.3 |
+ [fastcgi] |
+ fcgiapp>=0.1""") |
+ self.checkRequires(d,"Twisted>=1.5") |
+ self.checkRequires( |
+ d,"Twisted>=1.5 ZConfig>=2.0 docutils>=0.3".split(), ["docgen"] |
+ ) |
+ self.checkRequires( |
+ d,"Twisted>=1.5 fcgiapp>=0.1".split(), ["fastcgi"] |
+ ) |
+ self.checkRequires( |
+ d,"Twisted>=1.5 ZConfig>=2.0 docutils>=0.3 fcgiapp>=0.1".split(), |
+ ["docgen","fastcgi"] |
+ ) |
+ self.checkRequires( |
+ d,"Twisted>=1.5 fcgiapp>=0.1 ZConfig>=2.0 docutils>=0.3".split(), |
+ ["fastcgi", "docgen"] |
+ ) |
+ self.assertRaises(pkg_resources.UnknownExtra, d.requires, ["foo"]) |
+ |
+ |
+class EntryPointTests(TestCase): |
+ |
+ def assertfields(self, ep): |
+ self.assertEqual(ep.name,"foo") |
+ self.assertEqual(ep.module_name,"setuptools.tests.test_resources") |
+ self.assertEqual(ep.attrs, ("EntryPointTests",)) |
+ self.assertEqual(ep.extras, ("x",)) |
+ self.assertTrue(ep.load() is EntryPointTests) |
+ self.assertEqual( |
+ str(ep), |
+ "foo = setuptools.tests.test_resources:EntryPointTests [x]" |
+ ) |
+ |
+ def setUp(self): |
+ self.dist = Distribution.from_filename( |
+ "FooPkg-1.2-py2.4.egg", metadata=Metadata(('requires.txt','[x]'))) |
+ |
+ def testBasics(self): |
+ ep = EntryPoint( |
+ "foo", "setuptools.tests.test_resources", ["EntryPointTests"], |
+ ["x"], self.dist |
+ ) |
+ self.assertfields(ep) |
+ |
+ def testParse(self): |
+ s = "foo = setuptools.tests.test_resources:EntryPointTests [x]" |
+ ep = EntryPoint.parse(s, self.dist) |
+ self.assertfields(ep) |
+ |
+ ep = EntryPoint.parse("bar baz= spammity[PING]") |
+ self.assertEqual(ep.name,"bar baz") |
+ self.assertEqual(ep.module_name,"spammity") |
+ self.assertEqual(ep.attrs, ()) |
+ self.assertEqual(ep.extras, ("ping",)) |
+ |
+ ep = EntryPoint.parse(" fizzly = wocka:foo") |
+ self.assertEqual(ep.name,"fizzly") |
+ self.assertEqual(ep.module_name,"wocka") |
+ self.assertEqual(ep.attrs, ("foo",)) |
+ self.assertEqual(ep.extras, ()) |
+ |
+ def testRejects(self): |
+ for ep in [ |
+ "foo", "x=1=2", "x=a:b:c", "q=x/na", "fez=pish:tush-z", "x=f[a]>2", |
+ ]: |
+ try: EntryPoint.parse(ep) |
+ except ValueError: pass |
+ else: raise AssertionError("Should've been bad", ep) |
+ |
+ def checkSubMap(self, m): |
+ self.assertEqual(len(m), len(self.submap_expect)) |
+ for key, ep in iteritems(self.submap_expect): |
+ self.assertEqual(repr(m.get(key)), repr(ep)) |
+ |
+ submap_expect = dict( |
+ feature1=EntryPoint('feature1', 'somemodule', ['somefunction']), |
+ feature2=EntryPoint('feature2', 'another.module', ['SomeClass'], ['extra1','extra2']), |
+ feature3=EntryPoint('feature3', 'this.module', extras=['something']) |
+ ) |
+ submap_str = """ |
+ # define features for blah blah |
+ feature1 = somemodule:somefunction |
+ feature2 = another.module:SomeClass [extra1,extra2] |
+ feature3 = this.module [something] |
+ """ |
+ |
+ def testParseList(self): |
+ self.checkSubMap(EntryPoint.parse_group("xyz", self.submap_str)) |
+ self.assertRaises(ValueError, EntryPoint.parse_group, "x a", "foo=bar") |
+ self.assertRaises(ValueError, EntryPoint.parse_group, "x", |
+ ["foo=baz", "foo=bar"]) |
+ |
+ def testParseMap(self): |
+ m = EntryPoint.parse_map({'xyz':self.submap_str}) |
+ self.checkSubMap(m['xyz']) |
+ self.assertEqual(list(m.keys()),['xyz']) |
+ m = EntryPoint.parse_map("[xyz]\n"+self.submap_str) |
+ self.checkSubMap(m['xyz']) |
+ self.assertEqual(list(m.keys()),['xyz']) |
+ self.assertRaises(ValueError, EntryPoint.parse_map, ["[xyz]", "[xyz]"]) |
+ self.assertRaises(ValueError, EntryPoint.parse_map, self.submap_str) |
+ |
+class RequirementsTests(TestCase): |
+ |
+ def testBasics(self): |
+ r = Requirement.parse("Twisted>=1.2") |
+ self.assertEqual(str(r),"Twisted>=1.2") |
+ self.assertEqual(repr(r),"Requirement.parse('Twisted>=1.2')") |
+ self.assertEqual(r, Requirement("Twisted", [('>=','1.2')], ())) |
+ self.assertEqual(r, Requirement("twisTed", [('>=','1.2')], ())) |
+ self.assertNotEqual(r, Requirement("Twisted", [('>=','2.0')], ())) |
+ self.assertNotEqual(r, Requirement("Zope", [('>=','1.2')], ())) |
+ self.assertNotEqual(r, Requirement("Zope", [('>=','3.0')], ())) |
+ self.assertNotEqual(r, Requirement.parse("Twisted[extras]>=1.2")) |
+ |
+ def testOrdering(self): |
+ r1 = Requirement("Twisted", [('==','1.2c1'),('>=','1.2')], ()) |
+ r2 = Requirement("Twisted", [('>=','1.2'),('==','1.2c1')], ()) |
+ self.assertEqual(r1,r2) |
+ self.assertEqual(str(r1),str(r2)) |
+ self.assertEqual(str(r2),"Twisted==1.2c1,>=1.2") |
+ |
+ def testBasicContains(self): |
+ r = Requirement("Twisted", [('>=','1.2')], ()) |
+ foo_dist = Distribution.from_filename("FooPkg-1.3_1.egg") |
+ twist11 = Distribution.from_filename("Twisted-1.1.egg") |
+ twist12 = Distribution.from_filename("Twisted-1.2.egg") |
+ self.assertTrue(parse_version('1.2') in r) |
+ self.assertTrue(parse_version('1.1') not in r) |
+ self.assertTrue('1.2' in r) |
+ self.assertTrue('1.1' not in r) |
+ self.assertTrue(foo_dist not in r) |
+ self.assertTrue(twist11 not in r) |
+ self.assertTrue(twist12 in r) |
+ |
+ def testOptionsAndHashing(self): |
+ r1 = Requirement.parse("Twisted[foo,bar]>=1.2") |
+ r2 = Requirement.parse("Twisted[bar,FOO]>=1.2") |
+ self.assertEqual(r1,r2) |
+ self.assertEqual(r1.extras, ("foo","bar")) |
+ self.assertEqual(r2.extras, ("bar","foo")) # extras are normalized |
+ self.assertEqual(hash(r1), hash(r2)) |
+ self.assertEqual( |
+ hash(r1), hash(("twisted", packaging.specifiers.SpecifierSet(">=1.2"), |
+ frozenset(["foo","bar"]))) |
+ ) |
+ |
+ def testVersionEquality(self): |
+ r1 = Requirement.parse("foo==0.3a2") |
+ r2 = Requirement.parse("foo!=0.3a4") |
+ d = Distribution.from_filename |
+ |
+ self.assertTrue(d("foo-0.3a4.egg") not in r1) |
+ self.assertTrue(d("foo-0.3a1.egg") not in r1) |
+ self.assertTrue(d("foo-0.3a4.egg") not in r2) |
+ |
+ self.assertTrue(d("foo-0.3a2.egg") in r1) |
+ self.assertTrue(d("foo-0.3a2.egg") in r2) |
+ self.assertTrue(d("foo-0.3a3.egg") in r2) |
+ self.assertTrue(d("foo-0.3a5.egg") in r2) |
+ |
+ def testSetuptoolsProjectName(self): |
+ """ |
+ The setuptools project should implement the setuptools package. |
+ """ |
+ |
+ self.assertEqual( |
+ Requirement.parse('setuptools').project_name, 'setuptools') |
+ # setuptools 0.7 and higher means setuptools. |
+ self.assertEqual( |
+ Requirement.parse('setuptools == 0.7').project_name, 'setuptools') |
+ self.assertEqual( |
+ Requirement.parse('setuptools == 0.7a1').project_name, 'setuptools') |
+ self.assertEqual( |
+ Requirement.parse('setuptools >= 0.7').project_name, 'setuptools') |
+ |
+ |
+class ParseTests(TestCase): |
+ |
+ def testEmptyParse(self): |
+ self.assertEqual(list(parse_requirements('')), []) |
+ |
+ def testYielding(self): |
+ for inp,out in [ |
+ ([], []), ('x',['x']), ([[]],[]), (' x\n y', ['x','y']), |
+ (['x\n\n','y'], ['x','y']), |
+ ]: |
+ self.assertEqual(list(pkg_resources.yield_lines(inp)),out) |
+ |
+ def testSplitting(self): |
+ sample = """ |
+ x |
+ [Y] |
+ z |
+ |
+ a |
+ [b ] |
+ # foo |
+ c |
+ [ d] |
+ [q] |
+ v |
+ """ |
+ self.assertEqual(list(pkg_resources.split_sections(sample)), |
+ [(None,["x"]), ("Y",["z","a"]), ("b",["c"]), ("d",[]), ("q",["v"])] |
+ ) |
+ self.assertRaises(ValueError,list,pkg_resources.split_sections("[foo")) |
+ |
+ def testSafeName(self): |
+ self.assertEqual(safe_name("adns-python"), "adns-python") |
+ self.assertEqual(safe_name("WSGI Utils"), "WSGI-Utils") |
+ self.assertEqual(safe_name("WSGI Utils"), "WSGI-Utils") |
+ self.assertEqual(safe_name("Money$$$Maker"), "Money-Maker") |
+ self.assertNotEqual(safe_name("peak.web"), "peak-web") |
+ |
+ def testSafeVersion(self): |
+ self.assertEqual(safe_version("1.2-1"), "1.2.post1") |
+ self.assertEqual(safe_version("1.2 alpha"), "1.2.alpha") |
+ self.assertEqual(safe_version("2.3.4 20050521"), "2.3.4.20050521") |
+ self.assertEqual(safe_version("Money$$$Maker"), "Money-Maker") |
+ self.assertEqual(safe_version("peak.web"), "peak.web") |
+ |
+ def testSimpleRequirements(self): |
+ self.assertEqual( |
+ list(parse_requirements('Twis-Ted>=1.2-1')), |
+ [Requirement('Twis-Ted',[('>=','1.2-1')], ())] |
+ ) |
+ self.assertEqual( |
+ list(parse_requirements('Twisted >=1.2, \ # more\n<2.0')), |
+ [Requirement('Twisted',[('>=','1.2'),('<','2.0')], ())] |
+ ) |
+ self.assertEqual( |
+ Requirement.parse("FooBar==1.99a3"), |
+ Requirement("FooBar", [('==','1.99a3')], ()) |
+ ) |
+ self.assertRaises(ValueError,Requirement.parse,">=2.3") |
+ self.assertRaises(ValueError,Requirement.parse,"x\\") |
+ self.assertRaises(ValueError,Requirement.parse,"x==2 q") |
+ self.assertRaises(ValueError,Requirement.parse,"X==1\nY==2") |
+ self.assertRaises(ValueError,Requirement.parse,"#") |
+ |
+ def testVersionEquality(self): |
+ def c(s1,s2): |
+ 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('0post1', '0.0post1') |
+ c('0pre1', '0.0c1') |
+ c('0.0.0preview1', '0c1') |
+ c('0.0c1', '0-rc1') |
+ c('1.2a1', '1.2.a.1') |
+ c('1.2.a', '1.2a') |
+ |
+ def testVersionOrdering(self): |
+ def c(s1,s2): |
+ p1, p2 = parse_version(s1),parse_version(s2) |
+ self.assertTrue(p1<p2, (s1,s2,p1,p2)) |
+ |
+ c('2.1','2.1.1') |
+ c('2a1','2b0') |
+ c('2a1','2.1') |
+ c('2.3a1', '2.3') |
+ c('2.1-1', '2.1-2') |
+ c('2.1-1', '2.1.1') |
+ c('2.1', '2.1post4') |
+ c('2.1a0-20040501', '2.1') |
+ c('1.1', '02.1') |
+ c('3.2', '3.2.post0') |
+ c('3.2post1', '3.2post2') |
+ c('0.4', '4.0') |
+ c('0.0.4', '0.4.0') |
+ c('0post1', '0.4post1') |
+ c('2.1.0-rc1','2.1.0') |
+ c('2.1dev','2.1a0') |
+ |
+ torture =""" |
+ 0.80.1-3 0.80.1-2 0.80.1-1 0.79.9999+0.80.0pre4-1 |
+ 0.79.9999+0.80.0pre2-3 0.79.9999+0.80.0pre2-2 |
+ 0.77.2-1 0.77.1-1 0.77.0-1 |
+ """.split() |
+ |
+ for p,v1 in enumerate(torture): |
+ for v2 in torture[p+1:]: |
+ c(v2,v1) |
+ |
+ def testVersionBuildout(self): |
+ """ |
+ Buildout has a function in it's bootstrap.py that inspected the return |
+ value of parse_version. The new parse_version returns a Version class |
+ which needs to support this behavior, at least for now. |
+ """ |
+ def buildout(parsed_version): |
+ _final_parts = '*final-', '*final' |
+ |
+ def _final_version(parsed_version): |
+ for part in parsed_version: |
+ if (part[:1] == '*') and (part not in _final_parts): |
+ return False |
+ return True |
+ return _final_version(parsed_version) |
+ |
+ self.assertTrue(buildout(parse_version("1.0"))) |
+ self.assertFalse(buildout(parse_version("1.0a1"))) |
+ |
+ def testVersionIndexable(self): |
+ """ |
+ Some projects were doing things like parse_version("v")[0], so we'll |
+ support indexing the same as we support iterating. |
+ """ |
+ self.assertEqual(parse_version("1.0")[0], "00000001") |
+ |
+ def testVersionTupleSort(self): |
+ """ |
+ Some projects expected to be able to sort tuples against the return |
+ value of parse_version. So again we'll add a warning enabled shim to |
+ make this possible. |
+ """ |
+ self.assertTrue(parse_version("1.0") < tuple(parse_version("2.0"))) |
+ self.assertTrue(parse_version("1.0") <= tuple(parse_version("2.0"))) |
+ self.assertTrue(parse_version("1.0") == tuple(parse_version("1.0"))) |
+ self.assertTrue(parse_version("3.0") > tuple(parse_version("2.0"))) |
+ self.assertTrue(parse_version("3.0") >= tuple(parse_version("2.0"))) |
+ self.assertTrue(parse_version("3.0") != tuple(parse_version("2.0"))) |
+ self.assertFalse(parse_version("3.0") != tuple(parse_version("3.0"))) |
+ |
+ def testVersionHashable(self): |
+ """ |
+ Ensure that our versions stay hashable even though we've subclassed |
+ them and added some shim code to them. |
+ """ |
+ self.assertEqual( |
+ hash(parse_version("1.0")), |
+ hash(parse_version("1.0")), |
+ ) |
+ |
+ |
+class ScriptHeaderTests(TestCase): |
+ non_ascii_exe = '/Users/José/bin/python' |
+ exe_with_spaces = r'C:\Program Files\Python33\python.exe' |
+ |
+ def test_get_script_header(self): |
+ if not sys.platform.startswith('java') or not is_sh(sys.executable): |
+ # This test is for non-Jython platforms |
+ expected = '#!%s\n' % nt_quote_arg(os.path.normpath(sys.executable)) |
+ self.assertEqual(get_script_header('#!/usr/local/bin/python'), |
+ expected) |
+ expected = '#!%s -x\n' % nt_quote_arg(os.path.normpath(sys.executable)) |
+ self.assertEqual(get_script_header('#!/usr/bin/python -x'), |
+ expected) |
+ self.assertEqual(get_script_header('#!/usr/bin/python', |
+ executable=self.non_ascii_exe), |
+ '#!%s -x\n' % self.non_ascii_exe) |
+ candidate = get_script_header('#!/usr/bin/python', |
+ executable=self.exe_with_spaces) |
+ self.assertEqual(candidate, '#!"%s"\n' % self.exe_with_spaces) |
+ |
+ def test_get_script_header_jython_workaround(self): |
+ # This test doesn't work with Python 3 in some locales |
+ if PY3 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, stderr = sys.stdout, sys.stderr |
+ try: |
+ # A mock sys.executable that uses a shebang line (this file) |
+ exe = os.path.normpath(os.path.splitext(__file__)[0] + '.py') |
+ self.assertEqual( |
+ get_script_header('#!/usr/local/bin/python', executable=exe), |
+ '#!/usr/bin/env %s\n' % exe) |
+ |
+ # Ensure we generate what is basically a broken shebang line |
+ # when there's options, with a warning emitted |
+ sys.stdout = sys.stderr = StringIO() |
+ self.assertEqual(get_script_header('#!/usr/bin/python -x', |
+ executable=exe), |
+ '#!%s -x\n' % exe) |
+ self.assertTrue('Unable to adapt shebang line' in sys.stdout.getvalue()) |
+ sys.stdout = sys.stderr = StringIO() |
+ self.assertEqual(get_script_header('#!/usr/bin/python', |
+ executable=self.non_ascii_exe), |
+ '#!%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, sys.stderr = stdout, stderr |
+ |
+ |
+class NamespaceTests(TestCase): |
+ |
+ def setUp(self): |
+ self._ns_pkgs = pkg_resources._namespace_packages.copy() |
+ self._tmpdir = tempfile.mkdtemp(prefix="tests-setuptools-") |
+ os.makedirs(os.path.join(self._tmpdir, "site-pkgs")) |
+ self._prev_sys_path = sys.path[:] |
+ sys.path.append(os.path.join(self._tmpdir, "site-pkgs")) |
+ |
+ def tearDown(self): |
+ shutil.rmtree(self._tmpdir) |
+ pkg_resources._namespace_packages = self._ns_pkgs.copy() |
+ sys.path = self._prev_sys_path[:] |
+ |
+ msg = "Test fails when /tmp is a symlink. See #231" |
+ @skipIf(os.path.islink(tempfile.gettempdir()), msg) |
+ def test_two_levels_deep(self): |
+ """ |
+ Test nested namespace packages |
+ Create namespace packages in the following tree : |
+ site-packages-1/pkg1/pkg2 |
+ site-packages-2/pkg1/pkg2 |
+ Check both are in the _namespace_packages dict and that their __path__ |
+ is correct |
+ """ |
+ sys.path.append(os.path.join(self._tmpdir, "site-pkgs2")) |
+ os.makedirs(os.path.join(self._tmpdir, "site-pkgs", "pkg1", "pkg2")) |
+ os.makedirs(os.path.join(self._tmpdir, "site-pkgs2", "pkg1", "pkg2")) |
+ ns_str = "__import__('pkg_resources').declare_namespace(__name__)\n" |
+ for site in ["site-pkgs", "site-pkgs2"]: |
+ pkg1_init = open(os.path.join(self._tmpdir, site, |
+ "pkg1", "__init__.py"), "w") |
+ pkg1_init.write(ns_str) |
+ pkg1_init.close() |
+ pkg2_init = open(os.path.join(self._tmpdir, site, |
+ "pkg1", "pkg2", "__init__.py"), "w") |
+ pkg2_init.write(ns_str) |
+ pkg2_init.close() |
+ import pkg1 |
+ assert "pkg1" in pkg_resources._namespace_packages |
+ try: |
+ import pkg1.pkg2 |
+ except ImportError: |
+ self.fail("Setuptools tried to import the parent namespace package") |
+ # check the _namespace_packages dict |
+ assert "pkg1.pkg2" in pkg_resources._namespace_packages |
+ assert pkg_resources._namespace_packages["pkg1"] == ["pkg1.pkg2"] |
+ # check the __path__ attribute contains both paths |
+ expected = [ |
+ os.path.join(self._tmpdir, "site-pkgs", "pkg1", "pkg2"), |
+ os.path.join(self._tmpdir, "site-pkgs2", "pkg1", "pkg2"), |
+ ] |
+ assert pkg1.pkg2.__path__ == expected |