Skip to content

Commit c9a5f48

Browse files
committed
Restrict LOAD_ATTR plain mode to module/class scope imports
Only use plain LOAD_ATTR + PUSH_NULL for imports at module or class scope. Function-local imports use method call mode LOAD_ATTR, matching CPython 3.14's behavior.
1 parent 8948477 commit c9a5f48

File tree

1 file changed

+12
-5
lines changed

1 file changed

+12
-5
lines changed

crates/codegen/src/compile.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7514,11 +7514,18 @@ impl Compiler {
75147514
} else {
75157515
self.compile_expression(value)?;
75167516
let idx = self.name(attr.as_str());
7517-
// Imported names (modules) use plain LOAD_ATTR + PUSH_NULL;
7518-
// other names use method call mode LOAD_ATTR
7519-
let is_import = matches!(value.as_ref(), ast::Expr::Name(ast::ExprName { id, .. })
7520-
if self.current_symbol_table().symbols.get(id.as_str())
7521-
.is_some_and(|s| s.flags.contains(SymbolFlags::IMPORTED)));
7517+
// Module-level imported names use plain LOAD_ATTR + PUSH_NULL;
7518+
// function-local imports and other names use method call mode
7519+
let in_function = matches!(
7520+
self.current_symbol_table().typ,
7521+
CompilerScope::Function
7522+
| CompilerScope::AsyncFunction
7523+
| CompilerScope::Lambda
7524+
);
7525+
let is_import = !in_function
7526+
&& matches!(value.as_ref(), ast::Expr::Name(ast::ExprName { id, .. })
7527+
if self.current_symbol_table().symbols.get(id.as_str())
7528+
.is_some_and(|s| s.flags.contains(SymbolFlags::IMPORTED)));
75227529
if is_import {
75237530
self.emit_load_attr(idx);
75247531
emit!(self, Instruction::PushNull);

0 commit comments

Comments
 (0)