-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Provide detailed error for circular from imports
#5972
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
youknowone
merged 5 commits into
RustPython:main
from
ever0de:fix/circular-import-error
Jul 14, 2025
Merged
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Helper function implementation is sound but relies on unset attribute.
The
is_module_initializingfunction has proper error handling, but it checks for__spec__._initializingwhich isn't being set by the import system. This function needs to either:PyModule.initializingfield if the module is aPyModuleinstance__spec__._initializingis properly set during importConsider checking the internal field directly:
fn is_module_initializing(module: &PyObject, vm: &VirtualMachine) -> bool { + // First try to check the internal field if this is a PyModule + if let Ok(py_module) = module.downcast_ref::<PyModule>() { + use std::sync::atomic::Ordering; + return py_module.initializing.load(Ordering::Relaxed); + } + + // Fallback to checking __spec__._initializing let Ok(spec) = module.get_attr(&vm.ctx.new_str("__spec__"), vm) else { return false; }; if vm.is_none(&spec) { return false; } let Ok(initializing_attr) = spec.get_attr(&vm.ctx.new_str("_initializing"), vm) else { return false; }; initializing_attr.try_to_bool(vm).unwrap_or(false) }Run the following script to check how CPython handles module initialization tracking:
🌐 Web query:
💡 Result:
CPython tracks module initialization state for circular import detection by leveraging the
sys.modulescache. When a module is first imported, a module object is placed intosys.modulesimmediately—before its code is executed. This ensures that if the module is imported again (such as via a circular import), Python will return this already-existing (but possibly only partially initialized) module object, rather than starting a new import. This mechanism is essential for breaking import cycles and preventing infinite recursion during import[3][7].The
__spec__._initializingattribute (or similar such as__spec__._initialized) is an internal implementation detail and is not the primary mechanism for detection of circular imports in CPython. There have been discussions and experimental ideas about using such an attribute to mark a module’s initialization state for more fine-grained control or for advanced import hacks like async imports[6][8]. However, in normal CPython operation and as of current mainstream Python versions, this attribute is either not present or not used by the import machinery for circular import detection.Instead, here is how it works:
sys.modules, signaling "import in progress."sys.modulesbefore its code has finished running is the primary state signal.Summary Table
sys.modulesearly insert__spec__._initializingIn conclusion:
CPython does not use
__spec__._initializingto track module initialization state for the purpose of circular import detection; it relies on the presence of the module insys.modulesduring import.[3][7]Citations:
Streamline
is_module_initializingto use internal flag and drop__spec__._initializingfallback.__spec__._initializingfor import tracking—modules insys.modulessignal “in progress.”PyModulealready has aninitializingflag; use that and returnfalsefor all other objects.fn is_module_initializing(module: &PyObject, vm: &VirtualMachine) -> bool { - // Fallback to checking __spec__._initializing - let Ok(spec) = module.get_attr(&vm.ctx.new_str("__spec__"), vm) else { - return false; - }; - if vm.is_none(&spec) { - return false; - } - let Ok(initializing_attr) = spec.get_attr(&vm.ctx.new_str("_initializing"), vm) else { - return false; - }; - initializing_attr.try_to_bool(vm).unwrap_or(false) + // Use internal initializing flag on PyModule + if let Ok(py_module) = module.downcast_ref::<PyModule>() { + use std::sync::atomic::Ordering; + return py_module.initializing.load(Ordering::Relaxed); + } + false }🤖 Prompt for AI Agents