fix unparse · RustPython/RustPython@0da5931 · GitHub
Skip to content

Commit 0da5931

Browse files
committed
fix unparse
1 parent 400696c commit 0da5931

5 files changed

Lines changed: 71 additions & 3 deletions

File tree

crates/codegen/src/unparse.rs

Lines changed: 16 additions & 1 deletion

crates/vm/src/stdlib/ast/expression.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,26 @@ impl Node for ast::ExprLambda {
327327
.into_ref_with_type(vm, pyast::NodeExprLambda::static_type().to_owned())
328328
.unwrap();
329329
let dict = node.as_object().dict().unwrap();
330-
dict.set_item("args", parameters.ast_to_object(vm, source_file), vm)
330+
// Lambda with no parameters should have an empty arguments object, not None
331+
let args = match parameters {
332+
Some(params) => params.ast_to_object(vm, source_file),
333+
None => {
334+
// Create an empty arguments object
335+
let args_node = NodeAst
336+
.into_ref_with_type(vm, pyast::NodeArguments::static_type().to_owned())
337+
.unwrap();
338+
let args_dict = args_node.as_object().dict().unwrap();
339+
args_dict.set_item("posonlyargs", vm.ctx.new_list(vec![]).into(), vm).unwrap();
340+
args_dict.set_item("args", vm.ctx.new_list(vec![]).into(), vm).unwrap();
341+
args_dict.set_item("vararg", vm.ctx.none(), vm).unwrap();
342+
args_dict.set_item("kwonlyargs", vm.ctx.new_list(vec![]).into(), vm).unwrap();
343+
args_dict.set_item("kw_defaults", vm.ctx.new_list(vec![]).into(), vm).unwrap();
344+
args_dict.set_item("kwarg", vm.ctx.none(), vm).unwrap();
345+
args_dict.set_item("defaults", vm.ctx.new_list(vec![]).into(), vm).unwrap();
346+
args_node.into()
347+
}
348+
};
349+
dict.set_item("args", args, vm)
331350
.unwrap();
332351
dict.set_item("body", body.ast_to_object(vm, source_file), vm)
333352
.unwrap();

crates/vm/src/stdlib/ast/other.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use rustpython_compiler_core::SourceFile;
33

44
impl Node for ast::ConversionFlag {
55
fn ast_to_object(self, vm: &VirtualMachine, _source_file: &SourceFile) -> PyObjectRef {
6-
vm.ctx.new_int(self as u8).into()
6+
vm.ctx.new_int(self as i8).into()
77
}
88

99
fn ast_from_object(

crates/vm/src/stdlib/ast/python.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,13 @@ pub(crate) mod _ast {
6565
if fields.len() == 1 { "" } else { "s" },
6666
)));
6767
}
68+
69+
// Track which fields were set
70+
let mut set_fields = std::collections::HashSet::new();
71+
6872
for (name, arg) in fields.iter().zip(args.args) {
6973
zelf.set_attr(name, arg, vm)?;
74+
set_fields.insert(name.as_str().to_string());
7075
}
7176
for (key, value) in args.kwargs {
7277
if let Some(pos) = fields.iter().position(|f| f.as_str() == key)
@@ -78,9 +83,31 @@ pub(crate) mod _ast {
7883
key
7984
)));
8085
}
86+
set_fields.insert(key.clone());
8187
zelf.set_attr(vm.ctx.intern_str(key), value, vm)?;
8288
}
8389

90+
// Set default values for fields that weren't provided
91+
let class_name = &*zelf.class().name();
92+
if class_name == "Module" && !set_fields.contains("type_ignores") {
93+
zelf.set_attr("type_ignores", vm.ctx.new_list(vec![]), vm)?;
94+
}
95+
if class_name == "ImportFrom" && !set_fields.contains("level") {
96+
zelf.set_attr("level", vm.ctx.new_int(0), vm)?;
97+
}
98+
if class_name == "alias" && !set_fields.contains("asname") {
99+
zelf.set_attr("asname", vm.ctx.none(), vm)?;
100+
}
101+
// Set type_comment to None for nodes that support it
102+
if !set_fields.contains("type_comment") {
103+
match class_name {
104+
"FunctionDef" | "AsyncFunctionDef" | "For" | "AsyncFor" | "With" | "AsyncWith" | "arg" => {
105+
zelf.set_attr("type_comment", vm.ctx.none(), vm)?;
106+
}
107+
_ => {}
108+
}
109+
}
110+
84111
Ok(())
85112
}
86113

crates/vm/src/stdlib/builtins.rs

Lines changed: 7 additions & 0 deletions

0 commit comments

Comments
 (0)