diff --git a/Cargo.lock b/Cargo.lock index f71ff7c8d..f79b0748a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1953,7 +1953,7 @@ dependencies = [ [[package]] name = "ruff_source_location" version = "0.0.0" -source = "git+https://github.com/RustPython/Parser.git?rev=69d27d924c877b6f2fa5dc75c9589ab505d5b3f1#69d27d924c877b6f2fa5dc75c9589ab505d5b3f1" +source = "git+https://github.com/RustPython/Parser.git?rev=704eb40108239a8faf9bd1d4217e8dad0ac7edb3#704eb40108239a8faf9bd1d4217e8dad0ac7edb3" dependencies = [ "memchr", "once_cell", @@ -1963,7 +1963,7 @@ dependencies = [ [[package]] name = "ruff_text_size" version = "0.0.0" -source = "git+https://github.com/RustPython/Parser.git?rev=69d27d924c877b6f2fa5dc75c9589ab505d5b3f1#69d27d924c877b6f2fa5dc75c9589ab505d5b3f1" +source = "git+https://github.com/RustPython/Parser.git?rev=704eb40108239a8faf9bd1d4217e8dad0ac7edb3#704eb40108239a8faf9bd1d4217e8dad0ac7edb3" [[package]] name = "rustc-hash" @@ -2021,7 +2021,7 @@ dependencies = [ [[package]] name = "rustpython-ast" version = "0.2.0" -source = "git+https://github.com/RustPython/Parser.git?rev=69d27d924c877b6f2fa5dc75c9589ab505d5b3f1#69d27d924c877b6f2fa5dc75c9589ab505d5b3f1" +source = "git+https://github.com/RustPython/Parser.git?rev=704eb40108239a8faf9bd1d4217e8dad0ac7edb3#704eb40108239a8faf9bd1d4217e8dad0ac7edb3" dependencies = [ "is-macro", "malachite-bigint", @@ -2133,7 +2133,7 @@ dependencies = [ [[package]] name = "rustpython-format" version = "0.2.0" -source = "git+https://github.com/RustPython/Parser.git?rev=69d27d924c877b6f2fa5dc75c9589ab505d5b3f1#69d27d924c877b6f2fa5dc75c9589ab505d5b3f1" +source = "git+https://github.com/RustPython/Parser.git?rev=704eb40108239a8faf9bd1d4217e8dad0ac7edb3#704eb40108239a8faf9bd1d4217e8dad0ac7edb3" dependencies = [ "bitflags 2.3.1", "itertools 0.10.5", @@ -2160,7 +2160,7 @@ dependencies = [ [[package]] name = "rustpython-literal" version = "0.2.0" -source = "git+https://github.com/RustPython/Parser.git?rev=69d27d924c877b6f2fa5dc75c9589ab505d5b3f1#69d27d924c877b6f2fa5dc75c9589ab505d5b3f1" +source = "git+https://github.com/RustPython/Parser.git?rev=704eb40108239a8faf9bd1d4217e8dad0ac7edb3#704eb40108239a8faf9bd1d4217e8dad0ac7edb3" dependencies = [ "hexf-parse", "is-macro", @@ -2172,7 +2172,7 @@ dependencies = [ [[package]] name = "rustpython-parser" version = "0.2.0" -source = "git+https://github.com/RustPython/Parser.git?rev=69d27d924c877b6f2fa5dc75c9589ab505d5b3f1#69d27d924c877b6f2fa5dc75c9589ab505d5b3f1" +source = "git+https://github.com/RustPython/Parser.git?rev=704eb40108239a8faf9bd1d4217e8dad0ac7edb3#704eb40108239a8faf9bd1d4217e8dad0ac7edb3" dependencies = [ "anyhow", "is-macro", @@ -2195,7 +2195,7 @@ dependencies = [ [[package]] name = "rustpython-parser-core" version = "0.2.0" -source = "git+https://github.com/RustPython/Parser.git?rev=69d27d924c877b6f2fa5dc75c9589ab505d5b3f1#69d27d924c877b6f2fa5dc75c9589ab505d5b3f1" +source = "git+https://github.com/RustPython/Parser.git?rev=704eb40108239a8faf9bd1d4217e8dad0ac7edb3#704eb40108239a8faf9bd1d4217e8dad0ac7edb3" dependencies = [ "is-macro", "memchr", diff --git a/Cargo.toml b/Cargo.toml index 554887958..8fd494a67 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,11 +29,11 @@ rustpython-pylib = { path = "pylib" } rustpython-stdlib = { path = "stdlib" } rustpython-doc = { git = "https://github.com/RustPython/__doc__", branch = "main" } -rustpython-literal = { git = "https://github.com/RustPython/Parser.git", rev = "69d27d924c877b6f2fa5dc75c9589ab505d5b3f1" } -rustpython-parser-core = { git = "https://github.com/RustPython/Parser.git", rev = "69d27d924c877b6f2fa5dc75c9589ab505d5b3f1" } -rustpython-parser = { git = "https://github.com/RustPython/Parser.git", rev = "69d27d924c877b6f2fa5dc75c9589ab505d5b3f1" } -rustpython-ast = { git = "https://github.com/RustPython/Parser.git", rev = "69d27d924c877b6f2fa5dc75c9589ab505d5b3f1" } -rustpython-format = { git = "https://github.com/RustPython/Parser.git", rev = "69d27d924c877b6f2fa5dc75c9589ab505d5b3f1" } +rustpython-literal = { git = "https://github.com/RustPython/Parser.git", rev = "704eb40108239a8faf9bd1d4217e8dad0ac7edb3" } +rustpython-parser-core = { git = "https://github.com/RustPython/Parser.git", rev = "704eb40108239a8faf9bd1d4217e8dad0ac7edb3" } +rustpython-parser = { git = "https://github.com/RustPython/Parser.git", rev = "704eb40108239a8faf9bd1d4217e8dad0ac7edb3" } +rustpython-ast = { git = "https://github.com/RustPython/Parser.git", rev = "704eb40108239a8faf9bd1d4217e8dad0ac7edb3" } +rustpython-format = { git = "https://github.com/RustPython/Parser.git", rev = "704eb40108239a8faf9bd1d4217e8dad0ac7edb3" } # rustpython-literal = { path = "../RustPython-parser/literal" } # rustpython-parser-core = { path = "../RustPython-parser/core" } # rustpython-parser = { path = "../RustPython-parser/parser" } diff --git a/compiler/codegen/src/compile.rs b/compiler/codegen/src/compile.rs index cc4d82ec8..359ecd860 100644 --- a/compiler/codegen/src/compile.rs +++ b/compiler/codegen/src/compile.rs @@ -888,6 +888,7 @@ impl Compiler { Stmt::Pass(_) => { // No need to emit any code here :) } + Stmt::TypeAlias(_) => {} } Ok(()) } diff --git a/compiler/codegen/src/symboltable.rs b/compiler/codegen/src/symboltable.rs index a868a6ffb..e09f0c4aa 100644 --- a/compiler/codegen/src/symboltable.rs +++ b/compiler/codegen/src/symboltable.rs @@ -686,6 +686,7 @@ impl SymbolTableBuilder { bases, keywords, decorator_list, + type_params: _, range, }) => { self.enter_scope(name.as_str(), SymbolTableType::Class, range.start.row.get()); @@ -863,6 +864,7 @@ impl SymbolTableBuilder { self.scan_expression(expression, ExpressionContext::Load)?; } } + Stmt::TypeAlias(StmtTypeAlias { .. }) => {} } Ok(()) } diff --git a/vm/src/stdlib/ast/gen.rs b/vm/src/stdlib/ast/gen.rs index d053e41e3..d3969b902 100644 --- a/vm/src/stdlib/ast/gen.rs +++ b/vm/src/stdlib/ast/gen.rs @@ -89,6 +89,7 @@ impl NodeStmtFunctionDef { ctx.new_str(ascii!("decorator_list")).into(), ctx.new_str(ascii!("returns")).into(), ctx.new_str(ascii!("type_comment")).into(), + ctx.new_str(ascii!("type_params")).into(), ]) .into(), ); @@ -119,6 +120,7 @@ impl NodeStmtAsyncFunctionDef { ctx.new_str(ascii!("decorator_list")).into(), ctx.new_str(ascii!("returns")).into(), ctx.new_str(ascii!("type_comment")).into(), + ctx.new_str(ascii!("type_params")).into(), ]) .into(), ); @@ -148,6 +150,7 @@ impl NodeStmtClassDef { ctx.new_str(ascii!("keywords")).into(), ctx.new_str(ascii!("body")).into(), ctx.new_str(ascii!("decorator_list")).into(), + ctx.new_str(ascii!("type_params")).into(), ]) .into(), ); @@ -236,6 +239,33 @@ impl NodeStmtAssign { ); } } +#[pyclass(module = "_ast", name = "TypeAlias", base = "NodeStmt")] +struct NodeStmtTypeAlias; +#[pyclass(flags(HAS_DICT, BASETYPE))] +impl NodeStmtTypeAlias { + #[extend_class] + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { + class.set_attr( + identifier!(ctx, _fields), + ctx.new_tuple(vec![ + ctx.new_str(ascii!("name")).into(), + ctx.new_str(ascii!("type_params")).into(), + ctx.new_str(ascii!("value")).into(), + ]) + .into(), + ); + class.set_attr( + identifier!(ctx, _attributes), + ctx.new_list(vec![ + ctx.new_str(ascii!("lineno")).into(), + ctx.new_str(ascii!("col_offset")).into(), + ctx.new_str(ascii!("end_lineno")).into(), + ctx.new_str(ascii!("end_col_offset")).into(), + ]) + .into(), + ); + } +} #[pyclass(module = "_ast", name = "AugAssign", base = "NodeStmt")] struct NodeStmtAugAssign; #[pyclass(flags(HAS_DICT, BASETYPE))] @@ -2214,6 +2244,82 @@ impl NodeTypeIgnoreTypeIgnore { class.set_attr(identifier!(ctx, _attributes), ctx.new_list(vec![]).into()); } } +#[pyclass(module = "_ast", name = "type_param", base = "NodeAst")] +struct NodeTypeParam; +#[pyclass(flags(HAS_DICT, BASETYPE))] +impl NodeTypeParam {} +#[pyclass(module = "_ast", name = "TypeVar", base = "NodeTypeParam")] +struct NodeTypeParamTypeVar; +#[pyclass(flags(HAS_DICT, BASETYPE))] +impl NodeTypeParamTypeVar { + #[extend_class] + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { + class.set_attr( + identifier!(ctx, _fields), + ctx.new_tuple(vec![ + ctx.new_str(ascii!("name")).into(), + ctx.new_str(ascii!("bound")).into(), + ]) + .into(), + ); + class.set_attr( + identifier!(ctx, _attributes), + ctx.new_list(vec![ + ctx.new_str(ascii!("lineno")).into(), + ctx.new_str(ascii!("col_offset")).into(), + ctx.new_str(ascii!("end_lineno")).into(), + ctx.new_str(ascii!("end_col_offset")).into(), + ]) + .into(), + ); + } +} +#[pyclass(module = "_ast", name = "ParamSpec", base = "NodeTypeParam")] +struct NodeTypeParamParamSpec; +#[pyclass(flags(HAS_DICT, BASETYPE))] +impl NodeTypeParamParamSpec { + #[extend_class] + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { + class.set_attr( + identifier!(ctx, _fields), + ctx.new_tuple(vec![ctx.new_str(ascii!("name")).into()]) + .into(), + ); + class.set_attr( + identifier!(ctx, _attributes), + ctx.new_list(vec![ + ctx.new_str(ascii!("lineno")).into(), + ctx.new_str(ascii!("col_offset")).into(), + ctx.new_str(ascii!("end_lineno")).into(), + ctx.new_str(ascii!("end_col_offset")).into(), + ]) + .into(), + ); + } +} +#[pyclass(module = "_ast", name = "TypeVarTuple", base = "NodeTypeParam")] +struct NodeTypeParamTypeVarTuple; +#[pyclass(flags(HAS_DICT, BASETYPE))] +impl NodeTypeParamTypeVarTuple { + #[extend_class] + fn extend_class_with_fields(ctx: &Context, class: &'static Py) { + class.set_attr( + identifier!(ctx, _fields), + ctx.new_tuple(vec![ctx.new_str(ascii!("name")).into()]) + .into(), + ); + class.set_attr( + identifier!(ctx, _attributes), + ctx.new_list(vec![ + ctx.new_str(ascii!("lineno")).into(), + ctx.new_str(ascii!("col_offset")).into(), + ctx.new_str(ascii!("end_lineno")).into(), + ctx.new_str(ascii!("end_col_offset")).into(), + ]) + .into(), + ); + } +} // sum impl Node for ast::located::Mod { @@ -2364,6 +2470,7 @@ impl Node for ast::located::Stmt { ast::located::Stmt::Return(cons) => cons.ast_to_object(vm), ast::located::Stmt::Delete(cons) => cons.ast_to_object(vm), ast::located::Stmt::Assign(cons) => cons.ast_to_object(vm), + ast::located::Stmt::TypeAlias(cons) => cons.ast_to_object(vm), ast::located::Stmt::AugAssign(cons) => cons.ast_to_object(vm), ast::located::Stmt::AnnAssign(cons) => cons.ast_to_object(vm), ast::located::Stmt::For(cons) => cons.ast_to_object(vm), @@ -2405,6 +2512,10 @@ impl Node for ast::located::Stmt { ast::located::Stmt::Delete(ast::located::StmtDelete::ast_from_object(_vm, _object)?) } else if _cls.is(NodeStmtAssign::static_type()) { ast::located::Stmt::Assign(ast::located::StmtAssign::ast_from_object(_vm, _object)?) + } else if _cls.is(NodeStmtTypeAlias::static_type()) { + ast::located::Stmt::TypeAlias(ast::located::StmtTypeAlias::ast_from_object( + _vm, _object, + )?) } else if _cls.is(NodeStmtAugAssign::static_type()) { ast::located::Stmt::AugAssign(ast::located::StmtAugAssign::ast_from_object( _vm, _object, @@ -2473,6 +2584,7 @@ impl Node for ast::located::StmtFunctionDef { decorator_list, returns, type_comment, + type_params, range: _range, } = self; let node = NodeAst @@ -2488,6 +2600,8 @@ impl Node for ast::located::StmtFunctionDef { .unwrap(); dict.set_item("type_comment", type_comment.ast_to_object(_vm), _vm) .unwrap(); + dict.set_item("type_params", type_params.ast_to_object(_vm), _vm) + .unwrap(); node_add_location(&dict, _range, _vm); node.into() } @@ -2515,6 +2629,10 @@ impl Node for ast::located::StmtFunctionDef { type_comment: get_node_field_opt(_vm, &_object, "type_comment")? .map(|obj| Node::ast_from_object(_vm, obj)) .transpose()?, + type_params: Node::ast_from_object( + _vm, + get_node_field(_vm, &_object, "type_params", "FunctionDef")?, + )?, range: range_from_object(_vm, _object, "FunctionDef")?, }) } @@ -2529,6 +2647,7 @@ impl Node for ast::located::StmtAsyncFunctionDef { decorator_list, returns, type_comment, + type_params, range: _range, } = self; let node = NodeAst @@ -2544,6 +2663,8 @@ impl Node for ast::located::StmtAsyncFunctionDef { .unwrap(); dict.set_item("type_comment", type_comment.ast_to_object(_vm), _vm) .unwrap(); + dict.set_item("type_params", type_params.ast_to_object(_vm), _vm) + .unwrap(); node_add_location(&dict, _range, _vm); node.into() } @@ -2571,6 +2692,10 @@ impl Node for ast::located::StmtAsyncFunctionDef { type_comment: get_node_field_opt(_vm, &_object, "type_comment")? .map(|obj| Node::ast_from_object(_vm, obj)) .transpose()?, + type_params: Node::ast_from_object( + _vm, + get_node_field(_vm, &_object, "type_params", "AsyncFunctionDef")?, + )?, range: range_from_object(_vm, _object, "AsyncFunctionDef")?, }) } @@ -2584,6 +2709,7 @@ impl Node for ast::located::StmtClassDef { keywords, body, decorator_list, + type_params, range: _range, } = self; let node = NodeAst @@ -2598,6 +2724,8 @@ impl Node for ast::located::StmtClassDef { dict.set_item("body", body.ast_to_object(_vm), _vm).unwrap(); dict.set_item("decorator_list", decorator_list.ast_to_object(_vm), _vm) .unwrap(); + dict.set_item("type_params", type_params.ast_to_object(_vm), _vm) + .unwrap(); node_add_location(&dict, _range, _vm); node.into() } @@ -2614,6 +2742,10 @@ impl Node for ast::located::StmtClassDef { _vm, get_node_field(_vm, &_object, "decorator_list", "ClassDef")?, )?, + type_params: Node::ast_from_object( + _vm, + get_node_field(_vm, &_object, "type_params", "ClassDef")?, + )?, range: range_from_object(_vm, _object, "ClassDef")?, }) } @@ -2706,6 +2838,42 @@ impl Node for ast::located::StmtAssign { } } // constructor +impl Node for ast::located::StmtTypeAlias { + fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { + let ast::located::StmtTypeAlias { + name, + type_params, + value, + range: _range, + } = self; + let node = NodeAst + .into_ref_with_type(_vm, NodeStmtTypeAlias::static_type().to_owned()) + .unwrap(); + let dict = node.as_object().dict().unwrap(); + dict.set_item("name", name.ast_to_object(_vm), _vm).unwrap(); + dict.set_item("type_params", type_params.ast_to_object(_vm), _vm) + .unwrap(); + dict.set_item("value", value.ast_to_object(_vm), _vm) + .unwrap(); + node_add_location(&dict, _range, _vm); + node.into() + } + fn ast_from_object(_vm: &VirtualMachine, _object: PyObjectRef) -> PyResult { + Ok(ast::located::StmtTypeAlias { + name: Node::ast_from_object(_vm, get_node_field(_vm, &_object, "name", "TypeAlias")?)?, + type_params: Node::ast_from_object( + _vm, + get_node_field(_vm, &_object, "type_params", "TypeAlias")?, + )?, + value: Node::ast_from_object( + _vm, + get_node_field(_vm, &_object, "value", "TypeAlias")?, + )?, + range: range_from_object(_vm, _object, "TypeAlias")?, + }) + } +} +// constructor impl Node for ast::located::StmtAugAssign { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { let ast::located::StmtAugAssign { @@ -5092,6 +5260,112 @@ impl Node for ast::located::TypeIgnoreTypeIgnore { }) } } +// sum +impl Node for ast::located::TypeParam { + fn ast_to_object(self, vm: &VirtualMachine) -> PyObjectRef { + match self { + ast::located::TypeParam::TypeVar(cons) => cons.ast_to_object(vm), + ast::located::TypeParam::ParamSpec(cons) => cons.ast_to_object(vm), + ast::located::TypeParam::TypeVarTuple(cons) => cons.ast_to_object(vm), + } + } + fn ast_from_object(_vm: &VirtualMachine, _object: PyObjectRef) -> PyResult { + let _cls = _object.class(); + Ok(if _cls.is(NodeTypeParamTypeVar::static_type()) { + ast::located::TypeParam::TypeVar(ast::located::TypeParamTypeVar::ast_from_object( + _vm, _object, + )?) + } else if _cls.is(NodeTypeParamParamSpec::static_type()) { + ast::located::TypeParam::ParamSpec(ast::located::TypeParamParamSpec::ast_from_object( + _vm, _object, + )?) + } else if _cls.is(NodeTypeParamTypeVarTuple::static_type()) { + ast::located::TypeParam::TypeVarTuple( + ast::located::TypeParamTypeVarTuple::ast_from_object(_vm, _object)?, + ) + } else { + return Err(_vm.new_type_error(format!( + "expected some sort of type_param, but got {}", + _object.repr(_vm)? + ))); + }) + } +} +// constructor +impl Node for ast::located::TypeParamTypeVar { + fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { + let ast::located::TypeParamTypeVar { + name, + bound, + range: _range, + } = self; + let node = NodeAst + .into_ref_with_type(_vm, NodeTypeParamTypeVar::static_type().to_owned()) + .unwrap(); + let dict = node.as_object().dict().unwrap(); + dict.set_item("name", name.ast_to_object(_vm), _vm).unwrap(); + dict.set_item("bound", bound.ast_to_object(_vm), _vm) + .unwrap(); + node_add_location(&dict, _range, _vm); + node.into() + } + fn ast_from_object(_vm: &VirtualMachine, _object: PyObjectRef) -> PyResult { + Ok(ast::located::TypeParamTypeVar { + name: Node::ast_from_object(_vm, get_node_field(_vm, &_object, "name", "TypeVar")?)?, + bound: get_node_field_opt(_vm, &_object, "bound")? + .map(|obj| Node::ast_from_object(_vm, obj)) + .transpose()?, + range: range_from_object(_vm, _object, "TypeVar")?, + }) + } +} +// constructor +impl Node for ast::located::TypeParamParamSpec { + fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { + let ast::located::TypeParamParamSpec { + name, + range: _range, + } = self; + let node = NodeAst + .into_ref_with_type(_vm, NodeTypeParamParamSpec::static_type().to_owned()) + .unwrap(); + let dict = node.as_object().dict().unwrap(); + dict.set_item("name", name.ast_to_object(_vm), _vm).unwrap(); + node_add_location(&dict, _range, _vm); + node.into() + } + fn ast_from_object(_vm: &VirtualMachine, _object: PyObjectRef) -> PyResult { + Ok(ast::located::TypeParamParamSpec { + name: Node::ast_from_object(_vm, get_node_field(_vm, &_object, "name", "ParamSpec")?)?, + range: range_from_object(_vm, _object, "ParamSpec")?, + }) + } +} +// constructor +impl Node for ast::located::TypeParamTypeVarTuple { + fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { + let ast::located::TypeParamTypeVarTuple { + name, + range: _range, + } = self; + let node = NodeAst + .into_ref_with_type(_vm, NodeTypeParamTypeVarTuple::static_type().to_owned()) + .unwrap(); + let dict = node.as_object().dict().unwrap(); + dict.set_item("name", name.ast_to_object(_vm), _vm).unwrap(); + node_add_location(&dict, _range, _vm); + node.into() + } + fn ast_from_object(_vm: &VirtualMachine, _object: PyObjectRef) -> PyResult { + Ok(ast::located::TypeParamTypeVarTuple { + name: Node::ast_from_object( + _vm, + get_node_field(_vm, &_object, "name", "TypeVarTuple")?, + )?, + range: range_from_object(_vm, _object, "TypeVarTuple")?, + }) + } +} pub fn extend_module_nodes(vm: &VirtualMachine, module: &Py) { extend_module!(vm, module, { @@ -5107,6 +5381,7 @@ pub fn extend_module_nodes(vm: &VirtualMachine, module: &Py) { "Return" => NodeStmtReturn::make_class(&vm.ctx), "Delete" => NodeStmtDelete::make_class(&vm.ctx), "Assign" => NodeStmtAssign::make_class(&vm.ctx), + "TypeAlias" => NodeStmtTypeAlias::make_class(&vm.ctx), "AugAssign" => NodeStmtAugAssign::make_class(&vm.ctx), "AnnAssign" => NodeStmtAnnAssign::make_class(&vm.ctx), "For" => NodeStmtFor::make_class(&vm.ctx), @@ -5213,5 +5488,9 @@ pub fn extend_module_nodes(vm: &VirtualMachine, module: &Py) { "MatchOr" => NodePatternMatchOr::make_class(&vm.ctx), "type_ignore" => NodeTypeIgnore::make_class(&vm.ctx), "TypeIgnore" => NodeTypeIgnoreTypeIgnore::make_class(&vm.ctx), + "type_param" => NodeTypeParam::make_class(&vm.ctx), + "TypeVar" => NodeTypeParamTypeVar::make_class(&vm.ctx), + "ParamSpec" => NodeTypeParamParamSpec::make_class(&vm.ctx), + "TypeVarTuple" => NodeTypeParamTypeVarTuple::make_class(&vm.ctx), }) }