Parses a single parameter for the given function kind. Matches either the `param_no_default_star_annotation` or `param_no_default` rule in the [Python grammar] depending on whether star annotation is allowed or not. Use [`Parser::parse_parameter_with_default`] to allow parameter with default values. [Python grammar]: https://docs.python.org/3/reference/grammar.html
(
&mut self,
start: TextSize,
function_kind: FunctionKind,
allow_star_annotation: AllowStarAnnotation,
)
| 3152 | /// |
| 3153 | /// [Python grammar]: https://docs.python.org/3/reference/grammar.html |
| 3154 | fn parse_parameter( |
| 3155 | &mut self, |
| 3156 | start: TextSize, |
| 3157 | function_kind: FunctionKind, |
| 3158 | allow_star_annotation: AllowStarAnnotation, |
| 3159 | ) -> ast::Parameter { |
| 3160 | let name = self.parse_identifier(); |
| 3161 | |
| 3162 | // Annotations are only allowed for function definition. For lambda expression, |
| 3163 | // the `:` token would indicate its body. |
| 3164 | let annotation = match function_kind { |
| 3165 | FunctionKind::FunctionDef if self.eat(TokenKind::Colon) => { |
| 3166 | if self.at_expr() { |
| 3167 | let parsed_expr = match allow_star_annotation { |
| 3168 | AllowStarAnnotation::Yes => { |
| 3169 | // test_ok param_with_star_annotation |
| 3170 | // def foo(*args: *int | str): ... |
| 3171 | // def foo(*args: *(int or str)): ... |
| 3172 | |
| 3173 | // test_err param_with_invalid_star_annotation |
| 3174 | // def foo(*args: *): ... |
| 3175 | // def foo(*args: (*tuple[int])): ... |
| 3176 | // def foo(*args: *int or str): ... |
| 3177 | // def foo(*args: *yield x): ... |
| 3178 | // # def foo(*args: **int): ... |
| 3179 | let parsed_expr = self.parse_conditional_expression_or_higher_impl( |
| 3180 | ExpressionContext::starred_bitwise_or(), |
| 3181 | ); |
| 3182 | |
| 3183 | // test_ok param_with_star_annotation_py311 |
| 3184 | // # parse_options: {"target-version": "3.11"} |
| 3185 | // def foo(*args: *Ts): ... |
| 3186 | |
| 3187 | // test_ok param_with_star_annotation_py310 |
| 3188 | // # parse_options: {"target-version": "3.10"} |
| 3189 | // # regression tests for https://github.com/astral-sh/ruff/issues/16874 |
| 3190 | // # starred parameters are fine, just not the annotation |
| 3191 | // from typing import Annotated, Literal |
| 3192 | // def foo(*args: Ts): ... |
| 3193 | // def foo(*x: Literal["this should allow arbitrary strings"]): ... |
| 3194 | // def foo(*x: Annotated[str, "this should allow arbitrary strings"]): ... |
| 3195 | // def foo(*args: str, **kwds: int): ... |
| 3196 | // def union(*x: A | B): ... |
| 3197 | |
| 3198 | // test_err param_with_star_annotation_py310 |
| 3199 | // # parse_options: {"target-version": "3.10"} |
| 3200 | // def foo(*args: *Ts): ... |
| 3201 | if parsed_expr.is_starred_expr() { |
| 3202 | self.add_unsupported_syntax_error( |
| 3203 | UnsupportedSyntaxErrorKind::StarAnnotation, |
| 3204 | parsed_expr.range(), |
| 3205 | ); |
| 3206 | } |
| 3207 | |
| 3208 | parsed_expr |
| 3209 | } |
| 3210 | AllowStarAnnotation::No => { |
| 3211 | // test_ok param_with_annotation |
no test coverage detected