ruff/crates/ruff_python_parser/tests/snapshots/valid_syntax@statement__class.py.snap
Ibraheem Ahmed c9dff5c7d5
[ty] AST garbage collection (#18482)
## Summary

Garbage collect ASTs once we are done checking a given file. Queries
with a cross-file dependency on the AST will reparse the file on demand.
This reduces ty's peak memory usage by ~20-30%.

The primary change of this PR is adding a `node_index` field to every
AST node, that is assigned by the parser. `ParsedModule` can use this to
create a flat index of AST nodes any time the file is parsed (or
reparsed). This allows `AstNodeRef` to simply index into the current
instance of the `ParsedModule`, instead of storing a pointer directly.

The indices are somewhat hackily (using an atomic integer) assigned by
the `parsed_module` query instead of by the parser directly. Assigning
the indices in source-order in the (recursive) parser turns out to be
difficult, and collecting the nodes during semantic indexing is
impossible as `SemanticIndex` does not hold onto a specific
`ParsedModuleRef`, which the pointers in the flat AST are tied to. This
means that we have to do an extra AST traversal to assign and collect
the nodes into a flat index, but the small performance impact (~3% on
cold runs) seems worth it for the memory savings.

Part of https://github.com/astral-sh/ty/issues/214.
2025-06-13 08:40:11 -04:00

1450 lines
70 KiB
Text

---
source: crates/ruff_python_parser/tests/fixtures.rs
input_file: crates/ruff_python_parser/resources/valid/statement/class.py
---
## AST
```
Module(
ModModule {
node_index: AtomicNodeIndex(..),
range: 0..1023,
body: [
ClassDef(
StmtClassDef {
node_index: AtomicNodeIndex(..),
range: 0..19,
decorator_list: [],
name: Identifier {
id: Name("Test"),
range: 6..10,
node_index: AtomicNodeIndex(..),
},
type_params: None,
arguments: None,
body: [
Expr(
StmtExpr {
node_index: AtomicNodeIndex(..),
range: 16..19,
value: EllipsisLiteral(
ExprEllipsisLiteral {
node_index: AtomicNodeIndex(..),
range: 16..19,
},
),
},
),
],
},
),
ClassDef(
StmtClassDef {
node_index: AtomicNodeIndex(..),
range: 22..80,
decorator_list: [],
name: Identifier {
id: Name("Test"),
range: 28..32,
node_index: AtomicNodeIndex(..),
},
type_params: None,
arguments: Some(
Arguments {
range: 32..34,
node_index: AtomicNodeIndex(..),
args: [],
keywords: [],
},
),
body: [
FunctionDef(
StmtFunctionDef {
node_index: AtomicNodeIndex(..),
range: 44..80,
is_async: false,
decorator_list: [],
name: Identifier {
id: Name("__init__"),
range: 48..56,
node_index: AtomicNodeIndex(..),
},
type_params: None,
parameters: Parameters {
range: 56..62,
node_index: AtomicNodeIndex(
0,
),
posonlyargs: [],
args: [
ParameterWithDefault {
range: 57..61,
node_index: AtomicNodeIndex(..),
parameter: Parameter {
range: 57..61,
node_index: AtomicNodeIndex(..),
name: Identifier {
id: Name("self"),
range: 57..61,
node_index: AtomicNodeIndex(..),
},
annotation: None,
},
default: None,
},
],
vararg: None,
kwonlyargs: [],
kwarg: None,
},
returns: None,
body: [
Pass(
StmtPass {
node_index: AtomicNodeIndex(..),
range: 76..80,
},
),
],
},
),
],
},
),
ClassDef(
StmtClassDef {
node_index: AtomicNodeIndex(..),
range: 83..116,
decorator_list: [],
name: Identifier {
id: Name("Test"),
range: 89..93,
node_index: AtomicNodeIndex(..),
},
type_params: None,
arguments: Some(
Arguments {
range: 93..107,
node_index: AtomicNodeIndex(..),
args: [
Starred(
ExprStarred {
node_index: AtomicNodeIndex(..),
range: 99..101,
value: Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 100..101,
id: Name("A"),
ctx: Load,
},
),
ctx: Load,
},
),
],
keywords: [
Keyword {
range: 94..97,
node_index: AtomicNodeIndex(..),
arg: Some(
Identifier {
id: Name("a"),
range: 94..95,
node_index: AtomicNodeIndex(..),
},
),
value: NumberLiteral(
ExprNumberLiteral {
node_index: AtomicNodeIndex(..),
range: 96..97,
value: Int(
1,
),
},
),
},
Keyword {
range: 103..106,
node_index: AtomicNodeIndex(..),
arg: None,
value: Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 105..106,
id: Name("k"),
ctx: Load,
},
),
},
],
},
),
body: [
Expr(
StmtExpr {
node_index: AtomicNodeIndex(..),
range: 113..116,
value: EllipsisLiteral(
ExprEllipsisLiteral {
node_index: AtomicNodeIndex(..),
range: 113..116,
},
),
},
),
],
},
),
ClassDef(
StmtClassDef {
node_index: AtomicNodeIndex(..),
range: 119..168,
decorator_list: [],
name: Identifier {
id: Name("Test"),
range: 125..129,
node_index: AtomicNodeIndex(..),
},
type_params: None,
arguments: None,
body: [
FunctionDef(
StmtFunctionDef {
node_index: AtomicNodeIndex(..),
range: 135..168,
is_async: false,
decorator_list: [],
name: Identifier {
id: Name("method"),
range: 139..145,
node_index: AtomicNodeIndex(..),
},
type_params: None,
parameters: Parameters {
range: 145..147,
node_index: AtomicNodeIndex(
0,
),
posonlyargs: [],
args: [],
vararg: None,
kwonlyargs: [],
kwarg: None,
},
returns: None,
body: [
Assign(
StmtAssign {
node_index: AtomicNodeIndex(..),
range: 157..168,
targets: [
Tuple(
ExprTuple {
node_index: AtomicNodeIndex(..),
range: 157..161,
elts: [
Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 157..158,
id: Name("a"),
ctx: Store,
},
),
Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 160..161,
id: Name("b"),
ctx: Store,
},
),
],
ctx: Store,
parenthesized: false,
},
),
],
value: Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 164..168,
id: Name("data"),
ctx: Load,
},
),
},
),
],
},
),
],
},
),
ClassDef(
StmtClassDef {
node_index: AtomicNodeIndex(..),
range: 171..289,
decorator_list: [],
name: Identifier {
id: Name("Test"),
range: 177..181,
node_index: AtomicNodeIndex(..),
},
type_params: None,
arguments: Some(
Arguments {
range: 181..187,
node_index: AtomicNodeIndex(..),
args: [
Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 182..183,
id: Name("A"),
ctx: Load,
},
),
Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 185..186,
id: Name("B"),
ctx: Load,
},
),
],
keywords: [],
},
),
body: [
FunctionDef(
StmtFunctionDef {
node_index: AtomicNodeIndex(..),
range: 193..225,
is_async: false,
decorator_list: [],
name: Identifier {
id: Name("__init__"),
range: 197..205,
node_index: AtomicNodeIndex(..),
},
type_params: None,
parameters: Parameters {
range: 205..211,
node_index: AtomicNodeIndex(
0,
),
posonlyargs: [],
args: [
ParameterWithDefault {
range: 206..210,
node_index: AtomicNodeIndex(..),
parameter: Parameter {
range: 206..210,
node_index: AtomicNodeIndex(..),
name: Identifier {
id: Name("self"),
range: 206..210,
node_index: AtomicNodeIndex(..),
},
annotation: None,
},
default: None,
},
],
vararg: None,
kwonlyargs: [],
kwarg: None,
},
returns: None,
body: [
Pass(
StmtPass {
node_index: AtomicNodeIndex(..),
range: 221..225,
},
),
],
},
),
FunctionDef(
StmtFunctionDef {
node_index: AtomicNodeIndex(..),
range: 231..289,
is_async: false,
decorator_list: [],
name: Identifier {
id: Name("method_with_default"),
range: 235..254,
node_index: AtomicNodeIndex(..),
},
type_params: None,
parameters: Parameters {
range: 254..275,
node_index: AtomicNodeIndex(
0,
),
posonlyargs: [],
args: [
ParameterWithDefault {
range: 255..259,
node_index: AtomicNodeIndex(..),
parameter: Parameter {
range: 255..259,
node_index: AtomicNodeIndex(..),
name: Identifier {
id: Name("self"),
range: 255..259,
node_index: AtomicNodeIndex(..),
},
annotation: None,
},
default: None,
},
ParameterWithDefault {
range: 261..274,
node_index: AtomicNodeIndex(..),
parameter: Parameter {
range: 261..264,
node_index: AtomicNodeIndex(..),
name: Identifier {
id: Name("arg"),
range: 261..264,
node_index: AtomicNodeIndex(..),
},
annotation: None,
},
default: Some(
StringLiteral(
ExprStringLiteral {
node_index: AtomicNodeIndex(..),
range: 265..274,
value: StringLiteralValue {
inner: Single(
StringLiteral {
range: 265..274,
node_index: AtomicNodeIndex(..),
value: "default",
flags: StringLiteralFlags {
quote_style: Single,
prefix: Empty,
triple_quoted: false,
},
},
),
},
},
),
),
},
],
vararg: None,
kwonlyargs: [],
kwarg: None,
},
returns: None,
body: [
Pass(
StmtPass {
node_index: AtomicNodeIndex(..),
range: 285..289,
},
),
],
},
),
],
},
),
ClassDef(
StmtClassDef {
node_index: AtomicNodeIndex(..),
range: 331..351,
decorator_list: [],
name: Identifier {
id: Name("Test"),
range: 337..341,
node_index: AtomicNodeIndex(..),
},
type_params: Some(
TypeParams {
range: 341..344,
node_index: AtomicNodeIndex(..),
type_params: [
TypeVar(
TypeParamTypeVar {
range: 342..343,
node_index: AtomicNodeIndex(..),
name: Identifier {
id: Name("T"),
range: 342..343,
node_index: AtomicNodeIndex(..),
},
bound: None,
default: None,
},
),
],
},
),
arguments: Some(
Arguments {
range: 344..346,
node_index: AtomicNodeIndex(..),
args: [],
keywords: [],
},
),
body: [
Expr(
StmtExpr {
node_index: AtomicNodeIndex(..),
range: 348..351,
value: EllipsisLiteral(
ExprEllipsisLiteral {
node_index: AtomicNodeIndex(..),
range: 348..351,
},
),
},
),
],
},
),
ClassDef(
StmtClassDef {
node_index: AtomicNodeIndex(..),
range: 376..402,
decorator_list: [],
name: Identifier {
id: Name("Test"),
range: 382..386,
node_index: AtomicNodeIndex(..),
},
type_params: Some(
TypeParams {
range: 386..395,
node_index: AtomicNodeIndex(..),
type_params: [
TypeVar(
TypeParamTypeVar {
range: 387..394,
node_index: AtomicNodeIndex(..),
name: Identifier {
id: Name("T"),
range: 387..388,
node_index: AtomicNodeIndex(..),
},
bound: None,
default: Some(
Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 391..394,
id: Name("str"),
ctx: Load,
},
),
),
},
),
],
},
),
arguments: Some(
Arguments {
range: 395..397,
node_index: AtomicNodeIndex(..),
args: [],
keywords: [],
},
),
body: [
Expr(
StmtExpr {
node_index: AtomicNodeIndex(..),
range: 399..402,
value: EllipsisLiteral(
ExprEllipsisLiteral {
node_index: AtomicNodeIndex(..),
range: 399..402,
},
),
},
),
],
},
),
ClassDef(
StmtClassDef {
node_index: AtomicNodeIndex(..),
range: 425..450,
decorator_list: [],
name: Identifier {
id: Name("Test"),
range: 431..435,
node_index: AtomicNodeIndex(..),
},
type_params: Some(
TypeParams {
range: 435..443,
node_index: AtomicNodeIndex(..),
type_params: [
TypeVar(
TypeParamTypeVar {
range: 436..442,
node_index: AtomicNodeIndex(..),
name: Identifier {
id: Name("T"),
range: 436..437,
node_index: AtomicNodeIndex(..),
},
bound: Some(
Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 439..442,
id: Name("str"),
ctx: Load,
},
),
),
default: None,
},
),
],
},
),
arguments: Some(
Arguments {
range: 443..445,
node_index: AtomicNodeIndex(..),
args: [],
keywords: [],
},
),
body: [
Expr(
StmtExpr {
node_index: AtomicNodeIndex(..),
range: 447..450,
value: EllipsisLiteral(
ExprEllipsisLiteral {
node_index: AtomicNodeIndex(..),
range: 447..450,
},
),
},
),
],
},
),
ClassDef(
StmtClassDef {
node_index: AtomicNodeIndex(..),
range: 485..522,
decorator_list: [],
name: Identifier {
id: Name("Test"),
range: 491..495,
node_index: AtomicNodeIndex(..),
},
type_params: Some(
TypeParams {
range: 495..515,
node_index: AtomicNodeIndex(..),
type_params: [
TypeVar(
TypeParamTypeVar {
range: 496..514,
node_index: AtomicNodeIndex(..),
name: Identifier {
id: Name("T"),
range: 496..497,
node_index: AtomicNodeIndex(..),
},
bound: Some(
BinOp(
ExprBinOp {
node_index: AtomicNodeIndex(..),
range: 499..508,
left: Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 499..502,
id: Name("int"),
ctx: Load,
},
),
op: BitOr,
right: Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 505..508,
id: Name("str"),
ctx: Load,
},
),
},
),
),
default: Some(
Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 511..514,
id: Name("int"),
ctx: Load,
},
),
),
},
),
],
},
),
arguments: Some(
Arguments {
range: 515..517,
node_index: AtomicNodeIndex(..),
args: [],
keywords: [],
},
),
body: [
Expr(
StmtExpr {
node_index: AtomicNodeIndex(..),
range: 519..522,
value: EllipsisLiteral(
ExprEllipsisLiteral {
node_index: AtomicNodeIndex(..),
range: 519..522,
},
),
},
),
],
},
),
ClassDef(
StmtClassDef {
node_index: AtomicNodeIndex(..),
range: 551..585,
decorator_list: [],
name: Identifier {
id: Name("Test"),
range: 557..561,
node_index: AtomicNodeIndex(..),
},
type_params: Some(
TypeParams {
range: 561..578,
node_index: AtomicNodeIndex(..),
type_params: [
TypeVar(
TypeParamTypeVar {
range: 562..577,
node_index: AtomicNodeIndex(..),
name: Identifier {
id: Name("T"),
range: 562..563,
node_index: AtomicNodeIndex(..),
},
bound: Some(
Tuple(
ExprTuple {
node_index: AtomicNodeIndex(..),
range: 565..577,
elts: [
Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 566..569,
id: Name("str"),
ctx: Load,
},
),
Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 571..576,
id: Name("bytes"),
ctx: Load,
},
),
],
ctx: Load,
parenthesized: true,
},
),
),
default: None,
},
),
],
},
),
arguments: Some(
Arguments {
range: 578..580,
node_index: AtomicNodeIndex(..),
args: [],
keywords: [],
},
),
body: [
Expr(
StmtExpr {
node_index: AtomicNodeIndex(..),
range: 582..585,
value: EllipsisLiteral(
ExprEllipsisLiteral {
node_index: AtomicNodeIndex(..),
range: 582..585,
},
),
},
),
],
},
),
ClassDef(
StmtClassDef {
node_index: AtomicNodeIndex(..),
range: 606..629,
decorator_list: [],
name: Identifier {
id: Name("Test"),
range: 612..616,
node_index: AtomicNodeIndex(..),
},
type_params: Some(
TypeParams {
range: 616..622,
node_index: AtomicNodeIndex(..),
type_params: [
TypeVar(
TypeParamTypeVar {
range: 617..618,
node_index: AtomicNodeIndex(..),
name: Identifier {
id: Name("T"),
range: 617..618,
node_index: AtomicNodeIndex(..),
},
bound: None,
default: None,
},
),
TypeVar(
TypeParamTypeVar {
range: 620..621,
node_index: AtomicNodeIndex(..),
name: Identifier {
id: Name("U"),
range: 620..621,
node_index: AtomicNodeIndex(..),
},
bound: None,
default: None,
},
),
],
},
),
arguments: Some(
Arguments {
range: 622..624,
node_index: AtomicNodeIndex(..),
args: [],
keywords: [],
},
),
body: [
Expr(
StmtExpr {
node_index: AtomicNodeIndex(..),
range: 626..629,
value: EllipsisLiteral(
ExprEllipsisLiteral {
node_index: AtomicNodeIndex(..),
range: 626..629,
},
),
},
),
],
},
),
ClassDef(
StmtClassDef {
node_index: AtomicNodeIndex(..),
range: 648..672,
decorator_list: [],
name: Identifier {
id: Name("Test"),
range: 654..658,
node_index: AtomicNodeIndex(..),
},
type_params: Some(
TypeParams {
range: 658..665,
node_index: AtomicNodeIndex(..),
type_params: [
TypeVar(
TypeParamTypeVar {
range: 659..660,
node_index: AtomicNodeIndex(..),
name: Identifier {
id: Name("T"),
range: 659..660,
node_index: AtomicNodeIndex(..),
},
bound: None,
default: None,
},
),
TypeVar(
TypeParamTypeVar {
range: 662..663,
node_index: AtomicNodeIndex(..),
name: Identifier {
id: Name("U"),
range: 662..663,
node_index: AtomicNodeIndex(..),
},
bound: None,
default: None,
},
),
],
},
),
arguments: Some(
Arguments {
range: 665..667,
node_index: AtomicNodeIndex(..),
args: [],
keywords: [],
},
),
body: [
Expr(
StmtExpr {
node_index: AtomicNodeIndex(..),
range: 669..672,
value: EllipsisLiteral(
ExprEllipsisLiteral {
node_index: AtomicNodeIndex(..),
range: 669..672,
},
),
},
),
],
},
),
ClassDef(
StmtClassDef {
node_index: AtomicNodeIndex(..),
range: 689..711,
decorator_list: [],
name: Identifier {
id: Name("Test"),
range: 695..699,
node_index: AtomicNodeIndex(..),
},
type_params: Some(
TypeParams {
range: 699..704,
node_index: AtomicNodeIndex(..),
type_params: [
TypeVarTuple(
TypeParamTypeVarTuple {
range: 700..703,
node_index: AtomicNodeIndex(..),
name: Identifier {
id: Name("Ts"),
range: 701..703,
node_index: AtomicNodeIndex(..),
},
default: None,
},
),
],
},
),
arguments: Some(
Arguments {
range: 704..706,
node_index: AtomicNodeIndex(..),
args: [],
keywords: [],
},
),
body: [
Expr(
StmtExpr {
node_index: AtomicNodeIndex(..),
range: 708..711,
value: EllipsisLiteral(
ExprEllipsisLiteral {
node_index: AtomicNodeIndex(..),
range: 708..711,
},
),
},
),
],
},
),
ClassDef(
StmtClassDef {
node_index: AtomicNodeIndex(..),
range: 741..789,
decorator_list: [],
name: Identifier {
id: Name("Test"),
range: 747..751,
node_index: AtomicNodeIndex(..),
},
type_params: Some(
TypeParams {
range: 751..782,
node_index: AtomicNodeIndex(..),
type_params: [
TypeVarTuple(
TypeParamTypeVarTuple {
range: 752..781,
node_index: AtomicNodeIndex(..),
name: Identifier {
id: Name("Ts"),
range: 753..755,
node_index: AtomicNodeIndex(..),
},
default: Some(
Subscript(
ExprSubscript {
node_index: AtomicNodeIndex(..),
range: 758..781,
value: Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 758..764,
id: Name("Unpack"),
ctx: Load,
},
),
slice: Subscript(
ExprSubscript {
node_index: AtomicNodeIndex(..),
range: 765..780,
value: Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 765..770,
id: Name("tuple"),
ctx: Load,
},
),
slice: Tuple(
ExprTuple {
node_index: AtomicNodeIndex(..),
range: 771..779,
elts: [
Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 771..774,
id: Name("int"),
ctx: Load,
},
),
Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 776..779,
id: Name("str"),
ctx: Load,
},
),
],
ctx: Load,
parenthesized: false,
},
),
ctx: Load,
},
),
ctx: Load,
},
),
),
},
),
],
},
),
arguments: Some(
Arguments {
range: 782..784,
node_index: AtomicNodeIndex(..),
args: [],
keywords: [],
},
),
body: [
Expr(
StmtExpr {
node_index: AtomicNodeIndex(..),
range: 786..789,
value: EllipsisLiteral(
ExprEllipsisLiteral {
node_index: AtomicNodeIndex(..),
range: 786..789,
},
),
},
),
],
},
),
ClassDef(
StmtClassDef {
node_index: AtomicNodeIndex(..),
range: 827..868,
decorator_list: [],
name: Identifier {
id: Name("Test"),
range: 833..837,
node_index: AtomicNodeIndex(..),
},
type_params: Some(
TypeParams {
range: 837..861,
node_index: AtomicNodeIndex(..),
type_params: [
TypeVarTuple(
TypeParamTypeVarTuple {
range: 838..860,
node_index: AtomicNodeIndex(..),
name: Identifier {
id: Name("Ts"),
range: 839..841,
node_index: AtomicNodeIndex(..),
},
default: Some(
Starred(
ExprStarred {
node_index: AtomicNodeIndex(..),
range: 844..860,
value: Subscript(
ExprSubscript {
node_index: AtomicNodeIndex(..),
range: 845..860,
value: Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 845..850,
id: Name("tuple"),
ctx: Load,
},
),
slice: Tuple(
ExprTuple {
node_index: AtomicNodeIndex(..),
range: 851..859,
elts: [
Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 851..854,
id: Name("int"),
ctx: Load,
},
),
Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 856..859,
id: Name("str"),
ctx: Load,
},
),
],
ctx: Load,
parenthesized: false,
},
),
ctx: Load,
},
),
ctx: Load,
},
),
),
},
),
],
},
),
arguments: Some(
Arguments {
range: 861..863,
node_index: AtomicNodeIndex(..),
args: [],
keywords: [],
},
),
body: [
Expr(
StmtExpr {
node_index: AtomicNodeIndex(..),
range: 865..868,
value: EllipsisLiteral(
ExprEllipsisLiteral {
node_index: AtomicNodeIndex(..),
range: 865..868,
},
),
},
),
],
},
),
ClassDef(
StmtClassDef {
node_index: AtomicNodeIndex(..),
range: 882..904,
decorator_list: [],
name: Identifier {
id: Name("Test"),
range: 888..892,
node_index: AtomicNodeIndex(..),
},
type_params: Some(
TypeParams {
range: 892..897,
node_index: AtomicNodeIndex(..),
type_params: [
ParamSpec(
TypeParamParamSpec {
range: 893..896,
node_index: AtomicNodeIndex(..),
name: Identifier {
id: Name("P"),
range: 895..896,
node_index: AtomicNodeIndex(..),
},
default: None,
},
),
],
},
),
arguments: Some(
Arguments {
range: 897..899,
node_index: AtomicNodeIndex(..),
args: [],
keywords: [],
},
),
body: [
Expr(
StmtExpr {
node_index: AtomicNodeIndex(..),
range: 901..904,
value: EllipsisLiteral(
ExprEllipsisLiteral {
node_index: AtomicNodeIndex(..),
range: 901..904,
},
),
},
),
],
},
),
ClassDef(
StmtClassDef {
node_index: AtomicNodeIndex(..),
range: 931..966,
decorator_list: [],
name: Identifier {
id: Name("Test"),
range: 937..941,
node_index: AtomicNodeIndex(..),
},
type_params: Some(
TypeParams {
range: 941..959,
node_index: AtomicNodeIndex(..),
type_params: [
ParamSpec(
TypeParamParamSpec {
range: 942..958,
node_index: AtomicNodeIndex(..),
name: Identifier {
id: Name("P"),
range: 944..945,
node_index: AtomicNodeIndex(..),
},
default: Some(
List(
ExprList {
node_index: AtomicNodeIndex(..),
range: 948..958,
elts: [
Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 949..952,
id: Name("int"),
ctx: Load,
},
),
Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 954..957,
id: Name("str"),
ctx: Load,
},
),
],
ctx: Load,
},
),
),
},
),
],
},
),
arguments: Some(
Arguments {
range: 959..961,
node_index: AtomicNodeIndex(..),
args: [],
keywords: [],
},
),
body: [
Expr(
StmtExpr {
node_index: AtomicNodeIndex(..),
range: 963..966,
value: EllipsisLiteral(
ExprEllipsisLiteral {
node_index: AtomicNodeIndex(..),
range: 963..966,
},
),
},
),
],
},
),
ClassDef(
StmtClassDef {
node_index: AtomicNodeIndex(..),
range: 982..1022,
decorator_list: [],
name: Identifier {
id: Name("Test"),
range: 988..992,
node_index: AtomicNodeIndex(..),
},
type_params: Some(
TypeParams {
range: 992..1012,
node_index: AtomicNodeIndex(..),
type_params: [
TypeVar(
TypeParamTypeVar {
range: 993..994,
node_index: AtomicNodeIndex(..),
name: Identifier {
id: Name("X"),
range: 993..994,
node_index: AtomicNodeIndex(..),
},
bound: None,
default: None,
},
),
TypeVar(
TypeParamTypeVar {
range: 996..1002,
node_index: AtomicNodeIndex(..),
name: Identifier {
id: Name("Y"),
range: 996..997,
node_index: AtomicNodeIndex(..),
},
bound: Some(
Name(
ExprName {
node_index: AtomicNodeIndex(..),
range: 999..1002,
id: Name("str"),
ctx: Load,
},
),
),
default: None,
},
),
TypeVarTuple(
TypeParamTypeVarTuple {
range: 1004..1006,
node_index: AtomicNodeIndex(..),
name: Identifier {
id: Name("U"),
range: 1005..1006,
node_index: AtomicNodeIndex(..),
},
default: None,
},
),
ParamSpec(
TypeParamParamSpec {
range: 1008..1011,
node_index: AtomicNodeIndex(..),
name: Identifier {
id: Name("P"),
range: 1010..1011,
node_index: AtomicNodeIndex(..),
},
default: None,
},
),
],
},
),
arguments: Some(
Arguments {
range: 1012..1014,
node_index: AtomicNodeIndex(..),
args: [],
keywords: [],
},
),
body: [
Pass(
StmtPass {
node_index: AtomicNodeIndex(..),
range: 1018..1022,
},
),
],
},
),
],
},
)
```