MCPcopy Create free account
hub / github.com/astral-sh/ruff / parse_parameters

Method parse_parameters

crates/ruff_python_parser/src/parser/statement.rs:3298–3572  ·  view source on GitHub ↗

Parses a parameter list for the given function kind. See:

(&mut self, function_kind: FunctionKind)

Source from the content-addressed store, hash-verified

3296 ///
3297 /// See: <https://docs.python.org/3/reference/compound_stmts.html#grammar-token-python-grammar-parameter_list>
3298 pub(super) fn parse_parameters(&mut self, function_kind: FunctionKind) -> ast::Parameters {
3299 let start = self.node_start();
3300
3301 if matches!(function_kind, FunctionKind::FunctionDef) {
3302 self.expect(TokenKind::Lpar);
3303 }
3304
3305 // TODO(dhruvmanila): This has the same problem as `parse_match_pattern_mapping`
3306 // has where if there are multiple kwarg or vararg, the last one will win and
3307 // the parser will drop the previous ones. Another thing is the vararg and kwarg
3308 // uses `Parameter` (not `ParameterWithDefault`) which means that the parser cannot
3309 // recover well from `*args=(1, 2)`.
3310 let mut parameters = ast::Parameters::default();
3311
3312 let mut seen_default_param = false; // `a=10`
3313 let mut seen_positional_only_separator = false; // `/`
3314 let mut seen_keyword_only_separator = false; // `*`
3315 let mut seen_keyword_only_param_after_separator = false;
3316
3317 // Range of the keyword only separator if it's the last parameter in the list.
3318 let mut last_keyword_only_separator_range = None;
3319
3320 self.parse_comma_separated_list(RecoveryContextKind::Parameters(function_kind), |parser| {
3321 let param_start = parser.node_start();
3322
3323 if parameters.kwarg.is_some() {
3324 // test_err params_follows_var_keyword_param
3325 // def foo(**kwargs, a, /, b=10, *, *args): ...
3326 parser.add_error(
3327 ParseErrorType::ParamAfterVarKeywordParam,
3328 parser.current_token_range(),
3329 );
3330 }
3331
3332 match parser.current_token_kind() {
3333 TokenKind::Star => {
3334 let star_range = parser.current_token_range();
3335 parser.bump(TokenKind::Star);
3336
3337 if parser.at_name_or_soft_keyword() {
3338 let param = parser.parse_parameter(param_start, function_kind, AllowStarAnnotation::Yes);
3339 let param_star_range = parser.node_range(star_range.start());
3340
3341 if parser.at(TokenKind::Equal) {
3342 // test_err params_var_positional_with_default
3343 // def foo(a, *args=(1, 2)): ...
3344 parser.add_error(
3345 ParseErrorType::VarParameterWithDefault,
3346 parser.current_token_range(),
3347 );
3348 }
3349
3350 if seen_keyword_only_separator || parameters.vararg.is_some() {
3351 // test_err params_multiple_varargs
3352 // def foo(a, *, *args, b): ...
3353 // # def foo(a, *, b, c, *args): ...
3354 // def foo(a, *args1, *args2, b): ...
3355 // def foo(a, *args1, b, c, *args2): ...

Callers 2

parse_lambda_exprMethod · 0.80

Calls 15

node_startMethod · 0.80
expectMethod · 0.80
current_token_rangeMethod · 0.80
current_token_kindMethod · 0.80
parse_parameterMethod · 0.80
node_rangeMethod · 0.80
defaultFunction · 0.50
ParametersClass · 0.50

Tested by

no test coverage detected