Skip to content

Commit 6df3753

Browse files
authored
Py 3.14 changes fix (#6755)
* marshal v5 * conditional blclk * fix jit don't use lossy string * add varname * symboltable takes responsibility of __debug__
1 parent 892116c commit 6df3753

File tree

9 files changed

+198
-90
lines changed

9 files changed

+198
-90
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Lib/test/test_future_stmt/test_future.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -459,9 +459,6 @@ def test_infinity_numbers(self):
459459
self.assertAnnotationEqual("('inf', 1e1000, 'infxxx', 1e1000j)", expected=f"('inf', {inf}, 'infxxx', {infj})")
460460
self.assertAnnotationEqual("(1e1000, (1e1000j,))", expected=f"({inf}, ({infj},))")
461461

462-
# TODO: RUSTPYTHON
463-
# AssertionError: SyntaxError not raised
464-
@unittest.expectedFailure
465462
def test_annotation_with_complex_target(self):
466463
with self.assertRaises(SyntaxError):
467464
exec(

crates/codegen/src/compile.rs

Lines changed: 48 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -110,14 +110,6 @@ enum NameUsage {
110110
Store,
111111
Delete,
112112
}
113-
114-
fn is_forbidden_name(name: &str) -> bool {
115-
// See https://docs.python.org/3/library/constants.html#built-in-constants
116-
const BUILTIN_CONSTANTS: &[&str] = &["__debug__"];
117-
118-
BUILTIN_CONSTANTS.contains(&name)
119-
}
120-
121113
/// Main structure holding the state of compilation.
122114
struct Compiler {
123115
code_stack: Vec<ir::CodeInfo>,
@@ -130,10 +122,6 @@ struct Compiler {
130122
ctx: CompileContext,
131123
opts: CompileOpts,
132124
in_annotation: bool,
133-
// PEP 649: Track if we're inside a conditional block (if/for/while/etc.)
134-
in_conditional_block: bool,
135-
// PEP 649: Next index for conditional annotation tracking
136-
next_conditional_annotation_index: u32,
137125
}
138126

139127
enum DoneWithFuture {
@@ -424,6 +412,8 @@ impl Compiler {
424412
in_inlined_comp: false,
425413
fblock: Vec::with_capacity(MAXBLOCKS),
426414
symbol_table_index: 0, // Module is always the first symbol table
415+
in_conditional_block: 0,
416+
next_conditional_annotation_index: 0,
427417
};
428418
Self {
429419
code_stack: vec![module_code],
@@ -441,8 +431,6 @@ impl Compiler {
441431
},
442432
opts,
443433
in_annotation: false,
444-
in_conditional_block: false,
445-
next_conditional_annotation_index: 0,
446434
}
447435
}
448436

@@ -1045,6 +1033,8 @@ impl Compiler {
10451033
in_inlined_comp: false,
10461034
fblock: Vec::with_capacity(MAXBLOCKS),
10471035
symbol_table_index: key,
1036+
in_conditional_block: 0,
1037+
next_conditional_annotation_index: 0,
10481038
};
10491039

10501040
// Push the old compiler unit on the stack (like PyCapsule)
@@ -1525,11 +1515,7 @@ impl Compiler {
15251515
self._name_inner(name, |i| &mut i.metadata.names)
15261516
}
15271517
fn varname(&mut self, name: &str) -> CompileResult<bytecode::NameIdx> {
1528-
if Self::is_forbidden_arg_name(name) {
1529-
return Err(self.error(CodegenErrorType::SyntaxError(format!(
1530-
"cannot assign to {name}",
1531-
))));
1532-
}
1518+
// Note: __debug__ checks are now handled in symboltable phase
15331519
Ok(self._name_inner(name, |i| &mut i.metadata.varnames))
15341520
}
15351521
fn _name_inner(
@@ -1814,15 +1800,6 @@ impl Compiler {
18141800
symboltable::mangle_name(private, name)
18151801
}
18161802

1817-
fn check_forbidden_name(&mut self, name: &str, usage: NameUsage) -> CompileResult<()> {
1818-
let msg = match usage {
1819-
NameUsage::Store if is_forbidden_name(name) => "cannot assign to",
1820-
NameUsage::Delete if is_forbidden_name(name) => "cannot delete",
1821-
_ => return Ok(()),
1822-
};
1823-
Err(self.error(CodegenErrorType::SyntaxError(format!("{msg} {name}"))))
1824-
}
1825-
18261803
// = compiler_nameop
18271804
fn compile_name(&mut self, name: &str, usage: NameUsage) -> CompileResult<()> {
18281805
enum NameOp {
@@ -1834,7 +1811,6 @@ impl Compiler {
18341811
}
18351812

18361813
let name = self.mangle(name);
1837-
self.check_forbidden_name(&name, usage)?;
18381814

18391815
// Special handling for __debug__
18401816
if NameUsage::Load == usage && name == "__debug__" {
@@ -2135,6 +2111,7 @@ impl Compiler {
21352111
elif_else_clauses,
21362112
..
21372113
}) => {
2114+
self.enter_conditional_block();
21382115
match elif_else_clauses.as_slice() {
21392116
// Only if
21402117
[] => {
@@ -2182,6 +2159,7 @@ impl Compiler {
21822159
self.switch_to_block(after_block);
21832160
}
21842161
}
2162+
self.leave_conditional_block();
21852163
}
21862164
Stmt::While(StmtWhile {
21872165
test, body, orelse, ..
@@ -2228,11 +2206,13 @@ impl Compiler {
22282206
is_star,
22292207
..
22302208
}) => {
2209+
self.enter_conditional_block();
22312210
if *is_star {
22322211
self.compile_try_star_except(body, handlers, orelse, finalbody)?
22332212
} else {
22342213
self.compile_try_statement(body, handlers, orelse, finalbody)?
22352214
}
2215+
self.leave_conditional_block();
22362216
}
22372217
Stmt::FunctionDef(StmtFunctionDef {
22382218
name,
@@ -2432,7 +2412,6 @@ impl Compiler {
24322412
match &expression {
24332413
Expr::Name(ExprName { id, .. }) => self.compile_name(id.as_str(), NameUsage::Delete)?,
24342414
Expr::Attribute(ExprAttribute { value, attr, .. }) => {
2435-
self.check_forbidden_name(attr.as_str(), NameUsage::Delete)?;
24362415
self.compile_expression(value)?;
24372416
let idx = self.name(attr.as_str());
24382417
emit!(self, Instruction::DeleteAttr { idx });
@@ -3451,10 +3430,6 @@ impl Compiler {
34513430
Ok(())
34523431
}
34533432

3454-
fn is_forbidden_arg_name(name: &str) -> bool {
3455-
is_forbidden_name(name)
3456-
}
3457-
34583433
/// Compile default arguments
34593434
// = compiler_default_arguments
34603435
fn compile_default_arguments(
@@ -4485,6 +4460,8 @@ impl Compiler {
44854460
}
44864461

44874462
fn compile_while(&mut self, test: &Expr, body: &[Stmt], orelse: &[Stmt]) -> CompileResult<()> {
4463+
self.enter_conditional_block();
4464+
44884465
let while_block = self.new_block();
44894466
let else_block = self.new_block();
44904467
let after_block = self.new_block();
@@ -4513,6 +4490,8 @@ impl Compiler {
45134490
// Note: PopBlock is no longer emitted for loops
45144491
self.compile_statements(orelse)?;
45154492
self.switch_to_block(after_block);
4493+
4494+
self.leave_conditional_block();
45164495
Ok(())
45174496
}
45184497

@@ -4522,6 +4501,8 @@ impl Compiler {
45224501
body: &[Stmt],
45234502
is_async: bool,
45244503
) -> CompileResult<()> {
4504+
self.enter_conditional_block();
4505+
45254506
// Python 3.12+ style with statement:
45264507
//
45274508
// BEFORE_WITH # TOS: ctx_mgr -> [__exit__, __enter__ result]
@@ -4734,6 +4715,7 @@ impl Compiler {
47344715
// ===== After block =====
47354716
self.switch_to_block(after_block);
47364717

4718+
self.leave_conditional_block();
47374719
Ok(())
47384720
}
47394721

@@ -4745,6 +4727,8 @@ impl Compiler {
47454727
orelse: &[Stmt],
47464728
is_async: bool,
47474729
) -> CompileResult<()> {
4730+
self.enter_conditional_block();
4731+
47484732
// Start loop
47494733
let for_block = self.new_block();
47504734
let else_block = self.new_block();
@@ -4812,6 +4796,7 @@ impl Compiler {
48124796

48134797
self.switch_to_block(after_block);
48144798

4799+
self.leave_conditional_block();
48154800
Ok(())
48164801
}
48174802

@@ -5784,8 +5769,10 @@ impl Compiler {
57845769
}
57855770

57865771
fn compile_match(&mut self, subject: &Expr, cases: &[MatchCase]) -> CompileResult<()> {
5772+
self.enter_conditional_block();
57875773
let mut pattern_context = PatternContext::new();
57885774
self.compile_match_inner(subject, cases, &mut pattern_context)?;
5775+
self.leave_conditional_block();
57895776
Ok(())
57905777
}
57915778

@@ -5946,16 +5933,22 @@ impl Compiler {
59465933
} else {
59475934
// PEP 649: Handle conditional annotations
59485935
if self.current_symbol_table().has_conditional_annotations {
5949-
// Determine if this annotation is conditional
5950-
let is_module = self.current_symbol_table().typ == CompilerScope::Module;
5951-
let is_conditional = is_module || self.in_conditional_block;
5936+
// Allocate an index for every annotation when has_conditional_annotations
5937+
// This keeps indices aligned with compile_module_annotate's enumeration
5938+
let code_info = self.current_code_info();
5939+
let annotation_index = code_info.next_conditional_annotation_index;
5940+
code_info.next_conditional_annotation_index += 1;
59525941

5942+
// Determine if this annotation is conditional
5943+
// Module and Class scopes both need all annotations tracked
5944+
let scope_type = self.current_symbol_table().typ;
5945+
let in_conditional_block = self.current_code_info().in_conditional_block > 0;
5946+
let is_conditional =
5947+
matches!(scope_type, CompilerScope::Module | CompilerScope::Class)
5948+
|| in_conditional_block;
5949+
5950+
// Only add to __conditional_annotations__ set if actually conditional
59535951
if is_conditional {
5954-
// Get the current annotation index and increment
5955-
let annotation_index = self.next_conditional_annotation_index;
5956-
self.next_conditional_annotation_index += 1;
5957-
5958-
// Add index to __conditional_annotations__ set
59595952
let cond_annotations_name = self.name("__conditional_annotations__");
59605953
emit!(self, Instruction::LoadName(cond_annotations_name));
59615954
self.emit_load_const(ConstantData::Integer {
@@ -5980,7 +5973,6 @@ impl Compiler {
59805973
self.compile_subscript(value, slice, *ctx)?;
59815974
}
59825975
Expr::Attribute(ExprAttribute { value, attr, .. }) => {
5983-
self.check_forbidden_name(attr.as_str(), NameUsage::Store)?;
59845976
self.compile_expression(value)?;
59855977
let idx = self.name(attr.as_str());
59865978
emit!(self, Instruction::StoreAttr { idx });
@@ -6075,7 +6067,6 @@ impl Compiler {
60756067
}
60766068
Expr::Attribute(ExprAttribute { value, attr, .. }) => {
60776069
let attr = attr.as_str();
6078-
self.check_forbidden_name(attr, NameUsage::Store)?;
60796070
self.compile_expression(value)?;
60806071
emit!(self, Instruction::Copy { index: 1_u32 });
60816072
let idx = self.name(attr);
@@ -6903,12 +6894,6 @@ impl Compiler {
69036894
let (size, unpack) = self.gather_elements(additional_positional, &arguments.args)?;
69046895
let has_double_star = arguments.keywords.iter().any(|k| k.arg.is_none());
69056896

6906-
for keyword in &arguments.keywords {
6907-
if let Some(name) = &keyword.arg {
6908-
self.check_forbidden_name(name.as_str(), NameUsage::Store)?;
6909-
}
6910-
}
6911-
69126897
if unpack || has_double_star {
69136898
// Create a tuple with positional args:
69146899
if unpack {
@@ -7511,6 +7496,19 @@ impl Compiler {
75117496
self.code_stack.last_mut().expect("no code on stack")
75127497
}
75137498

7499+
/// Enter a conditional block (if/for/while/match/try/with)
7500+
/// PEP 649: Track conditional annotation context
7501+
fn enter_conditional_block(&mut self) {
7502+
self.current_code_info().in_conditional_block += 1;
7503+
}
7504+
7505+
/// Leave a conditional block
7506+
fn leave_conditional_block(&mut self) {
7507+
let code_info = self.current_code_info();
7508+
debug_assert!(code_info.in_conditional_block > 0);
7509+
code_info.in_conditional_block -= 1;
7510+
}
7511+
75147512
/// Compile break or continue statement with proper fblock cleanup.
75157513
/// compiler_break, compiler_continue
75167514
/// This handles unwinding through With blocks and exception handlers.

crates/codegen/src/ir.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,14 @@ pub struct CodeInfo {
145145

146146
// Reference to the symbol table for this scope
147147
pub symbol_table_index: usize,
148+
149+
// PEP 649: Track nesting depth inside conditional blocks (if/for/while/etc.)
150+
// u_in_conditional_block
151+
pub in_conditional_block: u32,
152+
153+
// PEP 649: Next index for conditional annotation tracking
154+
// u_next_conditional_annotation_index
155+
pub next_conditional_annotation_index: u32,
148156
}
149157

150158
impl CodeInfo {
@@ -171,6 +179,8 @@ impl CodeInfo {
171179
in_inlined_comp: _,
172180
fblock: _,
173181
symbol_table_index: _,
182+
in_conditional_block: _,
183+
next_conditional_annotation_index: _,
174184
} = self;
175185

176186
let CodeUnitMetadata {

0 commit comments

Comments
 (0)