13
13
14
14
import apipkg
15
15
16
+
17
+ PY2 = sys .version_info [0 ] == 2
18
+ PY3 = sys .version_info [0 ] == 3
19
+
20
+
16
21
#
17
22
# test support for importing modules
18
23
#
@@ -270,12 +275,12 @@ def parsenamespace(spec):
270
275
return ns
271
276
272
277
273
- def test_initpkg_replaces_sysmodules (monkeypatch ):
278
+ def test_initpkg_updates_sysmodules (monkeypatch ):
274
279
mod = ModuleType ("hello" )
275
280
monkeypatch .setitem (sys .modules , "hello" , mod )
276
281
apipkg .initpkg ("hello" , {"x" : "os.path:abspath" })
277
282
newmod = sys .modules ["hello" ]
278
- assert newmod != mod
283
+ assert ( PY2 and newmod != mod ) or ( PY3 and newmod is mod )
279
284
assert newmod .x == os .path .abspath
280
285
281
286
@@ -286,15 +291,17 @@ def test_initpkg_transfers_attrs(monkeypatch):
286
291
mod .__loader__ = "loader"
287
292
mod .__package__ = "package"
288
293
mod .__doc__ = "this is the documentation"
294
+ mod .goodbye = "goodbye"
289
295
monkeypatch .setitem (sys .modules , "hello" , mod )
290
296
apipkg .initpkg ("hello" , {})
291
297
newmod = sys .modules ["hello" ]
292
- assert newmod != mod
298
+ assert ( PY2 and newmod != mod ) or ( PY3 and newmod is mod )
293
299
assert newmod .__file__ == os .path .abspath (mod .__file__ )
294
300
assert newmod .__version__ == mod .__version__
295
301
assert newmod .__loader__ == mod .__loader__
296
302
assert newmod .__package__ == mod .__package__
297
303
assert newmod .__doc__ == mod .__doc__
304
+ assert not hasattr (newmod , "goodbye" )
298
305
299
306
300
307
def test_initpkg_nodoc (monkeypatch ):
@@ -312,7 +319,7 @@ def test_initpkg_overwrite_doc(monkeypatch):
312
319
monkeypatch .setitem (sys .modules , "hello" , hello )
313
320
apipkg .initpkg ("hello" , {"__doc__" : "sys:__doc__" })
314
321
newhello = sys .modules ["hello" ]
315
- assert newhello != hello
322
+ assert ( PY2 and newhello != hello ) or ( PY3 and newhello is hello )
316
323
assert newhello .__doc__ == sys .__doc__
317
324
318
325
@@ -324,7 +331,7 @@ def test_initpkg_not_transfers_not_existing_attrs(monkeypatch):
324
331
monkeypatch .setitem (sys .modules , "hello" , mod )
325
332
apipkg .initpkg ("hello" , {})
326
333
newmod = sys .modules ["hello" ]
327
- assert newmod != mod
334
+ assert ( PY2 and newmod != mod ) or ( PY3 and newmod is mod )
328
335
assert newmod .__file__ == os .path .abspath (mod .__file__ )
329
336
assert not hasattr (newmod , "__path__" )
330
337
assert not hasattr (newmod , "__package__" ) or mod .__package__ is None
@@ -337,7 +344,7 @@ def test_initpkg_not_changing_jython_paths(monkeypatch):
337
344
monkeypatch .setitem (sys .modules , "hello" , mod )
338
345
apipkg .initpkg ("hello" , {})
339
346
newmod = sys .modules ["hello" ]
340
- assert newmod != mod
347
+ assert ( PY2 and newmod != mod ) or ( PY3 and newmod is mod )
341
348
assert newmod .__file__ .startswith ("__pyclasspath__" )
342
349
unchanged , changed = newmod .__path__
343
350
assert changed != "ichange"
@@ -565,6 +572,58 @@ def run(self):
565
572
assert thread .attr == 42
566
573
567
574
575
+ @pytest .mark .skipif ("threading" not in sys .modules , reason = "requires thread support" )
576
+ def test_import_race (tmpdir , monkeypatch ):
577
+ pkgdir = tmpdir .mkdir ("importrace" )
578
+ pkgdir .join ("__init__.py" ).write (
579
+ textwrap .dedent (
580
+ """
581
+ import time
582
+ time.sleep(0.1)
583
+ import apipkg
584
+ apipkg.initpkg(__name__, exportdefs={
585
+ 'attr': '.submod:attr',
586
+ },
587
+ )
588
+ """
589
+ )
590
+ )
591
+ pkgdir .join ("submod.py" ).write (
592
+ textwrap .dedent (
593
+ """
594
+ attr = 43
595
+ """
596
+ )
597
+ )
598
+ monkeypatch .syspath_prepend (tmpdir )
599
+
600
+ class TestThread (threading .Thread ):
601
+ def __init__ (self ):
602
+ super (TestThread , self ).__init__ ()
603
+ self .importrace = None
604
+
605
+ def run (self ):
606
+ import importrace
607
+
608
+ self .importrace = importrace
609
+
610
+ threads = [TestThread () for _ in range (8 )]
611
+ for thread in threads :
612
+ thread .start ()
613
+ for thread in threads :
614
+ thread .join ()
615
+ for thread in threads :
616
+ assert isinstance (thread .importrace , apipkg .ApiModule )
617
+ assert thread .importrace .attr == 43
618
+
619
+ import importrace
620
+ assert isinstance (importrace , apipkg .ApiModule )
621
+ assert importrace .attr == 43
622
+
623
+ for thread in threads :
624
+ assert thread .importrace is importrace
625
+
626
+
568
627
def test_bpython_getattr_override (tmpdir , monkeypatch ):
569
628
def patchgetattr (self , name ):
570
629
raise AttributeError (name )
0 commit comments