ast: match CPython argument validation order (#8414) · RustPython/RustPython@55b3d68 · GitHub
Skip to content

Commit 55b3d68

Browse files
authored
ast: match CPython argument validation order (#8414)
Validate parameter annotations while converting ast.arguments, before merging positional and keyword-only defaults. This gives invalid annotation contexts precedence over default-list shape errors, as in CPython. Merge positional defaults before keyword-only defaults so an excess positional-default error also takes precedence over a keyword-only default length mismatch. Remove the expected-failure markers from the FunctionDef and Lambda AST validator tests that now pass. Assisted-by: Codex:gpt-5.6-sol
1 parent 87de0dd commit 55b3d68

3 files changed

Lines changed: 37 additions & 4 deletions

File tree

Lib/test/test_ast/test_ast.py

Lines changed: 0 additions & 2 deletions

crates/vm/src/stdlib/_ast/parameter.rs

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,14 +88,23 @@ impl Node for ast::Parameters {
8888
"arguments",
8989
)?;
9090

91+
validate_parameter_annotations(
92+
vm,
93+
&posonlyargs,
94+
&args,
95+
vararg.as_deref(),
96+
&kwonlyargs,
97+
kwarg.as_deref(),
98+
)?;
99+
91100
let ParameterDefaults {
92101
runtime_defaults,
93102
defaults,
94103
_range: _,
95104
} = defaults;
96-
let kwonlyargs = merge_keyword_parameter_defaults(vm, kwonlyargs, kw_defaults)?;
97105
let (posonlyargs, args) =
98106
merge_positional_parameter_defaults(vm, posonlyargs, args, defaults)?;
107+
let kwonlyargs = merge_keyword_parameter_defaults(vm, kwonlyargs, kw_defaults)?;
99108

100109
Ok(Self {
101110
node_index: Default::default(),
@@ -114,6 +123,29 @@ impl Node for ast::Parameters {
114123
}
115124
}
116125

126+
fn validate_parameter_annotations(
127+
vm: &VirtualMachine,
128+
posonlyargs: &PositionalParameters,
129+
args: &PositionalParameters,
130+
vararg: Option<&ast::Parameter>,
131+
kwonlyargs: &KeywordParameters,
132+
kwarg: Option<&ast::Parameter>,
133+
) -> PyResult<()> {
134+
for parameter in posonlyargs.args.iter().chain(&args.args) {
135+
super::validate::validate_parameter_annotation(vm, parameter)?;
136+
}
137+
if let Some(parameter) = vararg {
138+
super::validate::validate_parameter_annotation(vm, parameter)?;
139+
}
140+
for parameter in &kwonlyargs.keywords {
141+
super::validate::validate_parameter_annotation(vm, parameter)?;
142+
}
143+
if let Some(parameter) = kwarg {
144+
super::validate::validate_parameter_annotation(vm, parameter)?;
145+
}
146+
Ok(())
147+
}
148+
117149
// product
118150
impl Node for ast::Parameter {
119151
fn ast_to_object(self, vm: &VirtualMachine, source_file: &SourceFile) -> PyObjectRef {

crates/vm/src/stdlib/_ast/validate.rs

Lines changed: 4 additions & 1 deletion

0 commit comments

Comments
 (0)