| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
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
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Expand Up | @@ -610,13 +610,13 @@ impl Compiler { | |||||||||||||||||||||
| self.compile_expression(value)?; | ||||||||||||||||||||||
| match collection_type { | ||||||||||||||||||||||
| CollectionType::List => { | ||||||||||||||||||||||
| emit!(self, Instruction::ListExtend { i: 0 }); | ||||||||||||||||||||||
| emit!(self, Instruction::ListExtend { i: 1 }); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| CollectionType::Set => { | ||||||||||||||||||||||
| emit!(self, Instruction::SetUpdate { i: 0 }); | ||||||||||||||||||||||
| emit!(self, Instruction::SetUpdate { i: 1 }); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| CollectionType::Tuple => { | ||||||||||||||||||||||
| emit!(self, Instruction::ListExtend { i: 0 }); | ||||||||||||||||||||||
| emit!(self, Instruction::ListExtend { i: 1 }); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } else { | ||||||||||||||||||||||
| Expand All | @@ -627,13 +627,13 @@ impl Compiler { | |||||||||||||||||||||
| // Sequence already exists, append to it | ||||||||||||||||||||||
| match collection_type { | ||||||||||||||||||||||
| CollectionType::List => { | ||||||||||||||||||||||
| emit!(self, Instruction::ListAppend { i: 0 }); | ||||||||||||||||||||||
| emit!(self, Instruction::ListAppend { i: 1 }); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| CollectionType::Set => { | ||||||||||||||||||||||
| emit!(self, Instruction::SetAdd { i: 0 }); | ||||||||||||||||||||||
| emit!(self, Instruction::SetAdd { i: 1 }); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| CollectionType::Tuple => { | ||||||||||||||||||||||
| emit!(self, Instruction::ListAppend { i: 0 }); | ||||||||||||||||||||||
| emit!(self, Instruction::ListAppend { i: 1 }); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } else { | ||||||||||||||||||||||
| Expand Down Expand Up | @@ -692,6 +692,23 @@ impl Compiler { | |||||||||||||||||||||
| .expect("symbol_table_stack is empty! This is a compiler bug.") | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| /// Check if a name is imported in current scope or any enclosing scope. | ||||||||||||||||||||||
| fn is_name_imported(&self, name: &str) -> bool { | ||||||||||||||||||||||
| if let Some(sym) = self.current_symbol_table().symbols.get(name) { | ||||||||||||||||||||||
| if sym.flags.contains(SymbolFlags::IMPORTED) { | ||||||||||||||||||||||
| return true; | ||||||||||||||||||||||
| } else if sym.scope == SymbolScope::Local { | ||||||||||||||||||||||
| return false; | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| self.symbol_table_stack.iter().rev().skip(1).any(|table| { | ||||||||||||||||||||||
| table | ||||||||||||||||||||||
| .symbols | ||||||||||||||||||||||
| .get(name) | ||||||||||||||||||||||
| .is_some_and(|sym| sym.flags.contains(SymbolFlags::IMPORTED)) | ||||||||||||||||||||||
| }) | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| /// Get the cell-relative index of a free variable. | ||||||||||||||||||||||
| /// Returns ncells + freevar_idx. Fixed up to localsplus index during finalize. | ||||||||||||||||||||||
| fn get_free_var_index(&mut self, name: &str) -> CompileResult<oparg::VarNum> { | ||||||||||||||||||||||
| Expand Down Expand Up | @@ -1151,7 +1168,16 @@ impl Compiler { | |||||||||||||||||||||
| self.set_qualname(); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| // Emit COPY_FREE_VARS and MAKE_CELL prolog before RESUME | ||||||||||||||||||||||
| // Emit MAKE_CELL for each cell variable (before RESUME) | ||||||||||||||||||||||
| { | ||||||||||||||||||||||
| let ncells = self.code_stack.last().unwrap().metadata.cellvars.len(); | ||||||||||||||||||||||
| for i in 0..ncells { | ||||||||||||||||||||||
| let i_varnum: oparg::VarNum = u32::try_from(i).expect("too many cellvars").into(); | ||||||||||||||||||||||
| emit!(self, Instruction::MakeCell { i: i_varnum }); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| // Emit COPY_FREE_VARS if there are free variables (before RESUME) | ||||||||||||||||||||||
| { | ||||||||||||||||||||||
| let nfrees = self.code_stack.last().unwrap().metadata.freevars.len(); | ||||||||||||||||||||||
| if nfrees > 0 { | ||||||||||||||||||||||
| Expand All | @@ -1162,11 +1188,6 @@ impl Compiler { | |||||||||||||||||||||
| } | ||||||||||||||||||||||
| ); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| let ncells = self.code_stack.last().unwrap().metadata.cellvars.len(); | ||||||||||||||||||||||
| for i in 0..ncells { | ||||||||||||||||||||||
| let i_varnum: oparg::VarNum = u32::try_from(i).expect("too many cellvars").into(); | ||||||||||||||||||||||
| emit!(self, Instruction::MakeCell { i: i_varnum }); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| // Emit RESUME (handles async preamble and module lineno 0) | ||||||||||||||||||||||
| Expand Down Expand Up | @@ -1739,7 +1760,7 @@ impl Compiler { | |||||||||||||||||||||
| value: value.into(), | ||||||||||||||||||||||
| }); | ||||||||||||||||||||||
| let doc = self.name("__doc__"); | ||||||||||||||||||||||
| emit!(self, Instruction::StoreGlobal { namei: doc }) | ||||||||||||||||||||||
| emit!(self, Instruction::StoreName { namei: doc }) | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| // Handle annotations based on future_annotations flag | ||||||||||||||||||||||
| Expand Down Expand Up | @@ -3424,7 +3445,7 @@ impl Compiler { | |||||||||||||||||||||
| if n == 0 { | ||||||||||||||||||||||
| // Empty handlers (invalid AST) - append rest to list and proceed | ||||||||||||||||||||||
| // Stack: [prev_exc, orig, list, rest] | ||||||||||||||||||||||
| emit!(self, Instruction::ListAppend { i: 0 }); | ||||||||||||||||||||||
| emit!(self, Instruction::ListAppend { i: 1 }); | ||||||||||||||||||||||
| // Stack: [prev_exc, orig, list] | ||||||||||||||||||||||
| emit!( | ||||||||||||||||||||||
| self, | ||||||||||||||||||||||
| Expand Down Expand Up | @@ -3542,7 +3563,7 @@ impl Compiler { | |||||||||||||||||||||
| // After pop: [prev_exc, orig, list, new_rest, lasti] (len=5) | ||||||||||||||||||||||
| // nth_value(i) = stack[len - i - 1], we need stack[2] = list | ||||||||||||||||||||||
| // stack[5 - i - 1] = 2 -> i = 2 | ||||||||||||||||||||||
| emit!(self, Instruction::ListAppend { i: 2 }); | ||||||||||||||||||||||
| emit!(self, Instruction::ListAppend { i: 3 }); | ||||||||||||||||||||||
| // Stack: [prev_exc, orig, list, new_rest, lasti] | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| // POP_TOP - pop lasti | ||||||||||||||||||||||
| Expand Down Expand Up | @@ -3571,7 +3592,7 @@ impl Compiler { | |||||||||||||||||||||
| // PEEK(1) = stack[len-1] after pop | ||||||||||||||||||||||
| // RustPython nth_value(i) = stack[len-i-1] after pop | ||||||||||||||||||||||
| // For LIST_APPEND 1: stack[len-1] = stack[len-i-1] -> i = 0 | ||||||||||||||||||||||
| emit!(self, Instruction::ListAppend { i: 0 }); | ||||||||||||||||||||||
| emit!(self, Instruction::ListAppend { i: 1 }); | ||||||||||||||||||||||
| // Stack: [prev_exc, orig, list] | ||||||||||||||||||||||
| emit!( | ||||||||||||||||||||||
| self, | ||||||||||||||||||||||
| Expand Down Expand Up | @@ -4561,9 +4582,9 @@ impl Compiler { | |||||||||||||||||||||
| // 2. Set up class namespace | ||||||||||||||||||||||
| let (doc_str, body) = split_doc(body, &self.opts); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| // Load (global) __name__ and store as __module__ | ||||||||||||||||||||||
| // Load __name__ and store as __module__ | ||||||||||||||||||||||
| let dunder_name = self.name("__name__"); | ||||||||||||||||||||||
| self.emit_load_global(dunder_name, false); | ||||||||||||||||||||||
| emit!(self, Instruction::LoadName { namei: dunder_name }); | ||||||||||||||||||||||
| let dunder_module = self.name("__module__"); | ||||||||||||||||||||||
| emit!( | ||||||||||||||||||||||
| self, | ||||||||||||||||||||||
| Expand All | @@ -4584,14 +4605,7 @@ impl Compiler { | |||||||||||||||||||||
| } | ||||||||||||||||||||||
| ); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| // Store __doc__ only if there's an explicit docstring | ||||||||||||||||||||||
| if let Some(doc) = doc_str { | ||||||||||||||||||||||
| self.emit_load_const(ConstantData::Str { value: doc.into() }); | ||||||||||||||||||||||
| let doc_name = self.name("__doc__"); | ||||||||||||||||||||||
| emit!(self, Instruction::StoreName { namei: doc_name }); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| // Store __firstlineno__ (new in Python 3.12+) | ||||||||||||||||||||||
| // Store __firstlineno__ before __doc__ | ||||||||||||||||||||||
| self.emit_load_const(ConstantData::Integer { | ||||||||||||||||||||||
| value: BigInt::from(firstlineno), | ||||||||||||||||||||||
| }); | ||||||||||||||||||||||
| Expand All | @@ -4603,6 +4617,13 @@ impl Compiler { | |||||||||||||||||||||
| } | ||||||||||||||||||||||
| ); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| // Store __doc__ only if there's an explicit docstring | ||||||||||||||||||||||
| if let Some(doc) = doc_str { | ||||||||||||||||||||||
| self.emit_load_const(ConstantData::Str { value: doc.into() }); | ||||||||||||||||||||||
| let doc_name = self.name("__doc__"); | ||||||||||||||||||||||
| emit!(self, Instruction::StoreName { namei: doc_name }); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| // Set __type_params__ if we have type parameters | ||||||||||||||||||||||
| if type_params.is_some() { | ||||||||||||||||||||||
| // Load .type_params from enclosing scope | ||||||||||||||||||||||
| Expand Down Expand Up | @@ -4661,6 +4682,44 @@ impl Compiler { | |||||||||||||||||||||
| .iter() | ||||||||||||||||||||||
| .position(|var| *var == "__class__"); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| // Emit __static_attributes__ tuple | ||||||||||||||||||||||
| { | ||||||||||||||||||||||
| let attrs: Vec<String> = self | ||||||||||||||||||||||
| .code_stack | ||||||||||||||||||||||
| .last() | ||||||||||||||||||||||
| .unwrap() | ||||||||||||||||||||||
| .static_attributes | ||||||||||||||||||||||
| .as_ref() | ||||||||||||||||||||||
| .map(|s| s.iter().cloned().collect()) | ||||||||||||||||||||||
| .unwrap_or_default(); | ||||||||||||||||||||||
| self.emit_load_const(ConstantData::Tuple { | ||||||||||||||||||||||
| elements: attrs | ||||||||||||||||||||||
| .into_iter() | ||||||||||||||||||||||
| .map(|s| ConstantData::Str { value: s.into() }) | ||||||||||||||||||||||
| .collect(), | ||||||||||||||||||||||
| }); | ||||||||||||||||||||||
| let static_attrs_name = self.name("__static_attributes__"); | ||||||||||||||||||||||
| emit!( | ||||||||||||||||||||||
| self, | ||||||||||||||||||||||
| Instruction::StoreName { | ||||||||||||||||||||||
| namei: static_attrs_name | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| ); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| // Store __classdictcell__ if __classdict__ is a cell variable | ||||||||||||||||||||||
| if self.current_symbol_table().needs_classdict { | ||||||||||||||||||||||
| let classdict_idx = u32::from(self.get_cell_var_index("__classdict__")?); | ||||||||||||||||||||||
| emit!(self, PseudoInstruction::LoadClosure { i: classdict_idx }); | ||||||||||||||||||||||
| let classdictcell = self.name("__classdictcell__"); | ||||||||||||||||||||||
| emit!( | ||||||||||||||||||||||
| self, | ||||||||||||||||||||||
| Instruction::StoreName { | ||||||||||||||||||||||
| namei: classdictcell | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| ); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| if let Some(classcell_idx) = classcell_idx { | ||||||||||||||||||||||
| emit!( | ||||||||||||||||||||||
| self, | ||||||||||||||||||||||
| Expand Down Expand Up | @@ -4810,11 +4869,11 @@ impl Compiler { | |||||||||||||||||||||
| if let ast::Expr::Starred(ast::ExprStarred { value, .. }) = arg { | ||||||||||||||||||||||
| // Starred: compile and extend | ||||||||||||||||||||||
| self.compile_expression(value)?; | ||||||||||||||||||||||
| emit!(self, Instruction::ListExtend { i: 0 }); | ||||||||||||||||||||||
| emit!(self, Instruction::ListExtend { i: 1 }); | ||||||||||||||||||||||
| } else { | ||||||||||||||||||||||
| // Non-starred: compile and append | ||||||||||||||||||||||
| self.compile_expression(arg)?; | ||||||||||||||||||||||
| emit!(self, Instruction::ListAppend { i: 0 }); | ||||||||||||||||||||||
| emit!(self, Instruction::ListAppend { i: 1 }); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| Expand All | @@ -4826,7 +4885,7 @@ impl Compiler { | |||||||||||||||||||||
| namei: dot_generic_base | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| ); | ||||||||||||||||||||||
| emit!(self, Instruction::ListAppend { i: 0 }); | ||||||||||||||||||||||
| emit!(self, Instruction::ListAppend { i: 1 }); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| // Convert list to tuple | ||||||||||||||||||||||
| emit!( | ||||||||||||||||||||||
| Expand Down Expand Up | @@ -6495,7 +6554,7 @@ impl Compiler { | |||||||||||||||||||||
| self.emit_load_const(ConstantData::Integer { | ||||||||||||||||||||||
| value: annotation_index.into(), | ||||||||||||||||||||||
| }); | ||||||||||||||||||||||
| emit!(self, Instruction::SetAdd { i: 0 }); | ||||||||||||||||||||||
| emit!(self, Instruction::SetAdd { i: 1 }); | ||||||||||||||||||||||
| emit!(self, Instruction::PopTop); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| Expand Down Expand Up | @@ -6742,6 +6801,10 @@ impl Compiler { | |||||||||||||||||||||
| _ => { | ||||||||||||||||||||||
| // Fall back case which always will work! | ||||||||||||||||||||||
| self.compile_expression(expression)?; | ||||||||||||||||||||||
| // Compare already produces a bool; everything else needs TO_BOOL | ||||||||||||||||||||||
| if !matches!(expression, ast::Expr::Compare(_)) { | ||||||||||||||||||||||
| emit!(self, Instruction::ToBool); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
Comment thread
Comment on lines
+6804
to
+6807
Copy link
Copy Markdown
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality⚠️ Potential issue | 🟡 Minor The Compare rationale is inaccurate. Rich comparisons can return arbitrary objects; the reason this fast path is safe is the jump opcode’s truthiness handling, not that Compare itself always yields a bool. Please reword the comment so future refactors do not depend on the wrong invariant. Suggested comment update- // Compare already produces a bool; everything else needs TO_BOOL
+ // Rich comparisons may return non-bool objects; skipping TO_BOOL
+ // here is only correct because PopJumpIf* performs truthiness
+ // conversion itself.
Suggested change
Verify each finding against the current code and only fix it if needed. In `@crates/codegen/src/compile.rs` around lines 6732 - 6735, The comment above the ToBool emission is misleading because ast::Expr::Compare may produce non-bool values; update the comment near the if !matches!(expression, ast::Expr::Compare) check to state that the Compare fast path is safe due to the jump opcode’s truthiness handling (not because Compare always yields a bool), and clarify that everything else needs Instruction::ToBool before branching; reference the emit!(self, Instruction::ToBool) call and the ast::Expr::Compare pattern in the comment.
Sorry, something went wrong.
All reactions
|
||||||||||||||||||||||
| if condition { | ||||||||||||||||||||||
| emit!( | ||||||||||||||||||||||
| self, | ||||||||||||||||||||||
| Expand Down Expand Up | @@ -7240,7 +7303,7 @@ impl Compiler { | |||||||||||||||||||||
| emit!( | ||||||||||||||||||||||
| compiler, | ||||||||||||||||||||||
| Instruction::ListAppend { | ||||||||||||||||||||||
| i: generators.len().to_u32(), | ||||||||||||||||||||||
| i: (generators.len() + 1).to_u32(), | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| ); | ||||||||||||||||||||||
| Ok(()) | ||||||||||||||||||||||
| Expand All | @@ -7266,7 +7329,7 @@ impl Compiler { | |||||||||||||||||||||
| emit!( | ||||||||||||||||||||||
| compiler, | ||||||||||||||||||||||
| Instruction::SetAdd { | ||||||||||||||||||||||
| i: generators.len().to_u32(), | ||||||||||||||||||||||
| i: (generators.len() + 1).to_u32(), | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| ); | ||||||||||||||||||||||
| Ok(()) | ||||||||||||||||||||||
| Expand Down Expand Up | @@ -7298,7 +7361,7 @@ impl Compiler { | |||||||||||||||||||||
| emit!( | ||||||||||||||||||||||
| compiler, | ||||||||||||||||||||||
| Instruction::MapAdd { | ||||||||||||||||||||||
| i: generators.len().to_u32(), | ||||||||||||||||||||||
| i: (generators.len() + 1).to_u32(), | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| ); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| Expand Down Expand Up | @@ -7516,11 +7579,19 @@ impl Compiler { | |||||||||||||||||||||
| // CALL at .method( line (not the full expression line) | ||||||||||||||||||||||
| self.codegen_call_helper(0, args, attr.range())?; | ||||||||||||||||||||||
| } else { | ||||||||||||||||||||||
| // Normal method call: compile object, then LOAD_ATTR with method flag | ||||||||||||||||||||||
| // LOAD_ATTR(method=1) pushes [method, self_or_null] on stack | ||||||||||||||||||||||
| self.compile_expression(value)?; | ||||||||||||||||||||||
| let idx = self.name(attr.as_str()); | ||||||||||||||||||||||
| self.emit_load_attr_method(idx); | ||||||||||||||||||||||
| // Imported names use plain LOAD_ATTR + PUSH_NULL; | ||||||||||||||||||||||
| // other names use method call mode LOAD_ATTR. | ||||||||||||||||||||||
| // Check current scope and enclosing scopes for IMPORTED flag. | ||||||||||||||||||||||
| let is_import = matches!(value.as_ref(), ast::Expr::Name(ast::ExprName { id, .. }) | ||||||||||||||||||||||
| if self.is_name_imported(id.as_str())); | ||||||||||||||||||||||
| if is_import { | ||||||||||||||||||||||
| self.emit_load_attr(idx); | ||||||||||||||||||||||
| emit!(self, Instruction::PushNull); | ||||||||||||||||||||||
| } else { | ||||||||||||||||||||||
| self.emit_load_attr_method(idx); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| self.codegen_call_helper(0, args, call_range)?; | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } else { | ||||||||||||||||||||||
| Expand Down Expand Up | @@ -7558,7 +7629,7 @@ impl Compiler { | |||||||||||||||||||||
| self.compile_expression(&kw.value)?; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| if big { | ||||||||||||||||||||||
| emit!(self, Instruction::MapAdd { i: 0 }); | ||||||||||||||||||||||
| emit!(self, Instruction::MapAdd { i: 1 }); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| Expand Down | ||||||||||||||||||||||
| Back | FazBrowse Home | New Git URL |
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.
Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality⚠️ Potential issue | 🟠 Major
__static_attributes__ is always serialized as () here.
enter_scope() initializes every class with Some(IndexSet::default()) on Line 1120, but this file never inserts into that set before reaching this block. The new store therefore overwrites every class body’s __static_attributes__ with an empty tuple, including any explicit assignment made in body. Either populate static_attributes before this point or skip the store until the set is non-empty.
Minimal guard to avoid clobbering classes until the collector existsVerify each finding against the current code and only fix it if needed. In `@crates/codegen/src/compile.rs` around lines 4626 - 4649, The current block always emits and stores an empty tuple to __static_attributes__ because enter_scope() initializes static_attributes to Some(empty) but nothing is added before this emit; update compile.rs to skip emitting/storing __static_attributes__ when the collected attrs vector is empty (i.e., check the code_stack.last().unwrap().static_attributes contents and only call emit_load_const/Instruction::StoreName/name("__static_attributes__") if attrs is non-empty), or alternatively change enter_scope() to initialize static_attributes as None and only create/populate it when the collector runs; target the symbols static_attributes, enter_scope, emit_load_const, Instruction::StoreName and name("__static_attributes__") when making the change.Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.