Parses a parameter list for the given function kind. See:
(&mut self, function_kind: FunctionKind)
| 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): ... |
no test coverage detected