@@ -747,25 +747,6 @@ def test_concurrent_first_imports_of_sibling_packages(self):
747747 self .assertEqual (sys .modules ["sib_a.leaf" ].X , 1 )
748748 self .assertEqual (sys .modules ["sib_b.leaf" ].X , 1 )
749749
750- def test_concurrent_first_imports_no_partial_module (self ):
751- # Dependencies are a.leaf -> b -> a, again with no cycle. Thread 1
752- # finds b in sys.modules and waits for it, so if it kept a's lock
753- # during a/leaf.py it would get not _DeadlockError but "cannot
754- # import name 'X' from partially initialized module 'b'".
755- errors = self ._run_two_first_imports (
756- {
757- "part_a/__init__.py" : "import part_sync; part_sync.hold()\n " ,
758- "part_a/leaf.py" : "from part_b import X\n " ,
759- "part_b.py" : "import part_a\n X = 1\n " ,
760- },
761- "import part_a.leaf" ,
762- "import part_b" ,
763- sync_name = "part_sync" ,
764- t2_waits_for = "part_a" ,
765- )
766- self .assertEqual (errors , [])
767- self .assertEqual (sys .modules ["part_a.leaf" ].X , 1 )
768-
769750 def test_finished_package_import_not_blocked_by_submodule_body (self ):
770751 # Thread 2 starts waiting for pkg while pkg/__init__.py runs. It
771752 # needs only the finished pkg, so it must be released when that
@@ -794,8 +775,8 @@ def test_finished_package_import_not_blocked_by_submodule_body(self):
794775 self .assertEqual (errors , [])
795776
796777 def test_concurrent_first_imports_of_nested_packages (self ):
797- # The same one level down: thread 1 does `import g.sub.leaf`;
798- # g/sub/__init__.py needs module c; c needs g. Thread 2 imports c
778+ # Thread 1 does `import g.sub.leaf`; g/sub/__init__.py needs
779+ # module c; c needs g. Thread 2 imports c
799780 # while thread 1 is still inside g/__init__.py. No cycle. If
800781 # thread 1 still held g's lock while it ran g/sub/__init__.py,
801782 # thread 2 (holding c, waiting for g) would look deadlocked to it
@@ -957,67 +938,6 @@ def test_waiter_retries_after_failed_submodule_import(self):
957938 ])
958939 self .assertEqual (sys .modules [f"{ pkg } .mod" ].X , 1 )
959940
960- def test_waiters_recover_after_failed_package_init (self ):
961- # pkg/__init__.py imports pkg.a and pkg.b, but its first execution
962- # (thread 0) raises once two other threads -- importing pkg.a and
963- # pkg.b -- are already waiting for pkg. One of the waiters then
964- # re-runs pkg/__init__.py successfully; both waiters must succeed,
965- # and neither may end up importing the parent while holding its
966- # submodule's lock (the gh-83065 lock order) on that retry path.
967- self ._setup_package_tree ({
968- "flaky_pkg/__init__.py" : (
969- "import flaky_sync; flaky_sync.executed.append(__name__)\n "
970- "flaky_sync.gate()\n "
971- "import flaky_pkg.a\n "
972- "import flaky_pkg.b\n " ),
973- "flaky_pkg/a.py" : (
974- "import flaky_sync; flaky_sync.executed.append(__name__)\n "
975- "X = 1\n " ),
976- "flaky_pkg/b.py" : (
977- "import flaky_sync; flaky_sync.executed.append(__name__)\n "
978- "import flaky_pkg.a\n X = 1\n " ),
979- })
980- sync = types .ModuleType ("flaky_sync" )
981- sync .executed = []
982- sys .modules ["flaky_sync" ] = sync
983- self .addCleanup (sys .modules .pop , "flaky_sync" , None )
984- errors = []
985-
986- def run (stmt ):
987- try :
988- exec (stmt , {})
989- except Exception as e :
990- errors .append ((stmt , f"{ type (e ).__name__ } : { e } " ))
991-
992- waiters = [threading .Thread (target = run , daemon = True ,
993- args = (f"import flaky_pkg.{ m } " ,))
994- for m in ("a" , "b" )]
995- first = True
996-
997- def gate ():
998- nonlocal first
999- if not first :
1000- return
1001- first = False
1002- for t in waiters :
1003- t .start ()
1004- for t in waiters :
1005- self ._wait_until_blocked_on (t , "flaky_pkg" )
1006- raise RuntimeError ("first attempt fails" )
1007- sync .gate = gate
1008-
1009- t0 = threading .Thread (target = run , args = ("import flaky_pkg" ,),
1010- daemon = True )
1011- t0 .start ()
1012- self ._join_import_threads ([t0 , * waiters ])
1013- self .assertEqual (
1014- errors ,
1015- [("import flaky_pkg" , "RuntimeError: first attempt fails" )])
1016- self .assertEqual (sys .modules ["flaky_pkg.b" ].X , 1 )
1017- self .assertEqual (
1018- sync .executed ,
1019- ["flaky_pkg" , "flaky_pkg" , "flaky_pkg.a" , "flaky_pkg.b" ])
1020-
1021941
1022942def setUpModule ():
1023943 thread_info = threading_helper .threading_setup ()
0 commit comments