Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(81)

Side by Side Diff: recipe_engine/third_party/setuptools/tests/test_resources.py

Issue 1344583003: Recipe package system. (Closed) Base URL: git@github.com:luci/recipes-py.git@master
Patch Set: Recompiled proto Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 #!/usr/bin/python
2 # -*- coding: utf-8 -*-
3 # NOTE: the shebang and encoding lines are for ScriptHeaderTests do not remove
4
5 import os
6 import sys
7 import tempfile
8 import shutil
9 from unittest import TestCase
10
11 import setuptools._vendor.packaging.version
12 import setuptools._vendor.packaging.specifiers
13 packaging = setuptools._vendor.packaging
14
15 import pkg_resources
16 from pkg_resources import (parse_requirements, VersionConflict, parse_version,
17 Distribution, EntryPoint, Requirement, safe_version, safe_name,
18 WorkingSet)
19
20 from setuptools.command.easy_install import (get_script_header, is_sh,
21 nt_quote_arg)
22 from setuptools.compat import StringIO, iteritems, PY3
23 from .py26compat import skipIf
24
25 def safe_repr(obj, short=False):
26 """ copied from Python2.7"""
27 try:
28 result = repr(obj)
29 except Exception:
30 result = object.__repr__(obj)
31 if not short or len(result) < pkg_resources._MAX_LENGTH:
32 return result
33 return result[:pkg_resources._MAX_LENGTH] + ' [truncated]...'
34
35 class Metadata(pkg_resources.EmptyProvider):
36 """Mock object to return metadata as if from an on-disk distribution"""
37
38 def __init__(self,*pairs):
39 self.metadata = dict(pairs)
40
41 def has_metadata(self,name):
42 return name in self.metadata
43
44 def get_metadata(self,name):
45 return self.metadata[name]
46
47 def get_metadata_lines(self,name):
48 return pkg_resources.yield_lines(self.get_metadata(name))
49
50 dist_from_fn = pkg_resources.Distribution.from_filename
51
52 class DistroTests(TestCase):
53
54 def testCollection(self):
55 # empty path should produce no distributions
56 ad = pkg_resources.Environment([], platform=None, python=None)
57 self.assertEqual(list(ad), [])
58 self.assertEqual(ad['FooPkg'],[])
59 ad.add(dist_from_fn("FooPkg-1.3_1.egg"))
60 ad.add(dist_from_fn("FooPkg-1.4-py2.4-win32.egg"))
61 ad.add(dist_from_fn("FooPkg-1.2-py2.4.egg"))
62
63 # Name is in there now
64 self.assertTrue(ad['FooPkg'])
65 # But only 1 package
66 self.assertEqual(list(ad), ['foopkg'])
67
68 # Distributions sort by version
69 self.assertEqual(
70 [dist.version for dist in ad['FooPkg']], ['1.4','1.3-1','1.2']
71 )
72 # Removing a distribution leaves sequence alone
73 ad.remove(ad['FooPkg'][1])
74 self.assertEqual(
75 [dist.version for dist in ad['FooPkg']], ['1.4','1.2']
76 )
77 # And inserting adds them in order
78 ad.add(dist_from_fn("FooPkg-1.9.egg"))
79 self.assertEqual(
80 [dist.version for dist in ad['FooPkg']], ['1.9','1.4','1.2']
81 )
82
83 ws = WorkingSet([])
84 foo12 = dist_from_fn("FooPkg-1.2-py2.4.egg")
85 foo14 = dist_from_fn("FooPkg-1.4-py2.4-win32.egg")
86 req, = parse_requirements("FooPkg>=1.3")
87
88 # Nominal case: no distros on path, should yield all applicable
89 self.assertEqual(ad.best_match(req,ws).version, '1.9')
90 # If a matching distro is already installed, should return only that
91 ws.add(foo14)
92 self.assertEqual(ad.best_match(req,ws).version, '1.4')
93
94 # If the first matching distro is unsuitable, it's a version conflict
95 ws = WorkingSet([])
96 ws.add(foo12)
97 ws.add(foo14)
98 self.assertRaises(VersionConflict, ad.best_match, req, ws)
99
100 # If more than one match on the path, the first one takes precedence
101 ws = WorkingSet([])
102 ws.add(foo14)
103 ws.add(foo12)
104 ws.add(foo14)
105 self.assertEqual(ad.best_match(req,ws).version, '1.4')
106
107 def checkFooPkg(self,d):
108 self.assertEqual(d.project_name, "FooPkg")
109 self.assertEqual(d.key, "foopkg")
110 self.assertEqual(d.version, "1.3.post1")
111 self.assertEqual(d.py_version, "2.4")
112 self.assertEqual(d.platform, "win32")
113 self.assertEqual(d.parsed_version, parse_version("1.3-1"))
114
115 def testDistroBasics(self):
116 d = Distribution(
117 "/some/path",
118 project_name="FooPkg",version="1.3-1",py_version="2.4",platform="win 32"
119 )
120 self.checkFooPkg(d)
121
122 d = Distribution("/some/path")
123 self.assertEqual(d.py_version, sys.version[:3])
124 self.assertEqual(d.platform, None)
125
126 def testDistroParse(self):
127 d = dist_from_fn("FooPkg-1.3.post1-py2.4-win32.egg")
128 self.checkFooPkg(d)
129 d = dist_from_fn("FooPkg-1.3.post1-py2.4-win32.egg-info")
130 self.checkFooPkg(d)
131
132 def testDistroMetadata(self):
133 d = Distribution(
134 "/some/path", project_name="FooPkg", py_version="2.4", platform="win 32",
135 metadata = Metadata(
136 ('PKG-INFO',"Metadata-Version: 1.0\nVersion: 1.3-1\n")
137 )
138 )
139 self.checkFooPkg(d)
140
141 def distRequires(self, txt):
142 return Distribution("/foo", metadata=Metadata(('depends.txt', txt)))
143
144 def checkRequires(self, dist, txt, extras=()):
145 self.assertEqual(
146 list(dist.requires(extras)),
147 list(parse_requirements(txt))
148 )
149
150 def testDistroDependsSimple(self):
151 for v in "Twisted>=1.5", "Twisted>=1.5\nZConfig>=2.0":
152 self.checkRequires(self.distRequires(v), v)
153
154 def testResolve(self):
155 ad = pkg_resources.Environment([])
156 ws = WorkingSet([])
157 # Resolving no requirements -> nothing to install
158 self.assertEqual(list(ws.resolve([],ad)), [])
159 # Request something not in the collection -> DistributionNotFound
160 self.assertRaises(
161 pkg_resources.DistributionNotFound, ws.resolve, parse_requirements(" Foo"), ad
162 )
163 Foo = Distribution.from_filename(
164 "/foo_dir/Foo-1.2.egg",
165 metadata=Metadata(('depends.txt', "[bar]\nBaz>=2.0"))
166 )
167 ad.add(Foo)
168 ad.add(Distribution.from_filename("Foo-0.9.egg"))
169
170 # Request thing(s) that are available -> list to activate
171 for i in range(3):
172 targets = list(ws.resolve(parse_requirements("Foo"), ad))
173 self.assertEqual(targets, [Foo])
174 list(map(ws.add,targets))
175 self.assertRaises(VersionConflict, ws.resolve,
176 parse_requirements("Foo==0.9"), ad)
177 ws = WorkingSet([]) # reset
178
179 # Request an extra that causes an unresolved dependency for "Baz"
180 self.assertRaises(
181 pkg_resources.DistributionNotFound, ws.resolve,parse_requirements("F oo[bar]"), ad
182 )
183 Baz = Distribution.from_filename(
184 "/foo_dir/Baz-2.1.egg", metadata=Metadata(('depends.txt', "Foo"))
185 )
186 ad.add(Baz)
187
188 # Activation list now includes resolved dependency
189 self.assertEqual(
190 list(ws.resolve(parse_requirements("Foo[bar]"), ad)), [Foo,Baz]
191 )
192 # Requests for conflicting versions produce VersionConflict
193 self.assertRaises(VersionConflict,
194 ws.resolve, parse_requirements("Foo==1.2\nFoo!=1.2"), ad)
195
196 def testDistroDependsOptions(self):
197 d = self.distRequires("""
198 Twisted>=1.5
199 [docgen]
200 ZConfig>=2.0
201 docutils>=0.3
202 [fastcgi]
203 fcgiapp>=0.1""")
204 self.checkRequires(d,"Twisted>=1.5")
205 self.checkRequires(
206 d,"Twisted>=1.5 ZConfig>=2.0 docutils>=0.3".split(), ["docgen"]
207 )
208 self.checkRequires(
209 d,"Twisted>=1.5 fcgiapp>=0.1".split(), ["fastcgi"]
210 )
211 self.checkRequires(
212 d,"Twisted>=1.5 ZConfig>=2.0 docutils>=0.3 fcgiapp>=0.1".split(),
213 ["docgen","fastcgi"]
214 )
215 self.checkRequires(
216 d,"Twisted>=1.5 fcgiapp>=0.1 ZConfig>=2.0 docutils>=0.3".split(),
217 ["fastcgi", "docgen"]
218 )
219 self.assertRaises(pkg_resources.UnknownExtra, d.requires, ["foo"])
220
221
222 class EntryPointTests(TestCase):
223
224 def assertfields(self, ep):
225 self.assertEqual(ep.name,"foo")
226 self.assertEqual(ep.module_name,"setuptools.tests.test_resources")
227 self.assertEqual(ep.attrs, ("EntryPointTests",))
228 self.assertEqual(ep.extras, ("x",))
229 self.assertTrue(ep.load() is EntryPointTests)
230 self.assertEqual(
231 str(ep),
232 "foo = setuptools.tests.test_resources:EntryPointTests [x]"
233 )
234
235 def setUp(self):
236 self.dist = Distribution.from_filename(
237 "FooPkg-1.2-py2.4.egg", metadata=Metadata(('requires.txt','[x]')))
238
239 def testBasics(self):
240 ep = EntryPoint(
241 "foo", "setuptools.tests.test_resources", ["EntryPointTests"],
242 ["x"], self.dist
243 )
244 self.assertfields(ep)
245
246 def testParse(self):
247 s = "foo = setuptools.tests.test_resources:EntryPointTests [x]"
248 ep = EntryPoint.parse(s, self.dist)
249 self.assertfields(ep)
250
251 ep = EntryPoint.parse("bar baz= spammity[PING]")
252 self.assertEqual(ep.name,"bar baz")
253 self.assertEqual(ep.module_name,"spammity")
254 self.assertEqual(ep.attrs, ())
255 self.assertEqual(ep.extras, ("ping",))
256
257 ep = EntryPoint.parse(" fizzly = wocka:foo")
258 self.assertEqual(ep.name,"fizzly")
259 self.assertEqual(ep.module_name,"wocka")
260 self.assertEqual(ep.attrs, ("foo",))
261 self.assertEqual(ep.extras, ())
262
263 def testRejects(self):
264 for ep in [
265 "foo", "x=1=2", "x=a:b:c", "q=x/na", "fez=pish:tush-z", "x=f[a]>2",
266 ]:
267 try: EntryPoint.parse(ep)
268 except ValueError: pass
269 else: raise AssertionError("Should've been bad", ep)
270
271 def checkSubMap(self, m):
272 self.assertEqual(len(m), len(self.submap_expect))
273 for key, ep in iteritems(self.submap_expect):
274 self.assertEqual(repr(m.get(key)), repr(ep))
275
276 submap_expect = dict(
277 feature1=EntryPoint('feature1', 'somemodule', ['somefunction']),
278 feature2=EntryPoint('feature2', 'another.module', ['SomeClass'], ['extra 1','extra2']),
279 feature3=EntryPoint('feature3', 'this.module', extras=['something'])
280 )
281 submap_str = """
282 # define features for blah blah
283 feature1 = somemodule:somefunction
284 feature2 = another.module:SomeClass [extra1,extra2]
285 feature3 = this.module [something]
286 """
287
288 def testParseList(self):
289 self.checkSubMap(EntryPoint.parse_group("xyz", self.submap_str))
290 self.assertRaises(ValueError, EntryPoint.parse_group, "x a", "foo=bar")
291 self.assertRaises(ValueError, EntryPoint.parse_group, "x",
292 ["foo=baz", "foo=bar"])
293
294 def testParseMap(self):
295 m = EntryPoint.parse_map({'xyz':self.submap_str})
296 self.checkSubMap(m['xyz'])
297 self.assertEqual(list(m.keys()),['xyz'])
298 m = EntryPoint.parse_map("[xyz]\n"+self.submap_str)
299 self.checkSubMap(m['xyz'])
300 self.assertEqual(list(m.keys()),['xyz'])
301 self.assertRaises(ValueError, EntryPoint.parse_map, ["[xyz]", "[xyz]"])
302 self.assertRaises(ValueError, EntryPoint.parse_map, self.submap_str)
303
304 class RequirementsTests(TestCase):
305
306 def testBasics(self):
307 r = Requirement.parse("Twisted>=1.2")
308 self.assertEqual(str(r),"Twisted>=1.2")
309 self.assertEqual(repr(r),"Requirement.parse('Twisted>=1.2')")
310 self.assertEqual(r, Requirement("Twisted", [('>=','1.2')], ()))
311 self.assertEqual(r, Requirement("twisTed", [('>=','1.2')], ()))
312 self.assertNotEqual(r, Requirement("Twisted", [('>=','2.0')], ()))
313 self.assertNotEqual(r, Requirement("Zope", [('>=','1.2')], ()))
314 self.assertNotEqual(r, Requirement("Zope", [('>=','3.0')], ()))
315 self.assertNotEqual(r, Requirement.parse("Twisted[extras]>=1.2"))
316
317 def testOrdering(self):
318 r1 = Requirement("Twisted", [('==','1.2c1'),('>=','1.2')], ())
319 r2 = Requirement("Twisted", [('>=','1.2'),('==','1.2c1')], ())
320 self.assertEqual(r1,r2)
321 self.assertEqual(str(r1),str(r2))
322 self.assertEqual(str(r2),"Twisted==1.2c1,>=1.2")
323
324 def testBasicContains(self):
325 r = Requirement("Twisted", [('>=','1.2')], ())
326 foo_dist = Distribution.from_filename("FooPkg-1.3_1.egg")
327 twist11 = Distribution.from_filename("Twisted-1.1.egg")
328 twist12 = Distribution.from_filename("Twisted-1.2.egg")
329 self.assertTrue(parse_version('1.2') in r)
330 self.assertTrue(parse_version('1.1') not in r)
331 self.assertTrue('1.2' in r)
332 self.assertTrue('1.1' not in r)
333 self.assertTrue(foo_dist not in r)
334 self.assertTrue(twist11 not in r)
335 self.assertTrue(twist12 in r)
336
337 def testOptionsAndHashing(self):
338 r1 = Requirement.parse("Twisted[foo,bar]>=1.2")
339 r2 = Requirement.parse("Twisted[bar,FOO]>=1.2")
340 self.assertEqual(r1,r2)
341 self.assertEqual(r1.extras, ("foo","bar"))
342 self.assertEqual(r2.extras, ("bar","foo")) # extras are normalized
343 self.assertEqual(hash(r1), hash(r2))
344 self.assertEqual(
345 hash(r1), hash(("twisted", packaging.specifiers.SpecifierSet(">=1.2" ),
346 frozenset(["foo","bar"])))
347 )
348
349 def testVersionEquality(self):
350 r1 = Requirement.parse("foo==0.3a2")
351 r2 = Requirement.parse("foo!=0.3a4")
352 d = Distribution.from_filename
353
354 self.assertTrue(d("foo-0.3a4.egg") not in r1)
355 self.assertTrue(d("foo-0.3a1.egg") not in r1)
356 self.assertTrue(d("foo-0.3a4.egg") not in r2)
357
358 self.assertTrue(d("foo-0.3a2.egg") in r1)
359 self.assertTrue(d("foo-0.3a2.egg") in r2)
360 self.assertTrue(d("foo-0.3a3.egg") in r2)
361 self.assertTrue(d("foo-0.3a5.egg") in r2)
362
363 def testSetuptoolsProjectName(self):
364 """
365 The setuptools project should implement the setuptools package.
366 """
367
368 self.assertEqual(
369 Requirement.parse('setuptools').project_name, 'setuptools')
370 # setuptools 0.7 and higher means setuptools.
371 self.assertEqual(
372 Requirement.parse('setuptools == 0.7').project_name, 'setuptools')
373 self.assertEqual(
374 Requirement.parse('setuptools == 0.7a1').project_name, 'setuptools')
375 self.assertEqual(
376 Requirement.parse('setuptools >= 0.7').project_name, 'setuptools')
377
378
379 class ParseTests(TestCase):
380
381 def testEmptyParse(self):
382 self.assertEqual(list(parse_requirements('')), [])
383
384 def testYielding(self):
385 for inp,out in [
386 ([], []), ('x',['x']), ([[]],[]), (' x\n y', ['x','y']),
387 (['x\n\n','y'], ['x','y']),
388 ]:
389 self.assertEqual(list(pkg_resources.yield_lines(inp)),out)
390
391 def testSplitting(self):
392 sample = """
393 x
394 [Y]
395 z
396
397 a
398 [b ]
399 # foo
400 c
401 [ d]
402 [q]
403 v
404 """
405 self.assertEqual(list(pkg_resources.split_sections(sample)),
406 [(None,["x"]), ("Y",["z","a"]), ("b",["c"]), ("d",[]), ("q",["v"])]
407 )
408 self.assertRaises(ValueError,list,pkg_resources.split_sections("[foo"))
409
410 def testSafeName(self):
411 self.assertEqual(safe_name("adns-python"), "adns-python")
412 self.assertEqual(safe_name("WSGI Utils"), "WSGI-Utils")
413 self.assertEqual(safe_name("WSGI Utils"), "WSGI-Utils")
414 self.assertEqual(safe_name("Money$$$Maker"), "Money-Maker")
415 self.assertNotEqual(safe_name("peak.web"), "peak-web")
416
417 def testSafeVersion(self):
418 self.assertEqual(safe_version("1.2-1"), "1.2.post1")
419 self.assertEqual(safe_version("1.2 alpha"), "1.2.alpha")
420 self.assertEqual(safe_version("2.3.4 20050521"), "2.3.4.20050521")
421 self.assertEqual(safe_version("Money$$$Maker"), "Money-Maker")
422 self.assertEqual(safe_version("peak.web"), "peak.web")
423
424 def testSimpleRequirements(self):
425 self.assertEqual(
426 list(parse_requirements('Twis-Ted>=1.2-1')),
427 [Requirement('Twis-Ted',[('>=','1.2-1')], ())]
428 )
429 self.assertEqual(
430 list(parse_requirements('Twisted >=1.2, \ # more\n<2.0')),
431 [Requirement('Twisted',[('>=','1.2'),('<','2.0')], ())]
432 )
433 self.assertEqual(
434 Requirement.parse("FooBar==1.99a3"),
435 Requirement("FooBar", [('==','1.99a3')], ())
436 )
437 self.assertRaises(ValueError,Requirement.parse,">=2.3")
438 self.assertRaises(ValueError,Requirement.parse,"x\\")
439 self.assertRaises(ValueError,Requirement.parse,"x==2 q")
440 self.assertRaises(ValueError,Requirement.parse,"X==1\nY==2")
441 self.assertRaises(ValueError,Requirement.parse,"#")
442
443 def testVersionEquality(self):
444 def c(s1,s2):
445 p1, p2 = parse_version(s1),parse_version(s2)
446 self.assertEqual(p1,p2, (s1,s2,p1,p2))
447
448 c('1.2-rc1', '1.2rc1')
449 c('0.4', '0.4.0')
450 c('0.4.0.0', '0.4.0')
451 c('0.4.0-0', '0.4-0')
452 c('0post1', '0.0post1')
453 c('0pre1', '0.0c1')
454 c('0.0.0preview1', '0c1')
455 c('0.0c1', '0-rc1')
456 c('1.2a1', '1.2.a.1')
457 c('1.2.a', '1.2a')
458
459 def testVersionOrdering(self):
460 def c(s1,s2):
461 p1, p2 = parse_version(s1),parse_version(s2)
462 self.assertTrue(p1<p2, (s1,s2,p1,p2))
463
464 c('2.1','2.1.1')
465 c('2a1','2b0')
466 c('2a1','2.1')
467 c('2.3a1', '2.3')
468 c('2.1-1', '2.1-2')
469 c('2.1-1', '2.1.1')
470 c('2.1', '2.1post4')
471 c('2.1a0-20040501', '2.1')
472 c('1.1', '02.1')
473 c('3.2', '3.2.post0')
474 c('3.2post1', '3.2post2')
475 c('0.4', '4.0')
476 c('0.0.4', '0.4.0')
477 c('0post1', '0.4post1')
478 c('2.1.0-rc1','2.1.0')
479 c('2.1dev','2.1a0')
480
481 torture ="""
482 0.80.1-3 0.80.1-2 0.80.1-1 0.79.9999+0.80.0pre4-1
483 0.79.9999+0.80.0pre2-3 0.79.9999+0.80.0pre2-2
484 0.77.2-1 0.77.1-1 0.77.0-1
485 """.split()
486
487 for p,v1 in enumerate(torture):
488 for v2 in torture[p+1:]:
489 c(v2,v1)
490
491 def testVersionBuildout(self):
492 """
493 Buildout has a function in it's bootstrap.py that inspected the return
494 value of parse_version. The new parse_version returns a Version class
495 which needs to support this behavior, at least for now.
496 """
497 def buildout(parsed_version):
498 _final_parts = '*final-', '*final'
499
500 def _final_version(parsed_version):
501 for part in parsed_version:
502 if (part[:1] == '*') and (part not in _final_parts):
503 return False
504 return True
505 return _final_version(parsed_version)
506
507 self.assertTrue(buildout(parse_version("1.0")))
508 self.assertFalse(buildout(parse_version("1.0a1")))
509
510 def testVersionIndexable(self):
511 """
512 Some projects were doing things like parse_version("v")[0], so we'll
513 support indexing the same as we support iterating.
514 """
515 self.assertEqual(parse_version("1.0")[0], "00000001")
516
517 def testVersionTupleSort(self):
518 """
519 Some projects expected to be able to sort tuples against the return
520 value of parse_version. So again we'll add a warning enabled shim to
521 make this possible.
522 """
523 self.assertTrue(parse_version("1.0") < tuple(parse_version("2.0")))
524 self.assertTrue(parse_version("1.0") <= tuple(parse_version("2.0")))
525 self.assertTrue(parse_version("1.0") == tuple(parse_version("1.0")))
526 self.assertTrue(parse_version("3.0") > tuple(parse_version("2.0")))
527 self.assertTrue(parse_version("3.0") >= tuple(parse_version("2.0")))
528 self.assertTrue(parse_version("3.0") != tuple(parse_version("2.0")))
529 self.assertFalse(parse_version("3.0") != tuple(parse_version("3.0")))
530
531 def testVersionHashable(self):
532 """
533 Ensure that our versions stay hashable even though we've subclassed
534 them and added some shim code to them.
535 """
536 self.assertEqual(
537 hash(parse_version("1.0")),
538 hash(parse_version("1.0")),
539 )
540
541
542 class ScriptHeaderTests(TestCase):
543 non_ascii_exe = '/Users/José/bin/python'
544 exe_with_spaces = r'C:\Program Files\Python33\python.exe'
545
546 def test_get_script_header(self):
547 if not sys.platform.startswith('java') or not is_sh(sys.executable):
548 # This test is for non-Jython platforms
549 expected = '#!%s\n' % nt_quote_arg(os.path.normpath(sys.executable))
550 self.assertEqual(get_script_header('#!/usr/local/bin/python'),
551 expected)
552 expected = '#!%s -x\n' % nt_quote_arg(os.path.normpath(sys.executab le))
553 self.assertEqual(get_script_header('#!/usr/bin/python -x'),
554 expected)
555 self.assertEqual(get_script_header('#!/usr/bin/python',
556 executable=self.non_ascii_exe),
557 '#!%s -x\n' % self.non_ascii_exe)
558 candidate = get_script_header('#!/usr/bin/python',
559 executable=self.exe_with_spaces)
560 self.assertEqual(candidate, '#!"%s"\n' % self.exe_with_spaces)
561
562 def test_get_script_header_jython_workaround(self):
563 # This test doesn't work with Python 3 in some locales
564 if PY3 and os.environ.get("LC_CTYPE") in (None, "C", "POSIX"):
565 return
566
567 class java:
568 class lang:
569 class System:
570 @staticmethod
571 def getProperty(property):
572 return ""
573 sys.modules["java"] = java
574
575 platform = sys.platform
576 sys.platform = 'java1.5.0_13'
577 stdout, stderr = sys.stdout, sys.stderr
578 try:
579 # A mock sys.executable that uses a shebang line (this file)
580 exe = os.path.normpath(os.path.splitext(__file__)[0] + '.py')
581 self.assertEqual(
582 get_script_header('#!/usr/local/bin/python', executable=exe),
583 '#!/usr/bin/env %s\n' % exe)
584
585 # Ensure we generate what is basically a broken shebang line
586 # when there's options, with a warning emitted
587 sys.stdout = sys.stderr = StringIO()
588 self.assertEqual(get_script_header('#!/usr/bin/python -x',
589 executable=exe),
590 '#!%s -x\n' % exe)
591 self.assertTrue('Unable to adapt shebang line' in sys.stdout.getvalu e())
592 sys.stdout = sys.stderr = StringIO()
593 self.assertEqual(get_script_header('#!/usr/bin/python',
594 executable=self.non_ascii_exe),
595 '#!%s -x\n' % self.non_ascii_exe)
596 self.assertTrue('Unable to adapt shebang line' in sys.stdout.getvalu e())
597 finally:
598 del sys.modules["java"]
599 sys.platform = platform
600 sys.stdout, sys.stderr = stdout, stderr
601
602
603 class NamespaceTests(TestCase):
604
605 def setUp(self):
606 self._ns_pkgs = pkg_resources._namespace_packages.copy()
607 self._tmpdir = tempfile.mkdtemp(prefix="tests-setuptools-")
608 os.makedirs(os.path.join(self._tmpdir, "site-pkgs"))
609 self._prev_sys_path = sys.path[:]
610 sys.path.append(os.path.join(self._tmpdir, "site-pkgs"))
611
612 def tearDown(self):
613 shutil.rmtree(self._tmpdir)
614 pkg_resources._namespace_packages = self._ns_pkgs.copy()
615 sys.path = self._prev_sys_path[:]
616
617 msg = "Test fails when /tmp is a symlink. See #231"
618 @skipIf(os.path.islink(tempfile.gettempdir()), msg)
619 def test_two_levels_deep(self):
620 """
621 Test nested namespace packages
622 Create namespace packages in the following tree :
623 site-packages-1/pkg1/pkg2
624 site-packages-2/pkg1/pkg2
625 Check both are in the _namespace_packages dict and that their __path__
626 is correct
627 """
628 sys.path.append(os.path.join(self._tmpdir, "site-pkgs2"))
629 os.makedirs(os.path.join(self._tmpdir, "site-pkgs", "pkg1", "pkg2"))
630 os.makedirs(os.path.join(self._tmpdir, "site-pkgs2", "pkg1", "pkg2"))
631 ns_str = "__import__('pkg_resources').declare_namespace(__name__)\n"
632 for site in ["site-pkgs", "site-pkgs2"]:
633 pkg1_init = open(os.path.join(self._tmpdir, site,
634 "pkg1", "__init__.py"), "w")
635 pkg1_init.write(ns_str)
636 pkg1_init.close()
637 pkg2_init = open(os.path.join(self._tmpdir, site,
638 "pkg1", "pkg2", "__init__.py"), "w")
639 pkg2_init.write(ns_str)
640 pkg2_init.close()
641 import pkg1
642 assert "pkg1" in pkg_resources._namespace_packages
643 try:
644 import pkg1.pkg2
645 except ImportError:
646 self.fail("Setuptools tried to import the parent namespace package")
647 # check the _namespace_packages dict
648 assert "pkg1.pkg2" in pkg_resources._namespace_packages
649 assert pkg_resources._namespace_packages["pkg1"] == ["pkg1.pkg2"]
650 # check the __path__ attribute contains both paths
651 expected = [
652 os.path.join(self._tmpdir, "site-pkgs", "pkg1", "pkg2"),
653 os.path.join(self._tmpdir, "site-pkgs2", "pkg1", "pkg2"),
654 ]
655 assert pkg1.pkg2.__path__ == expected
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698