mirror of
https://github.com/python/cpython.git
synced 2025-08-04 00:48:58 +00:00
[3.11] gh-117178: Recover lazy loading of self-referential modules (GH-117179) (#117320)
Co-authored-by: Chris Markiewicz <effigies@gmail.com>
This commit is contained in:
parent
370a7f1e4a
commit
c703b7b54f
3 changed files with 25 additions and 6 deletions
|
@ -232,12 +232,11 @@ class _LazyModule(types.ModuleType):
|
|||
# Only the first thread to get the lock should trigger the load
|
||||
# and reset the module's class. The rest can now getattr().
|
||||
if object.__getattribute__(self, '__class__') is _LazyModule:
|
||||
# The first thread comes here multiple times as it descends the
|
||||
# call stack. The first time, it sets is_loading and triggers
|
||||
# exec_module(), which will access module.__dict__, module.__name__,
|
||||
# and/or module.__spec__, reentering this method. These accesses
|
||||
# need to be allowed to proceed without triggering the load again.
|
||||
if loader_state['is_loading'] and attr.startswith('__') and attr.endswith('__'):
|
||||
# Reentrant calls from the same thread must be allowed to proceed without
|
||||
# triggering the load again.
|
||||
# exec_module() and self-referential imports are the primary ways this can
|
||||
# happen, but in any case we must return something to avoid deadlock.
|
||||
if loader_state['is_loading']:
|
||||
return object.__getattribute__(self, attr)
|
||||
loader_state['is_loading'] = True
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue