Skip to content

Commit 23aa9e0

Browse files
committed
refactor
1 parent 22f8354 commit 23aa9e0

File tree

1 file changed

+39
-45
lines changed

1 file changed

+39
-45
lines changed

vm/src/stdlib/typing.rs

Lines changed: 39 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -302,17 +302,7 @@ pub(crate) mod _typing {
302302

303303
let obj = typevar.into_ref_with_type(vm, cls)?;
304304
let obj_ref: PyObjectRef = obj.into();
305-
306-
// Set __module__ from the current frame
307-
if let Some(frame) = vm.current_frame() {
308-
if let Ok(module_name) = frame.globals.get_item("__name__", vm) {
309-
// Don't set __module__ if it's None
310-
if !vm.is_none(&module_name) {
311-
obj_ref.set_attr("__module__", module_name, vm)?;
312-
}
313-
}
314-
}
315-
305+
set_module_from_caller(&obj_ref, vm)?;
316306
Ok(obj_ref)
317307
}
318308
}
@@ -559,23 +549,7 @@ pub(crate) mod _typing {
559549

560550
let obj = paramspec.into_ref_with_type(vm, cls)?;
561551
let obj_ref: PyObjectRef = obj.into();
562-
563-
// Set __module__ from the current frame
564-
if let Some(frame) = vm.current_frame() {
565-
if let Ok(module_name) = frame.globals.get_item("__name__", vm) {
566-
// Set __module__ to None for modules that start with "<"
567-
if let Ok(name_str) = module_name.str(vm) {
568-
if name_str.as_str().starts_with('<') {
569-
obj_ref.set_attr("__module__", vm.ctx.none(), vm)?;
570-
} else {
571-
obj_ref.set_attr("__module__", module_name, vm)?;
572-
}
573-
} else {
574-
obj_ref.set_attr("__module__", module_name, vm)?;
575-
}
576-
}
577-
}
578-
552+
set_module_from_caller(&obj_ref, vm)?;
579553
Ok(obj_ref)
580554
}
581555
}
@@ -722,23 +696,7 @@ pub(crate) mod _typing {
722696

723697
let obj = typevartuple.into_ref_with_type(vm, cls)?;
724698
let obj_ref: PyObjectRef = obj.into();
725-
726-
// Set __module__ from the current frame
727-
if let Some(frame) = vm.current_frame() {
728-
if let Ok(module_name) = frame.globals.get_item("__name__", vm) {
729-
// Set __module__ to None for modules that start with "<"
730-
if let Ok(name_str) = module_name.str(vm) {
731-
if name_str.as_str().starts_with('<') {
732-
obj_ref.set_attr("__module__", vm.ctx.none(), vm)?;
733-
} else {
734-
obj_ref.set_attr("__module__", module_name, vm)?;
735-
}
736-
} else {
737-
obj_ref.set_attr("__module__", module_name, vm)?;
738-
}
739-
}
740-
}
741-
699+
set_module_from_caller(&obj_ref, vm)?;
742700
Ok(obj_ref)
743701
}
744702
}
@@ -893,4 +851,40 @@ pub(crate) mod _typing {
893851
// &AS_MAPPING
894852
// }
895853
// }
854+
855+
/// Get the module of the caller frame, similar to CPython's caller() function.
856+
/// Returns the module name or None if not found.
857+
///
858+
/// Note: CPython's implementation (in typevarobject.c) gets the module from the
859+
/// frame's function object using PyFunction_GetModule(f->f_funcobj). However,
860+
/// RustPython's Frame doesn't store a reference to the function object, so we
861+
/// get the module name from the frame's globals dictionary instead.
862+
fn caller(vm: &VirtualMachine) -> Option<PyObjectRef> {
863+
let frame = vm.current_frame()?;
864+
865+
// In RustPython, we get the module name from frame's globals
866+
// This is similar to CPython's sys._getframe().f_globals.get('__name__')
867+
frame.globals.get_item("__name__", vm).ok()
868+
}
869+
870+
/// Set __module__ attribute for an object based on the caller's module.
871+
/// This follows CPython's behavior for TypeVar and similar objects.
872+
fn set_module_from_caller(obj: &PyObjectRef, vm: &VirtualMachine) -> PyResult<()> {
873+
// Note: CPython gets module from frame->f_funcobj, but RustPython's Frame
874+
// architecture is different - we use globals['__name__'] instead
875+
if let Some(module_name) = caller(vm) {
876+
// Special handling for certain module names
877+
if let Ok(name_str) = module_name.str(vm) {
878+
let name = name_str.as_str();
879+
// CPython sets __module__ to None for builtins and <...> modules
880+
if name == "builtins" || name.starts_with('<') {
881+
// Don't set __module__ attribute at all (CPython behavior)
882+
// This allows the typing module to handle it
883+
return Ok(());
884+
}
885+
}
886+
obj.set_attr("__module__", module_name, vm)?;
887+
}
888+
Ok(())
889+
}
896890
}

0 commit comments

Comments
 (0)