Multi phase module init by youknowone · Pull Request #6740 · RustPython/RustPython
🏁 Script executed:
# First, locate the file and understand the current implementation find . -name "pyexpat.rs" -type f
Repository: RustPython/RustPython
Length of output: 95
🏁 Script executed:
# Search for how other modules handle submodule registration in RustPython fd -e rs -type f | xargs grep -l "sys_modules\|sys\.modules" | head -20
Repository: RustPython/RustPython
Length of output: 235
🏁 Script executed:
# Look for any tests that use pyexpat.model or pyexpat.errors rg -n "pyexpat\.(model|errors)" --type rs
Repository: RustPython/RustPython
Length of output: 91
🏁 Script executed:
# Check for existing submodule patterns in the codebase rg -n "create_module" --type rs -A 5 | head -60
Repository: RustPython/RustPython
Length of output: 91
🏁 Script executed:
# Look at the _model and _errors module definitions fd -e rs -type f -path "*pyexpat*" | xargs ls -la
Repository: RustPython/RustPython
Length of output: 3391
🏁 Script executed:
# Read the pyexpat.rs file cat -n crates/stdlib/src/pyexpat.rs | head -100
Repository: RustPython/RustPython
Length of output: 4159
🏁 Script executed:
# Search for sys_modules usage patterns rg -n "sys_modules\|sys\.modules" | head -20
Repository: RustPython/RustPython
Length of output: 47
🏁 Script executed:
# Search for create_module calls to see submodule patterns rg -n "create_module" -A 3 | head -40
Repository: RustPython/RustPython
Length of output: 2163
🏁 Script executed:
# Look for pyexpat tests find . -name "*test*" -o -name "*tests*" | xargs grep -l "pyexpat" 2>/dev/null | head -5
Repository: RustPython/RustPython
Length of output: 143
🏁 Script executed:
# Search for how other stdlib modules register submodules rg -n "extend_module" -B 5 -A 5 | head -80
Repository: RustPython/RustPython
Length of output: 5217
🏁 Script executed:
# Check the pyexpat test file to see how submodules are used cat Lib/test/test_pyexpat.py | head -150
Repository: RustPython/RustPython
Length of output: 4977
🏁 Script executed:
# Search for model/errors attribute access in test files rg -n "pyexpat\.(model|errors)" Lib/
Repository: RustPython/RustPython
Length of output: 47
🏁 Script executed:
# Look at how create_module is implemented rg -n "fn create_module" -A 10
Repository: RustPython/RustPython
Length of output: 980
🏁 Script executed:
# Check other stdlib modules that have submodules for comparison find crates/stdlib/src -name "*.rs" -type f | head -20
Repository: RustPython/RustPython
Length of output: 699
🏁 Script executed:
# Look for other submodule patterns - search for modules that might have nested structure rg -n "module_exec.*PyResult" -A 15 crates/stdlib/src/ | head -100
Repository: RustPython/RustPython
Length of output: 6065
🏁 Script executed:
# Search for any import statements in tests that use qualified submodule syntax rg -n "import.*pyexpat\." Lib/
Repository: RustPython/RustPython
Length of output: 47
🏁 Script executed:
# Check if there are any tests that try to import pyexpat.model or pyexpat.errors rg -n "import pyexpat" Lib/test/ -A 5
Repository: RustPython/RustPython
Length of output: 344
🏁 Script executed:
# Look at the _model and _errors submodule definitions in pyexpat find crates/stdlib/src -name "*model*" -o -name "*errors*" | grep pyexpat
Repository: RustPython/RustPython
Length of output: 47
🏁 Script executed:
# Search for how other modules with submodules handle sys.modules registration rg -n "__name__.*=.*\|sys_modules.*set" crates/stdlib/src/ | head -30
Repository: RustPython/RustPython
Length of output: 47
🏁 Script executed:
# Look at the extend_module macro implementation more closely cat -n crates/vm/src/macros.rs | head -20
Repository: RustPython/RustPython
Length of output: 1051
🏁 Script executed:
# Look at how __module_set_attr is implemented rg -n "__module_set_attr" crates/vm/src/ -A 5 | head -40
Repository: RustPython/RustPython
Length of output: 1128
🏁 Script executed:
# Search for how modules get registered in sys.modules rg -n "sys_modules\|sys\.modules" crates/vm/src/builtins/module.rs -B 3 -A 3
Repository: RustPython/RustPython
Length of output: 47
🏁 Script executed:
# Check if there are any tests that specifically test pyexpat module attributes or imports cat Lib/test/test_pyexpat.py | grep -n "expat\.\|pyexpat\." | head -20
Repository: RustPython/RustPython
Length of output: 1229
🏁 Script executed:
# Look at the module.rs file to understand module creation and sys.modules registration cat -n crates/vm/src/builtins/module.rs | head -80
Repository: RustPython/RustPython
Length of output: 3343
🏁 Script executed:
# Search for how PyModule::from_def works and if it sets __name__ automatically rg -n "from_def\|PyModule::new" crates/vm/src/builtins/module.rs -A 10 | head -60
Repository: RustPython/RustPython
Length of output: 47
🏁 Script executed:
# Look at how PyModule::from_def works and what __name__ is set to rg -n "from_def\|__init_dict_from_def" crates/vm/src/builtins/module.rs -A 20 | head -80
Repository: RustPython/RustPython
Length of output: 47
🏁 Script executed:
# Check how the pymodule macro initializes module __name__ rg -n "#\[pymodule" crates/stdlib/src/pyexpat.rs -B 2 -A 10
Repository: RustPython/RustPython
Length of output: 638
🏁 Script executed:
# Look for how __name__ is set on modules during creation rg -n "__name__\|\"__name__\"" crates/vm/src/builtins/module.rs -B 2 -A 2 | head -40
Repository: RustPython/RustPython
Length of output: 47
🏁 Script executed:
# Test if qualified imports actually work by looking at import system rg -n "import_submodule\|find_submodule" crates/vm/src/ | head -20
Repository: RustPython/RustPython
Length of output: 47
🏁 Script executed:
# Check how CPython's pyexpat.errors and pyexpat.model are used rg -n "expat\.errors\|expat\.model" Lib/test/test_pyexpat.py
Repository: RustPython/RustPython
Length of output: 47
🏁 Script executed:
# Look at how RustPython imports work, especially for submodules find crates/vm/src -name "*import*" -type f
Repository: RustPython/RustPython
Length of output: 88
🏁 Script executed:
# Check the import implementation rg -n "def import_module\|import_from\|__import__" crates/vm/src/ | head -30
Repository: RustPython/RustPython
Length of output: 47
🏁 Script executed:
# Look for how the import machinery handles parent.child imports rg -n "parent.*module\|submodule" crates/vm/src/stdlib/ | head -20
Repository: RustPython/RustPython
Length of output: 47
🏁 Script executed:
# Check if there are any tests that test qualified submodule imports find Lib/test -name "*.py" -exec grep -l "import.*\\..*" {} \; 2>/dev/null | head -5
Repository: RustPython/RustPython
Length of output: 195
🏁 Script executed:
# Search the codebase for examples of modules with submodules that ARE registered in sys.modules rg -n "set_item.*sys" crates/stdlib/src/ | head -20
Repository: RustPython/RustPython
Length of output: 47
🏁 Script executed:
# Look at how json module handles its submodules (as json has encoder/decoder) grep -rn "json" crates/stdlib/src/ | grep module_exec | head -5
Repository: RustPython/RustPython
Length of output: 47
🏁 Script executed:
# Look at the import system implementation cat -n crates/vm/src/import.rs | head -200
Repository: RustPython/RustPython
Length of output: 8431
🏁 Script executed:
# Check if there are any package/namespace tests rg -n "import.*\\..*as\|from.*\\..*import" Lib/test/ | grep -v "Binary\|\.pyc" | head -20
Repository: RustPython/RustPython
Length of output: 47
🏁 Script executed:
# Look specifically for how the pymodule macro generates __name__ rg -n "pymodule\|__name__" crates/vm/src/py_serde.rs | head -40
Repository: RustPython/RustPython
Length of output: 47
🏁 Script executed:
# Check the implementation of module initialization in the macro find crates -name "*.rs" -exec grep -l "pymodule" {} \; | head -5
Repository: RustPython/RustPython
Length of output: 3529
🏁 Script executed:
# Look at a stdlib module that imports submodules to see pattern rg -n "module_exec\|__module_exec" crates/stdlib/src/json/ -A 10 | head -60
Repository: RustPython/RustPython
Length of output: 47
🏁 Script executed:
# Check the pymodule macro implementation to understand how __name__ is set cat -n crates/derive-impl/src/pymodule.rs | head -150
Repository: RustPython/RustPython
Length of output: 6221
🏁 Script executed:
# Look for any tests that import qualified submodules rg -n "from pyexpat import\|import pyexpat\." Lib/test/
Repository: RustPython/RustPython
Length of output: 47
🏁 Script executed:
# Check Python standard library behavior for pyexpat submodules python3 -c "import pyexpat; print('model' in dir(pyexpat)); import pyexpat.errors; print(pyexpat.errors.__name__)" 2>&1 || true
Repository: RustPython/RustPython
Length of output: 151
🏁 Script executed:
# Check if there's documentation or tests about how RustPython handles submodule imports rg -n "submodule\|parent.*module" Lib/test/ | head -20
Repository: RustPython/RustPython
Length of output: 47
🏁 Script executed:
# Look at what __name__ is set to for the submodules created via create_module rg -n "PyModule.*__name__\|set.*__name__" crates/vm/src/builtins/module.rs -B 2 -A 2
Repository: RustPython/RustPython
Length of output: 47
🏁 Script executed:
# Let me check if there are any tests specifically for pyexpat.model or pyexpat.errors cat Lib/test/test_pyexpat.py | grep -n "\.model\|\.errors" | head -20
Repository: RustPython/RustPython
Length of output: 127
🏁 Script executed:
# Check what happens with qualified module imports in RustPython rg -n "import.*\\..*import" Lib/test/test_import*.py | head -20
Repository: RustPython/RustPython
Length of output: 129
🏁 Script executed:
# Look at how modules set their __name__ attribute during creation cat -n crates/vm/src/builtins/module.rs | sed -n '1,200p' | tail -100
Repository: RustPython/RustPython
Length of output: 4025
🏁 Script executed:
# Check if there's anything about parent module setup in module creation rg -n "__package__\|__path__" crates/vm/src/builtins/module.rs
Repository: RustPython/RustPython
Length of output: 47
🏁 Script executed:
# Check if there are any tests or code that use import pyexpat.model or pyexpat.errors rg -n "import.*pyexpat\." Lib/test/test_pyexpat.py
Repository: RustPython/RustPython
Length of output: 47
🏁 Script executed:
# Look at the test more carefully to see if qualified imports are tested cat -n Lib/test/test_pyexpat.py | sed -n '1,50p'
Repository: RustPython/RustPython
Length of output: 2047
🏁 Script executed:
# Check how create_module is implemented to understand what __name__ gets set cat -n crates/vm/src/builtins/module.rs | sed -n '44,75p'
Repository: RustPython/RustPython
Length of output: 1461
🏁 Script executed:
# Verify if vm.sys_module.get_attr is available and the set_item API works rg -n "set_item\|get_attr" crates/stdlib/src/pyexpat.rs
Repository: RustPython/RustPython
Length of output: 47
🏁 Script executed:
# Look for similar patterns in other modules to see if anyone else registers submodules rg -n "sys_modules.*set_item" crates/stdlib/src/
Repository: RustPython/RustPython
Length of output: 47
🏁 Script executed:
# Check if test_pyexpat.py or other tests actually try qualified imports like "import pyexpat.errors" grep -rn "import pyexpat" Lib/test/ | grep -v "from pyexpat"
Repository: RustPython/RustPython
Length of output: 109
🏁 Script executed:
# Look at what the test actually expects - check line 275 more closely sed -n '270,280p' Lib/test/test_pyexpat.py
Repository: RustPython/RustPython
Length of output: 600
🏁 Script executed:
# Check how the xml.parsers.expat module relates to pyexpat find . -name "expat.py" -o -name "*expat*" -path "*/xml/parsers/*"
Repository: RustPython/RustPython
Length of output: 91
🏁 Script executed:
# See if there are any imports of pyexpat.model or pyexpat.errors in the entire codebase rg -rn "pyexpat\.model\|pyexpat\.errors"
Repository: RustPython/RustPython
Length of output: 47
🏁 Script executed:
# Check the actual behavior - what __name__ does the model submodule have rg -n "model\|errors" crates/stdlib/src/pyexpat.rs | grep -E "pymodule|module_def"
Repository: RustPython/RustPython
Length of output: 47
🏁 Script executed:
# Look at the xml.parsers.expat module to understand the relationship cat -n Lib/xml/parsers/expat.py | head -50
Repository: RustPython/RustPython
Length of output: 368
🏁 Script executed:
# Check if expat.py re-exports or wraps pyexpat grep -n "pyexpat\|from.*import" Lib/xml/parsers/expat.py | head -30
Repository: RustPython/RustPython
Length of output: 151
🏁 Script executed:
# Look for how sys.modules handles submodule registrations in import tests find Lib/test -name "*.py" -exec grep -l "sys.modules" {} \; | head -5
Repository: RustPython/RustPython
Length of output: 3453
🏁 Script executed:
# Check if there's any code that tests or uses qualified submodule imports grep -rn "sys\.modules\[.*\.\|set_item.*\." Lib/test/ | head -20
Repository: RustPython/RustPython
Length of output: 1996
🏁 Script executed:
# Check how the import system finds submodules - look for the import machinery grep -n "find.*submodule\|parent.*module" crates/vm/src/import.rs
Repository: RustPython/RustPython
Length of output: 47
🏁 Script executed:
# See the full expat.py file to understand how it uses the submodules
cat -n Lib/xml/parsers/expat.pyRepository: RustPython/RustPython
Length of output: 368
🏁 Script executed:
# Check if RustPython's import system is in importlib (frozen) find . -name "*importlib*" -type f | grep -v ".pyc\|test"
Repository: RustPython/RustPython
Length of output: 47
🏁 Script executed:
# Test whether qualified imports actually work in RustPython by looking for test cases rg -n "import.*\\..*\|sys.modules.*\\." Lib/test/test_importlib/ | head -20
Repository: RustPython/RustPython
Length of output: 47
🏁 Script executed:
# Check if there are any actual tests that try to import pyexpat.model or pyexpat.errors directly grep -rn "import pyexpat\.model\|import pyexpat\.errors\|from pyexpat import model\|from pyexpat import errors" Lib/
Repository: RustPython/RustPython
Length of output: 47
🏁 Script executed:
# Look at what attributes are accessible on pyexpat module cat -n crates/stdlib/src/pyexpat.rs | sed -n '53,75p'
Repository: RustPython/RustPython
Length of output: 917
🏁 Script executed:
# Check if the import system in RustPython handles qualified imports rg -n "resolve.*parent\|split.*module.*name" crates/vm/src/import.rs | head -20
Repository: RustPython/RustPython
Length of output: 47
🏁 Script executed:
# Look for how other builtin modules with submodules handle this find crates/stdlib/src -name "*.rs" -exec grep -l "super::_" {} \; | head -10
Repository: RustPython/RustPython
Length of output: 150
🏁 Script executed:
# Final check - see if there's a test that verifies pyexpat.errors can be imported as a qualified name rg -rn "pyexpat\.errors\|pyexpat\.model" Lib/test/ 2>/dev/null
Repository: RustPython/RustPython
Length of output: 47
🏁 Script executed:
# Look for documentation on how Python handles module.submodule imports grep -rn "__path__" crates/vm/src/builtins/module.rs
Repository: RustPython/RustPython
Length of output: 47
🏁 Script executed:
# Check if pyexpat should be a package by looking at CPython source patterns rg -n "is_package\|__path__" crates/stdlib/src/ | head -20
Repository: RustPython/RustPython
Length of output: 47
🏁 Script executed:
# Verify what __name__ is actually set to for the submodules by checking module creation cat -n crates/vm/src/builtins/module.rs | sed -n '119,130p'
Repository: RustPython/RustPython
Length of output: 513
🏁 Script executed:
# Check if there's any handling of qualified module imports in RustPython's import system rg -n "\.split\(.*\.\)" crates/vm/src/import.rs | head -10
Repository: RustPython/RustPython
Length of output: 47
Register pyexpat submodules with qualified names in sys.modules for CPython compatibility.
The current implementation attaches model and errors submodules as attributes but doesn't register them in sys.modules with qualified names (pyexpat.model, pyexpat.errors). This follows the pattern shown in Lib/xml/parsers/expat.py, which explicitly registers submodules in sys.modules. While RustPython's import system may not currently support qualified submodule imports like import pyexpat.model, registering them ensures compatibility with code that expects this behavior and with introspection tools that check sys.modules.