Skip to content

Commit b72cc5f

Browse files
youknowoneclaude
andcommitted
Implement Py_mod_create slot support in multi-phase init
Following CPython's implementation, now properly use the create slot if provided, instead of always using default module creation. CPython flow (Objects/moduleobject.c PyModule_FromDefAndSpec): - If Py_mod_create slot exists: call create(spec, def) - Otherwise: use PyModule_NewObject() for default creation RustPython now follows the same pattern: - If slots.create exists: call create(vm, spec, def) - Otherwise: use PyModule::from_def() + __init_dict_from_def() This allows modules to provide custom module objects during creation phase, enabling advanced use cases like singleton modules or modules with special initialization requirements. Tested: - Basic imports work correctly - sha256/sha512 with custom exec still work - test_pickle, test_pickletools, test_hashlib all pass Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent 1eaf55d commit b72cc5f

File tree

1 file changed

+11
-5
lines changed

1 file changed

+11
-5
lines changed

crates/vm/src/import.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -101,11 +101,17 @@ pub fn import_builtin(vm: &VirtualMachine, module_name: &str) -> PyResult {
101101
if let Some(def_func) = vm.state.module_defs.get(module_name) {
102102
let def = def_func(&vm.ctx);
103103

104-
// Phase 1: Create module from definition
105-
let module = PyModule::from_def(def).into_ref(&vm.ctx);
106-
107-
// Initialize module dict using proper method
108-
PyModule::__init_dict_from_def(vm, &module);
104+
// Phase 1: Create module (use create slot if provided, else default creation)
105+
let module = if let Some(create) = def.slots.create {
106+
// Custom module creation (CPython: Py_mod_create slot)
107+
let spec = vm.ctx.new_str(module_name);
108+
create(vm, spec.as_object(), def)?
109+
} else {
110+
// Default module creation
111+
let module = PyModule::from_def(def).into_ref(&vm.ctx);
112+
PyModule::__init_dict_from_def(vm, &module);
113+
module
114+
};
109115

110116
// Add to sys.modules BEFORE exec (critical for circular import handling)
111117
sys_modules.set_item(module_name, module.clone().into(), vm)?;

0 commit comments

Comments
 (0)