diff --git a/compiler/codegen/src/compile.rs b/compiler/codegen/src/compile.rs index b75e977b5de..bcb67ca0f53 100644 --- a/compiler/codegen/src/compile.rs +++ b/compiler/codegen/src/compile.rs @@ -1095,8 +1095,27 @@ impl Compiler { self.store_name(name.as_ref())?; } } - located_ast::TypeParam::ParamSpec(_) => todo!(), - located_ast::TypeParam::TypeVarTuple(_) => todo!(), + located_ast::TypeParam::ParamSpec(located_ast::TypeParamParamSpec { + name, .. + }) => { + self.emit_load_const(ConstantData::Str { + value: name.to_string(), + }); + emit!(self, Instruction::ParamSpec); + emit!(self, Instruction::Duplicate); + self.store_name(name.as_ref())?; + } + located_ast::TypeParam::TypeVarTuple(located_ast::TypeParamTypeVarTuple { + name, + .. + }) => { + self.emit_load_const(ConstantData::Str { + value: name.to_string(), + }); + emit!(self, Instruction::TypeVarTuple); + emit!(self, Instruction::Duplicate); + self.store_name(name.as_ref())?; + } }; } emit!( diff --git a/compiler/codegen/src/symboltable.rs b/compiler/codegen/src/symboltable.rs index bbb134facf9..80c6e389fcf 100644 --- a/compiler/codegen/src/symboltable.rs +++ b/compiler/codegen/src/symboltable.rs @@ -1257,8 +1257,18 @@ impl SymbolTableBuilder { self.scan_expression(binding, ExpressionContext::Load)?; } } - ast::located::TypeParam::ParamSpec(_) => todo!(), - ast::located::TypeParam::TypeVarTuple(_) => todo!(), + ast::located::TypeParam::ParamSpec(ast::TypeParamParamSpec { + name, + range: param_spec_range, + }) => { + self.register_name(name, SymbolUsage::Assigned, param_spec_range.start)?; + } + ast::located::TypeParam::TypeVarTuple(ast::TypeParamTypeVarTuple { + name, + range: type_var_tuple_range, + }) => { + self.register_name(name, SymbolUsage::Assigned, type_var_tuple_range.start)?; + } } } Ok(()) diff --git a/compiler/core/src/bytecode.rs b/compiler/core/src/bytecode.rs index c8dbc637446..46839c26955 100644 --- a/compiler/core/src/bytecode.rs +++ b/compiler/core/src/bytecode.rs @@ -595,10 +595,12 @@ pub enum Instruction { TypeVarWithBound, TypeVarWithConstraint, TypeAlias, + TypeVarTuple, + ParamSpec, // If you add a new instruction here, be sure to keep LAST_INSTRUCTION updated } // This must be kept up to date to avoid marshaling errors -const LAST_INSTRUCTION: Instruction = Instruction::TypeAlias; +const LAST_INSTRUCTION: Instruction = Instruction::ParamSpec; const _: () = assert!(mem::size_of::() == 1); impl From for u8 { @@ -1291,6 +1293,8 @@ impl Instruction { TypeVarWithBound => -1, TypeVarWithConstraint => -1, TypeAlias => -2, + ParamSpec => 0, + TypeVarTuple => 0, } } @@ -1460,6 +1464,8 @@ impl Instruction { TypeVarWithBound => w!(TypeVarWithBound), TypeVarWithConstraint => w!(TypeVarWithConstraint), TypeAlias => w!(TypeAlias), + ParamSpec => w!(ParamSpec), + TypeVarTuple => w!(TypeVarTuple), } } } diff --git a/vm/src/frame.rs b/vm/src/frame.rs index 8fc7e171b3c..fac6da8df59 100644 --- a/vm/src/frame.rs +++ b/vm/src/frame.rs @@ -1202,6 +1202,23 @@ impl ExecutingFrame<'_> { self.push_value(type_alias.into_ref(&vm.ctx).into()); Ok(None) } + bytecode::Instruction::ParamSpec => { + let param_spec_name = self.pop_value(); + let param_spec: PyObjectRef = _typing::make_paramspec(param_spec_name.clone()) + .into_ref(&vm.ctx) + .into(); + self.push_value(param_spec); + Ok(None) + } + bytecode::Instruction::TypeVarTuple => { + let type_var_tuple_name = self.pop_value(); + let type_var_tuple: PyObjectRef = + _typing::make_typevartuple(type_var_tuple_name.clone()) + .into_ref(&vm.ctx) + .into(); + self.push_value(type_var_tuple); + Ok(None) + } } } diff --git a/vm/src/stdlib/typing.rs b/vm/src/stdlib/typing.rs index daa01803250..29ce516b148 100644 --- a/vm/src/stdlib/typing.rs +++ b/vm/src/stdlib/typing.rs @@ -75,18 +75,31 @@ pub(crate) mod _typing { #[pyclass(name = "ParamSpec")] #[derive(Debug, PyPayload)] #[allow(dead_code)] - struct ParamSpec {} + pub(crate) struct ParamSpec { + name: PyObjectRef, + } + #[pyclass(flags(BASETYPE))] impl ParamSpec {} + pub(crate) fn make_paramspec(name: PyObjectRef) -> ParamSpec { + ParamSpec { name } + } + #[pyattr] #[pyclass(name = "TypeVarTuple")] #[derive(Debug, PyPayload)] #[allow(dead_code)] - pub(crate) struct TypeVarTuple {} + pub(crate) struct TypeVarTuple { + name: PyObjectRef, + } #[pyclass(flags(BASETYPE))] impl TypeVarTuple {} + pub(crate) fn make_typevartuple(name: PyObjectRef) -> TypeVarTuple { + TypeVarTuple { name } + } + #[pyattr] #[pyclass(name = "ParamSpecArgs")] #[derive(Debug, PyPayload)]