GeezerVison is showing github.com — `test_concurrent_lazy_import_reification` is flaky · Issue #154561 · python/cpython
test_concurrent_lazy_import_reification is flaky #154561
Labels interpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)topic-free-threadingtopic-lazy-importstype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error DescriptionBug report
Bug description:
See for example, this run:
======================================================================
FAIL: test_concurrent_lazy_import_reification (test.test_lazy_import.ThreadSafetyTests.test_concurrent_lazy_import_reification)
Multiple threads racing to reify the same lazy import should succeed.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/var/lib/buildbot/workers/rise-riscv64-3/3.x.rise-riscv64-3.nogil/build/Lib/test/test_lazy_import/__init__.py", line 1820, in test_concurrent_lazy_import_reification
self.assertEqual(errors, [], f"Errors occurred: {errors}")
~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: Lists differ: [(9, AttributeError("module 'test.test_laz[39 chars]'"))] != []
First list contains 1 additional elements.
First extra element 0:
(9, AttributeError("module 'test.test_lazy_import.data' has no attribute 'basic2'"))
+ []
- [(9,
- AttributeError("module 'test.test_lazy_import.data' has no attribute 'basic2'"))] : Errors occurred: [(9, AttributeError("module 'test.test_lazy_import.data' has no attribute 'basic2'"))]
----------------------------------------------------------------------
Ran 128 tests in 78.334s
FAILED (failures=1)
test test_lazy_import failed
CPython versions tested on:
CPython main branch
Operating systems tested on:
No response
Linked PRs
Activityjohnslavik commented on Jul 23, 2026 johnslavik commented on Jul 23, 2026 Oh, I thought this was new but it's an old one. I'll try to work on this. I reproduced it locally. BHUVANSH855 commented on Jul 24, 2026 Hi! I've been investigating the intermittent failure in test_concurrent_lazy_import_reification and have been able to reproduce it locally.
So far I've instrumented both the C and Python sides of the lazy import path. Here's what I've observed:
setattr(parent_module, child, module) succeeds, and an immediate assert getattr(parent_module, child) is module always passes.
_find_and_load_lazy_submodule() is just a wrapper around _find_and_load(..., lazy_submodule=True).
_find_and_load_unlocked() publishes the child module on the parent and doesn't appear to remove it afterwards.
- During a failing run, I see the following sequence:
- the attribute is initially missing (
has_key=0, contains=1),
- it is successfully published,
- the pending entry is discarded,
- later another thread still gets
AttributeError, and by then the pending-set entry is already gone (contains=0).
At this point I'm not seeing any Python-level code that removes the published attribute after setattr(), so I'm wondering if I'm looking in the wrong place.
Would you recommend continuing to investigate the free-threaded module attribute implementation / synchronization, or is there another part of the lazy import implementation that would be a better place to look? brittanyrey commented on Sep 18, 2026 This no longer repros.
It looks like it was fixed when the fix for #155194 went in.
cc: @johnslavik to close johnslavik commented on Sep 18, 2026 I've stress-tested the test under a higher number of threads and confirm this no longer reproduces. Thank you @brittanyrey! Reacted by Brittany Reynoso
MetadataMetadatainterpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)topic-free-threadingtopic-lazy-importstype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error DevelopmentNo branches or pull requestsIssue actions
|