Skip to content

Commit 2f94a63

Browse files
authored
Add SymbolUsage::TypeParams (#5941)
1 parent 2c30e01 commit 2f94a63

File tree

4 files changed

+28
-9
lines changed

4 files changed

+28
-9
lines changed

Lib/test/test_typing.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3888,8 +3888,6 @@ def test_pep695_generic_class_with_future_annotations(self):
38883888
# should not have changed as a result of the get_type_hints() calls!
38893889
self.assertEqual(ann_module695.__dict__, original_globals)
38903890

3891-
# TODO: RUSTPYTHON
3892-
@unittest.expectedFailure
38933891
def test_pep695_generic_class_with_future_annotations_and_local_shadowing(self):
38943892
hints_for_B = get_type_hints(ann_module695.B)
38953893
self.assertEqual(hints_for_B, {"x": int, "y": str, "z": bytes})
@@ -3935,8 +3933,6 @@ def test_pep_695_generic_method_with_future_annotations_name_clash_with_global_v
39353933
set(ann_module695.D.generic_method_2.__type_params__)
39363934
)
39373935

3938-
# TODO: RUSTPYTHON
3939-
@unittest.expectedFailure
39403936
def test_pep_695_generics_with_future_annotations_nested_in_function(self):
39413937
results = ann_module695.nested()
39423938

compiler/codegen/src/compile.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -638,7 +638,11 @@ impl Compiler<'_> {
638638
cache = &mut info.cellvar_cache;
639639
NameOpType::Deref
640640
} // TODO: is this right?
641-
// SymbolScope::Unknown => NameOpType::Global,
641+
SymbolScope::TypeParams => {
642+
// Type parameters are always cell variables
643+
cache = &mut info.cellvar_cache;
644+
NameOpType::Deref
645+
} // SymbolScope::Unknown => NameOpType::Global,
642646
};
643647

644648
if NameUsage::Load == usage && name == "__debug__" {
@@ -1630,6 +1634,7 @@ impl Compiler<'_> {
16301634
let vars = match symbol.scope {
16311635
SymbolScope::Free => &parent_code.freevar_cache,
16321636
SymbolScope::Cell => &parent_code.cellvar_cache,
1637+
SymbolScope::TypeParams => &parent_code.cellvar_cache,
16331638
_ if symbol.flags.contains(SymbolFlags::FREE_CLASS) => &parent_code.freevar_cache,
16341639
x => unreachable!(
16351640
"var {} in a {:?} should be free or cell but it's {:?}",

compiler/codegen/src/symboltable.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ pub enum SymbolScope {
113113
GlobalImplicit,
114114
Free,
115115
Cell,
116+
TypeParams,
116117
}
117118

118119
bitflags! {
@@ -359,6 +360,10 @@ impl SymbolTableAnalyzer {
359360
SymbolScope::Local | SymbolScope::Cell => {
360361
// all is well
361362
}
363+
SymbolScope::TypeParams => {
364+
// Type parameters are always cell variables in their scope
365+
symbol.scope = SymbolScope::Cell;
366+
}
362367
SymbolScope::Unknown => {
363368
// Try hard to figure out what the scope of this symbol is.
364369
let scope = if symbol.is_bound() {
@@ -557,6 +562,7 @@ enum SymbolUsage {
557562
AnnotationParameter,
558563
AssignedNamedExprInComprehension,
559564
Iter,
565+
TypeParam,
560566
}
561567

562568
struct SymbolTableBuilder<'src> {
@@ -1267,6 +1273,9 @@ impl SymbolTableBuilder<'_> {
12671273
}
12681274

12691275
fn scan_type_params(&mut self, type_params: &TypeParams) -> SymbolTableResult {
1276+
// Register .type_params as a type parameter (automatically becomes cell variable)
1277+
self.register_name(".type_params", SymbolUsage::TypeParam, type_params.range)?;
1278+
12701279
// First register all type parameters
12711280
for type_param in &type_params.type_params {
12721281
match type_param {
@@ -1276,7 +1285,7 @@ impl SymbolTableBuilder<'_> {
12761285
range: type_var_range,
12771286
..
12781287
}) => {
1279-
self.register_name(name.as_str(), SymbolUsage::Assigned, *type_var_range)?;
1288+
self.register_name(name.as_str(), SymbolUsage::TypeParam, *type_var_range)?;
12801289
if let Some(binding) = bound {
12811290
self.scan_expression(binding, ExpressionContext::Load)?;
12821291
}
@@ -1286,14 +1295,14 @@ impl SymbolTableBuilder<'_> {
12861295
range: param_spec_range,
12871296
..
12881297
}) => {
1289-
self.register_name(name, SymbolUsage::Assigned, *param_spec_range)?;
1298+
self.register_name(name, SymbolUsage::TypeParam, *param_spec_range)?;
12901299
}
12911300
TypeParam::TypeVarTuple(TypeParamTypeVarTuple {
12921301
name,
12931302
range: type_var_tuple_range,
12941303
..
12951304
}) => {
1296-
self.register_name(name, SymbolUsage::Assigned, *type_var_tuple_range)?;
1305+
self.register_name(name, SymbolUsage::TypeParam, *type_var_tuple_range)?;
12971306
}
12981307
}
12991308
}
@@ -1544,6 +1553,11 @@ impl SymbolTableBuilder<'_> {
15441553
SymbolUsage::Iter => {
15451554
flags.insert(SymbolFlags::ITER);
15461555
}
1556+
SymbolUsage::TypeParam => {
1557+
// Type parameters are always cell variables in their scope
1558+
symbol.scope = SymbolScope::Cell;
1559+
flags.insert(SymbolFlags::ASSIGNED);
1560+
}
15471561
}
15481562

15491563
// and even more checking

vm/src/frame.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -596,7 +596,11 @@ impl ExecutingFrame<'_> {
596596
}
597597
bytecode::Instruction::LoadClassDeref(i) => {
598598
let i = i.get(arg) as usize;
599-
let name = self.code.freevars[i - self.code.cellvars.len()];
599+
let name = if i < self.code.cellvars.len() {
600+
self.code.cellvars[i]
601+
} else {
602+
self.code.freevars[i - self.code.cellvars.len()]
603+
};
600604
let value = self.locals.mapping().subscript(name, vm).ok();
601605
self.push_value(match value {
602606
Some(v) => v,

0 commit comments

Comments
 (0)