mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-26 20:10:09 +00:00
[syntax-errors] Type parameter lists before Python 3.12 (#16479)
Summary -- Another simple one, just detect type parameter lists in functions and classes. Like pyright, we don't emit a second diagnostic for `type` alias statements, which were also introduced in 3.12. Test Plan -- Inline tests.
This commit is contained in:
parent
d94a78a134
commit
81bcdcebd3
10 changed files with 557 additions and 0 deletions
|
@ -0,0 +1,3 @@
|
||||||
|
# parse_options: {"target-version": "3.11"}
|
||||||
|
class Foo[S: (str, bytes), T: float, *Ts, **P]: ...
|
||||||
|
class Foo[]: ...
|
|
@ -0,0 +1,3 @@
|
||||||
|
# parse_options: {"target-version": "3.11"}
|
||||||
|
def foo[T](): ...
|
||||||
|
def foo[](): ...
|
|
@ -0,0 +1,2 @@
|
||||||
|
# parse_options: {"target-version": "3.12"}
|
||||||
|
class Foo[S: (str, bytes), T: float, *Ts, **P]: ...
|
|
@ -0,0 +1,2 @@
|
||||||
|
# parse_options: {"target-version": "3.12"}
|
||||||
|
def foo[T](): ...
|
|
@ -449,6 +449,34 @@ pub enum UnsupportedSyntaxErrorKind {
|
||||||
Match,
|
Match,
|
||||||
Walrus,
|
Walrus,
|
||||||
ExceptStar,
|
ExceptStar,
|
||||||
|
/// Represents the use of a [type parameter list] before Python 3.12.
|
||||||
|
///
|
||||||
|
/// ## Examples
|
||||||
|
///
|
||||||
|
/// Before Python 3.12, generic parameters had to be declared separately using a class like
|
||||||
|
/// [`typing.TypeVar`], which could then be used in a function or class definition:
|
||||||
|
///
|
||||||
|
/// ```python
|
||||||
|
/// from typing import Generic, TypeVar
|
||||||
|
///
|
||||||
|
/// T = TypeVar("T")
|
||||||
|
///
|
||||||
|
/// def f(t: T): ...
|
||||||
|
/// class C(Generic[T]): ...
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// [PEP 695], included in Python 3.12, introduced the new type parameter syntax, which allows
|
||||||
|
/// these to be written more compactly and without a separate type variable:
|
||||||
|
///
|
||||||
|
/// ```python
|
||||||
|
/// def f[T](t: T): ...
|
||||||
|
/// class C[T]: ...
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// [type parameter list]: https://docs.python.org/3/reference/compound_stmts.html#type-parameter-lists
|
||||||
|
/// [PEP 695]: https://peps.python.org/pep-0695/
|
||||||
|
/// [`typing.TypeVar`]: https://docs.python.org/3/library/typing.html#typevar
|
||||||
|
TypeParameterList,
|
||||||
TypeAliasStatement,
|
TypeAliasStatement,
|
||||||
TypeParamDefault,
|
TypeParamDefault,
|
||||||
}
|
}
|
||||||
|
@ -459,6 +487,7 @@ impl Display for UnsupportedSyntaxError {
|
||||||
UnsupportedSyntaxErrorKind::Match => "Cannot use `match` statement",
|
UnsupportedSyntaxErrorKind::Match => "Cannot use `match` statement",
|
||||||
UnsupportedSyntaxErrorKind::Walrus => "Cannot use named assignment expression (`:=`)",
|
UnsupportedSyntaxErrorKind::Walrus => "Cannot use named assignment expression (`:=`)",
|
||||||
UnsupportedSyntaxErrorKind::ExceptStar => "Cannot use `except*`",
|
UnsupportedSyntaxErrorKind::ExceptStar => "Cannot use `except*`",
|
||||||
|
UnsupportedSyntaxErrorKind::TypeParameterList => "Cannot use type parameter lists",
|
||||||
UnsupportedSyntaxErrorKind::TypeAliasStatement => "Cannot use `type` alias statement",
|
UnsupportedSyntaxErrorKind::TypeAliasStatement => "Cannot use `type` alias statement",
|
||||||
UnsupportedSyntaxErrorKind::TypeParamDefault => {
|
UnsupportedSyntaxErrorKind::TypeParamDefault => {
|
||||||
"Cannot set default type for a type parameter"
|
"Cannot set default type for a type parameter"
|
||||||
|
@ -480,6 +509,7 @@ impl UnsupportedSyntaxErrorKind {
|
||||||
UnsupportedSyntaxErrorKind::Match => PythonVersion::PY310,
|
UnsupportedSyntaxErrorKind::Match => PythonVersion::PY310,
|
||||||
UnsupportedSyntaxErrorKind::Walrus => PythonVersion::PY38,
|
UnsupportedSyntaxErrorKind::Walrus => PythonVersion::PY38,
|
||||||
UnsupportedSyntaxErrorKind::ExceptStar => PythonVersion::PY311,
|
UnsupportedSyntaxErrorKind::ExceptStar => PythonVersion::PY311,
|
||||||
|
UnsupportedSyntaxErrorKind::TypeParameterList => PythonVersion::PY312,
|
||||||
UnsupportedSyntaxErrorKind::TypeAliasStatement => PythonVersion::PY312,
|
UnsupportedSyntaxErrorKind::TypeAliasStatement => PythonVersion::PY312,
|
||||||
UnsupportedSyntaxErrorKind::TypeParamDefault => PythonVersion::PY313,
|
UnsupportedSyntaxErrorKind::TypeParamDefault => PythonVersion::PY313,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1786,6 +1786,21 @@ impl<'src> Parser<'src> {
|
||||||
// x = 10
|
// x = 10
|
||||||
let type_params = self.try_parse_type_params();
|
let type_params = self.try_parse_type_params();
|
||||||
|
|
||||||
|
// test_ok function_type_params_py312
|
||||||
|
// # parse_options: {"target-version": "3.12"}
|
||||||
|
// def foo[T](): ...
|
||||||
|
|
||||||
|
// test_err function_type_params_py311
|
||||||
|
// # parse_options: {"target-version": "3.11"}
|
||||||
|
// def foo[T](): ...
|
||||||
|
// def foo[](): ...
|
||||||
|
if let Some(ast::TypeParams { range, .. }) = &type_params {
|
||||||
|
self.add_unsupported_syntax_error(
|
||||||
|
UnsupportedSyntaxErrorKind::TypeParameterList,
|
||||||
|
*range,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// test_ok function_def_parameter_range
|
// test_ok function_def_parameter_range
|
||||||
// def foo(
|
// def foo(
|
||||||
// first: int,
|
// first: int,
|
||||||
|
@ -1900,6 +1915,21 @@ impl<'src> Parser<'src> {
|
||||||
// x = 10
|
// x = 10
|
||||||
let type_params = self.try_parse_type_params();
|
let type_params = self.try_parse_type_params();
|
||||||
|
|
||||||
|
// test_ok class_type_params_py312
|
||||||
|
// # parse_options: {"target-version": "3.12"}
|
||||||
|
// class Foo[S: (str, bytes), T: float, *Ts, **P]: ...
|
||||||
|
|
||||||
|
// test_err class_type_params_py311
|
||||||
|
// # parse_options: {"target-version": "3.11"}
|
||||||
|
// class Foo[S: (str, bytes), T: float, *Ts, **P]: ...
|
||||||
|
// class Foo[]: ...
|
||||||
|
if let Some(ast::TypeParams { range, .. }) = &type_params {
|
||||||
|
self.add_unsupported_syntax_error(
|
||||||
|
UnsupportedSyntaxErrorKind::TypeParameterList,
|
||||||
|
*range,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// test_ok class_def_arguments
|
// test_ok class_def_arguments
|
||||||
// class Foo: ...
|
// class Foo: ...
|
||||||
// class Foo(): ...
|
// class Foo(): ...
|
||||||
|
|
|
@ -0,0 +1,174 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_python_parser/tests/fixtures.rs
|
||||||
|
input_file: crates/ruff_python_parser/resources/inline/err/class_type_params_py311.py
|
||||||
|
---
|
||||||
|
## AST
|
||||||
|
|
||||||
|
```
|
||||||
|
Module(
|
||||||
|
ModModule {
|
||||||
|
range: 0..113,
|
||||||
|
body: [
|
||||||
|
ClassDef(
|
||||||
|
StmtClassDef {
|
||||||
|
range: 44..95,
|
||||||
|
decorator_list: [],
|
||||||
|
name: Identifier {
|
||||||
|
id: Name("Foo"),
|
||||||
|
range: 50..53,
|
||||||
|
},
|
||||||
|
type_params: Some(
|
||||||
|
TypeParams {
|
||||||
|
range: 53..90,
|
||||||
|
type_params: [
|
||||||
|
TypeVar(
|
||||||
|
TypeParamTypeVar {
|
||||||
|
range: 54..69,
|
||||||
|
name: Identifier {
|
||||||
|
id: Name("S"),
|
||||||
|
range: 54..55,
|
||||||
|
},
|
||||||
|
bound: Some(
|
||||||
|
Tuple(
|
||||||
|
ExprTuple {
|
||||||
|
range: 57..69,
|
||||||
|
elts: [
|
||||||
|
Name(
|
||||||
|
ExprName {
|
||||||
|
range: 58..61,
|
||||||
|
id: Name("str"),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Name(
|
||||||
|
ExprName {
|
||||||
|
range: 63..68,
|
||||||
|
id: Name("bytes"),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
ctx: Load,
|
||||||
|
parenthesized: true,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
default: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
TypeVar(
|
||||||
|
TypeParamTypeVar {
|
||||||
|
range: 71..79,
|
||||||
|
name: Identifier {
|
||||||
|
id: Name("T"),
|
||||||
|
range: 71..72,
|
||||||
|
},
|
||||||
|
bound: Some(
|
||||||
|
Name(
|
||||||
|
ExprName {
|
||||||
|
range: 74..79,
|
||||||
|
id: Name("float"),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
default: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
TypeVarTuple(
|
||||||
|
TypeParamTypeVarTuple {
|
||||||
|
range: 81..84,
|
||||||
|
name: Identifier {
|
||||||
|
id: Name("Ts"),
|
||||||
|
range: 82..84,
|
||||||
|
},
|
||||||
|
default: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ParamSpec(
|
||||||
|
TypeParamParamSpec {
|
||||||
|
range: 86..89,
|
||||||
|
name: Identifier {
|
||||||
|
id: Name("P"),
|
||||||
|
range: 88..89,
|
||||||
|
},
|
||||||
|
default: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
arguments: None,
|
||||||
|
body: [
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 92..95,
|
||||||
|
value: EllipsisLiteral(
|
||||||
|
ExprEllipsisLiteral {
|
||||||
|
range: 92..95,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ClassDef(
|
||||||
|
StmtClassDef {
|
||||||
|
range: 96..112,
|
||||||
|
decorator_list: [],
|
||||||
|
name: Identifier {
|
||||||
|
id: Name("Foo"),
|
||||||
|
range: 102..105,
|
||||||
|
},
|
||||||
|
type_params: Some(
|
||||||
|
TypeParams {
|
||||||
|
range: 105..107,
|
||||||
|
type_params: [],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
arguments: None,
|
||||||
|
body: [
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 109..112,
|
||||||
|
value: EllipsisLiteral(
|
||||||
|
ExprEllipsisLiteral {
|
||||||
|
range: 109..112,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
```
|
||||||
|
## Errors
|
||||||
|
|
||||||
|
|
|
||||||
|
1 | # parse_options: {"target-version": "3.11"}
|
||||||
|
2 | class Foo[S: (str, bytes), T: float, *Ts, **P]: ...
|
||||||
|
3 | class Foo[]: ...
|
||||||
|
| ^ Syntax Error: Type parameter list cannot be empty
|
||||||
|
|
|
||||||
|
|
||||||
|
|
||||||
|
## Unsupported Syntax Errors
|
||||||
|
|
||||||
|
|
|
||||||
|
1 | # parse_options: {"target-version": "3.11"}
|
||||||
|
2 | class Foo[S: (str, bytes), T: float, *Ts, **P]: ...
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Syntax Error: Cannot use type parameter lists on Python 3.11 (syntax was added in Python 3.12)
|
||||||
|
3 | class Foo[]: ...
|
||||||
|
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
1 | # parse_options: {"target-version": "3.11"}
|
||||||
|
2 | class Foo[S: (str, bytes), T: float, *Ts, **P]: ...
|
||||||
|
3 | class Foo[]: ...
|
||||||
|
| ^^ Syntax Error: Cannot use type parameter lists on Python 3.11 (syntax was added in Python 3.12)
|
||||||
|
|
|
|
@ -0,0 +1,129 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_python_parser/tests/fixtures.rs
|
||||||
|
input_file: crates/ruff_python_parser/resources/inline/err/function_type_params_py311.py
|
||||||
|
---
|
||||||
|
## AST
|
||||||
|
|
||||||
|
```
|
||||||
|
Module(
|
||||||
|
ModModule {
|
||||||
|
range: 0..79,
|
||||||
|
body: [
|
||||||
|
FunctionDef(
|
||||||
|
StmtFunctionDef {
|
||||||
|
range: 44..61,
|
||||||
|
is_async: false,
|
||||||
|
decorator_list: [],
|
||||||
|
name: Identifier {
|
||||||
|
id: Name("foo"),
|
||||||
|
range: 48..51,
|
||||||
|
},
|
||||||
|
type_params: Some(
|
||||||
|
TypeParams {
|
||||||
|
range: 51..54,
|
||||||
|
type_params: [
|
||||||
|
TypeVar(
|
||||||
|
TypeParamTypeVar {
|
||||||
|
range: 52..53,
|
||||||
|
name: Identifier {
|
||||||
|
id: Name("T"),
|
||||||
|
range: 52..53,
|
||||||
|
},
|
||||||
|
bound: None,
|
||||||
|
default: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
parameters: Parameters {
|
||||||
|
range: 54..56,
|
||||||
|
posonlyargs: [],
|
||||||
|
args: [],
|
||||||
|
vararg: None,
|
||||||
|
kwonlyargs: [],
|
||||||
|
kwarg: None,
|
||||||
|
},
|
||||||
|
returns: None,
|
||||||
|
body: [
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 58..61,
|
||||||
|
value: EllipsisLiteral(
|
||||||
|
ExprEllipsisLiteral {
|
||||||
|
range: 58..61,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
FunctionDef(
|
||||||
|
StmtFunctionDef {
|
||||||
|
range: 62..78,
|
||||||
|
is_async: false,
|
||||||
|
decorator_list: [],
|
||||||
|
name: Identifier {
|
||||||
|
id: Name("foo"),
|
||||||
|
range: 66..69,
|
||||||
|
},
|
||||||
|
type_params: Some(
|
||||||
|
TypeParams {
|
||||||
|
range: 69..71,
|
||||||
|
type_params: [],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
parameters: Parameters {
|
||||||
|
range: 71..73,
|
||||||
|
posonlyargs: [],
|
||||||
|
args: [],
|
||||||
|
vararg: None,
|
||||||
|
kwonlyargs: [],
|
||||||
|
kwarg: None,
|
||||||
|
},
|
||||||
|
returns: None,
|
||||||
|
body: [
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 75..78,
|
||||||
|
value: EllipsisLiteral(
|
||||||
|
ExprEllipsisLiteral {
|
||||||
|
range: 75..78,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
```
|
||||||
|
## Errors
|
||||||
|
|
||||||
|
|
|
||||||
|
1 | # parse_options: {"target-version": "3.11"}
|
||||||
|
2 | def foo[T](): ...
|
||||||
|
3 | def foo[](): ...
|
||||||
|
| ^ Syntax Error: Type parameter list cannot be empty
|
||||||
|
|
|
||||||
|
|
||||||
|
|
||||||
|
## Unsupported Syntax Errors
|
||||||
|
|
||||||
|
|
|
||||||
|
1 | # parse_options: {"target-version": "3.11"}
|
||||||
|
2 | def foo[T](): ...
|
||||||
|
| ^^^ Syntax Error: Cannot use type parameter lists on Python 3.11 (syntax was added in Python 3.12)
|
||||||
|
3 | def foo[](): ...
|
||||||
|
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
1 | # parse_options: {"target-version": "3.11"}
|
||||||
|
2 | def foo[T](): ...
|
||||||
|
3 | def foo[](): ...
|
||||||
|
| ^^ Syntax Error: Cannot use type parameter lists on Python 3.11 (syntax was added in Python 3.12)
|
||||||
|
|
|
|
@ -0,0 +1,119 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_python_parser/tests/fixtures.rs
|
||||||
|
input_file: crates/ruff_python_parser/resources/inline/ok/class_type_params_py312.py
|
||||||
|
---
|
||||||
|
## AST
|
||||||
|
|
||||||
|
```
|
||||||
|
Module(
|
||||||
|
ModModule {
|
||||||
|
range: 0..96,
|
||||||
|
body: [
|
||||||
|
ClassDef(
|
||||||
|
StmtClassDef {
|
||||||
|
range: 44..95,
|
||||||
|
decorator_list: [],
|
||||||
|
name: Identifier {
|
||||||
|
id: Name("Foo"),
|
||||||
|
range: 50..53,
|
||||||
|
},
|
||||||
|
type_params: Some(
|
||||||
|
TypeParams {
|
||||||
|
range: 53..90,
|
||||||
|
type_params: [
|
||||||
|
TypeVar(
|
||||||
|
TypeParamTypeVar {
|
||||||
|
range: 54..69,
|
||||||
|
name: Identifier {
|
||||||
|
id: Name("S"),
|
||||||
|
range: 54..55,
|
||||||
|
},
|
||||||
|
bound: Some(
|
||||||
|
Tuple(
|
||||||
|
ExprTuple {
|
||||||
|
range: 57..69,
|
||||||
|
elts: [
|
||||||
|
Name(
|
||||||
|
ExprName {
|
||||||
|
range: 58..61,
|
||||||
|
id: Name("str"),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Name(
|
||||||
|
ExprName {
|
||||||
|
range: 63..68,
|
||||||
|
id: Name("bytes"),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
ctx: Load,
|
||||||
|
parenthesized: true,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
default: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
TypeVar(
|
||||||
|
TypeParamTypeVar {
|
||||||
|
range: 71..79,
|
||||||
|
name: Identifier {
|
||||||
|
id: Name("T"),
|
||||||
|
range: 71..72,
|
||||||
|
},
|
||||||
|
bound: Some(
|
||||||
|
Name(
|
||||||
|
ExprName {
|
||||||
|
range: 74..79,
|
||||||
|
id: Name("float"),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
default: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
TypeVarTuple(
|
||||||
|
TypeParamTypeVarTuple {
|
||||||
|
range: 81..84,
|
||||||
|
name: Identifier {
|
||||||
|
id: Name("Ts"),
|
||||||
|
range: 82..84,
|
||||||
|
},
|
||||||
|
default: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ParamSpec(
|
||||||
|
TypeParamParamSpec {
|
||||||
|
range: 86..89,
|
||||||
|
name: Identifier {
|
||||||
|
id: Name("P"),
|
||||||
|
range: 88..89,
|
||||||
|
},
|
||||||
|
default: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
arguments: None,
|
||||||
|
body: [
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 92..95,
|
||||||
|
value: EllipsisLiteral(
|
||||||
|
ExprEllipsisLiteral {
|
||||||
|
range: 92..95,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
```
|
|
@ -0,0 +1,65 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_python_parser/tests/fixtures.rs
|
||||||
|
input_file: crates/ruff_python_parser/resources/inline/ok/function_type_params_py312.py
|
||||||
|
---
|
||||||
|
## AST
|
||||||
|
|
||||||
|
```
|
||||||
|
Module(
|
||||||
|
ModModule {
|
||||||
|
range: 0..62,
|
||||||
|
body: [
|
||||||
|
FunctionDef(
|
||||||
|
StmtFunctionDef {
|
||||||
|
range: 44..61,
|
||||||
|
is_async: false,
|
||||||
|
decorator_list: [],
|
||||||
|
name: Identifier {
|
||||||
|
id: Name("foo"),
|
||||||
|
range: 48..51,
|
||||||
|
},
|
||||||
|
type_params: Some(
|
||||||
|
TypeParams {
|
||||||
|
range: 51..54,
|
||||||
|
type_params: [
|
||||||
|
TypeVar(
|
||||||
|
TypeParamTypeVar {
|
||||||
|
range: 52..53,
|
||||||
|
name: Identifier {
|
||||||
|
id: Name("T"),
|
||||||
|
range: 52..53,
|
||||||
|
},
|
||||||
|
bound: None,
|
||||||
|
default: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
parameters: Parameters {
|
||||||
|
range: 54..56,
|
||||||
|
posonlyargs: [],
|
||||||
|
args: [],
|
||||||
|
vararg: None,
|
||||||
|
kwonlyargs: [],
|
||||||
|
kwarg: None,
|
||||||
|
},
|
||||||
|
returns: None,
|
||||||
|
body: [
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 58..61,
|
||||||
|
value: EllipsisLiteral(
|
||||||
|
ExprEllipsisLiteral {
|
||||||
|
range: 58..61,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
```
|
Loading…
Add table
Add a link
Reference in a new issue