-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Update _ast_unparse and fix unparse, type_comments #6961
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
400696c
0da5931
1876ac8
63bbb3c
69c19f7
ff49bfe
00cdb30
9e7faba
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Extract empty_arguments_object helper from expression.rs - Fix LIST_FIELDS ambiguity: "args" and "body" have different ASDL types per node (e.g. Lambda.args is `arguments`, not `expr*`; Lambda.body is `expr`, not `stmt*`) - Replace class name string comparison in compile() with fast_isinstance to accept AST subclasses
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -95,12 +95,11 @@ pub(crate) mod _ast { | |
| .is_some(); | ||
| if has_field_types { | ||
| // ASDL list fields (type*) default to empty list, | ||
| // optional fields (type?) default to None. | ||
| // optional/required fields default to None. | ||
| // Fields that are always list-typed regardless of node class. | ||
| const LIST_FIELDS: &[&str] = &[ | ||
| "args", | ||
| "argtypes", | ||
| "bases", | ||
| "body", | ||
| "cases", | ||
| "comparators", | ||
| "decorator_list", | ||
|
|
@@ -113,31 +112,49 @@ pub(crate) mod _ast { | |
| "items", | ||
| "keys", | ||
| "kw_defaults", | ||
| "kwd_attrs", | ||
| "kwd_patterns", | ||
| "keywords", | ||
| "kwonlyargs", | ||
| "names", | ||
| "orelse", | ||
| "ops", | ||
| "patterns", | ||
| "posonlyargs", | ||
| "targets", | ||
| "type_ignores", | ||
| "type_params", | ||
| "values", | ||
| ]; | ||
|
|
||
| let class_name = zelf.class().name().to_string(); | ||
|
|
||
| for field in &fields { | ||
| if !set_fields.contains(field.as_str()) { | ||
| let default: PyObjectRef = if LIST_FIELDS.contains(&field.as_str()) { | ||
| let field_name = field.as_str(); | ||
| // Some field names have different ASDL types depending on the node. | ||
| // For example, "args" is `expr*` in Call but `arguments` in Lambda. | ||
| // "body" and "orelse" are `stmt*` in most nodes but `expr` in IfExp. | ||
| let is_list_field = if field_name == "args" { | ||
| class_name == "Call" || class_name == "arguments" | ||
| } else if field_name == "body" || field_name == "orelse" { | ||
| !matches!( | ||
| class_name.as_str(), | ||
| "Lambda" | "Expression" | "IfExp" | ||
| ) | ||
| } else { | ||
| LIST_FIELDS.contains(&field_name) | ||
| }; | ||
|
|
||
| let default: PyObjectRef = if is_list_field { | ||
| vm.ctx.new_list(vec![]).into() | ||
| } else { | ||
| vm.ctx.none() | ||
| }; | ||
| zelf.set_attr(vm.ctx.intern_str(field.as_str()), default, vm)?; | ||
| zelf.set_attr(vm.ctx.intern_str(field_name), default, vm)?; | ||
| } | ||
|
Comment on lines
+129
to
+151
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: cd crates/vm && head -200 src/stdlib/ast/python.rs | tail -100Repository: RustPython/RustPython Length of output: 3868 🏁 Script executed: sed -n '100,160p' crates/vm/src/stdlib/ast/python.rsRepository: RustPython/RustPython Length of output: 2601 🏁 Script executed: # Search for fast_issubclass usage in the codebase to understand the pattern
rg "fast_issubclass" crates/vm/src/stdlib/ast/ -A 2 -B 2Repository: RustPython/RustPython Length of output: 47 🏁 Script executed: # Look for NodeExprCall, NodeArguments, NodeExprLambda types in the codebase
rg "NodeExprCall|NodeArguments|NodeExprLambda|NodeModExpression|NodeExprIfExp" crates/vm/src/stdlib/ast/Repository: RustPython/RustPython Length of output: 1907 🏁 Script executed: # Check what node types are available in the pyast module
fd "pyast" crates/vm/src/stdlib/ast/ && ls -la crates/vm/src/stdlib/ast/pyast* 2>/dev/null || find crates/vm/src/stdlib/ast -name "*pyast*" -type fRepository: RustPython/RustPython Length of output: 182 🏁 Script executed: rg "fast_issubclass" crates/vm --type rustRepository: RustPython/RustPython Length of output: 6337 🏁 Script executed: # Search for issubclass patterns in the codebase
rg "\.is\(.*::static_type" crates/vm/src/stdlib/ast/ -A 1 -B 1Repository: RustPython/RustPython Length of output: 25507 🏁 Script executed: # Check what methods are available on PyClass for subclass checking
rg "impl.*PyClass" crates/vm/src/builtins/ -A 10 | head -50Repository: RustPython/RustPython Length of output: 3469 🏁 Script executed: # Look for subclass checking methods in the PyClass implementation
fd "class.rs" crates/vm/src && head -100 "$(fd 'class.rs' crates/vm/src)"Repository: RustPython/RustPython Length of output: 3451 🏁 Script executed: # Search for how .is() method is used on PyClass
rg "\.is\(" crates/vm/src/stdlib/ast/python.rs -B 2 -A 2Repository: RustPython/RustPython Length of output: 47 Use subclass checking instead of exact class name matching for field defaults. When 🛠️ Suggested fix- let class_name = zelf.class().name().to_string();
+ let class = zelf.class();
+ let class_name = class.name().to_string();
...
- let is_list_field = if field_name == "args" {
- class_name == "Call" || class_name == "arguments"
- } else if field_name == "body" || field_name == "orelse" {
- !matches!(
- class_name.as_str(),
- "Lambda" | "Expression" | "IfExp"
- )
- } else {
- LIST_FIELDS.contains(&field_name)
- };
+ let is_list_field = if field_name == "args" {
+ class.fast_issubclass(super::pyast::NodeExprCall::static_type())
+ || class.fast_issubclass(super::pyast::NodeArguments::static_type())
+ } else if field_name == "body" || field_name == "orelse" {
+ !(class.fast_issubclass(super::pyast::NodeExprLambda::static_type())
+ || class.fast_issubclass(super::pyast::NodeModExpression::static_type())
+ || class.fast_issubclass(super::pyast::NodeExprIfExp::static_type()))
+ } else {
+ LIST_FIELDS.contains(&field_name)
+ };🤖 Prompt for AI Agents |
||
| } | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
|
|
||
| // Special defaults that are not None or empty list | ||
| let class_name = &*zelf.class().name(); | ||
| if class_name == "ImportFrom" && !set_fields.contains("level") { | ||
| zelf.set_attr("level", vm.ctx.new_int(0), vm)?; | ||
| } | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.