[Python-checkins] gh-103763: Implement PEP 695 (#103764)

JelleZijlstra webhook-mailer at python.org
Mon May 15 23:37:05 EDT 2023


https://github.com/python/cpython/commit/24d8b88420b81fc60aeb0cbcacef1e72d633824a
commit: 24d8b88420b81fc60aeb0cbcacef1e72d633824a
branch: main
author: Jelle Zijlstra <jelle.zijlstra at gmail.com>
committer: JelleZijlstra <jelle.zijlstra at gmail.com>
date: 2023-05-15T20:36:23-07:00
summary:

gh-103763: Implement PEP 695 (#103764)

This implements PEP 695, Type Parameter Syntax. It adds support for:

- Generic functions (def func[T](): ...)
- Generic classes (class X[T](): ...)
- Type aliases (type X = ...)
- New scoping when the new syntax is used within a class body
- Compiler and interpreter changes to support the new syntax and scoping rules 

Co-authored-by: Marc Mueller <30130371+cdce8p at users.noreply.github.com>
Co-authored-by: Eric Traut <eric at traut.com>
Co-authored-by: Larry Hastings <larry at hastings.org>
Co-authored-by: Alex Waygood <Alex.Waygood at Gmail.com>

files:
A Include/internal/pycore_typevarobject.h
A Lib/test/test_type_aliases.py
A Lib/test/test_type_params.py
A Misc/NEWS.d/next/Core and Builtins/2023-04-25-08-43-11.gh-issue-103763.ZLBZk1.rst
A Objects/clinic/typevarobject.c.h
A Objects/typevarobject.c
M Doc/library/ast.rst
M Grammar/python.gram
M Include/cpython/funcobject.h
M Include/internal/pycore_ast.h
M Include/internal/pycore_ast_state.h
M Include/internal/pycore_function.h
M Include/internal/pycore_global_objects.h
M Include/internal/pycore_global_objects_fini_generated.h
M Include/internal/pycore_global_strings.h
M Include/internal/pycore_intrinsics.h
M Include/internal/pycore_opcode.h
M Include/internal/pycore_runtime_init_generated.h
M Include/internal/pycore_symtable.h
M Include/internal/pycore_unicodeobject_generated.h
M Include/opcode.h
M Lib/ast.py
M Lib/importlib/_bootstrap_external.py
M Lib/keyword.py
M Lib/opcode.py
M Lib/test/support/__init__.py
M Lib/test/test_ast.py
M Lib/test/test_keyword.py
M Lib/test/test_sys.py
M Lib/test/test_typing.py
M Lib/typing.py
M Makefile.pre.in
M Modules/Setup.bootstrap.in
M Modules/Setup.stdlib.in
M Modules/_typingmodule.c
M Objects/funcobject.c
M Objects/object.c
M Objects/typeobject.c
M Objects/unionobject.c
M PCbuild/_freeze_module.vcxproj
M PCbuild/pythoncore.vcxproj
M PCbuild/pythoncore.vcxproj.filters
M Parser/Python.asdl
M Parser/action_helpers.c
M Parser/parser.c
M Python/Python-ast.c
M Python/ast.c
M Python/ast_opt.c
M Python/bytecodes.c
M Python/compile.c
M Python/generated_cases.c.h
M Python/intrinsics.c
M Python/opcode_metadata.h
M Python/opcode_targets.h
M Python/pylifecycle.c
M Python/symtable.c

diff --git a/Doc/library/ast.rst b/Doc/library/ast.rst
index 0811b3fa0e78..eb6a973cac62 100644
--- a/Doc/library/ast.rst
+++ b/Doc/library/ast.rst
@@ -1724,6 +1724,7 @@ Function and class definitions
             body=[
                 FunctionDef(
                     name='f',
+                    typeparams=[],
                     args=arguments(
                         posonlyargs=[],
                         args=[
@@ -1847,6 +1848,7 @@ Function and class definitions
             body=[
                 ClassDef(
                     name='Foo',
+                    typeparams=[],
                     bases=[
                         Name(id='base1', ctx=Load()),
                         Name(id='base2', ctx=Load())],
@@ -1885,6 +1887,7 @@ Async and await
         body=[
             AsyncFunctionDef(
                 name='f',
+                typeparams=[],
                 args=arguments(
                     posonlyargs=[],
                     args=[],
diff --git a/Grammar/python.gram b/Grammar/python.gram
index 6361dcd0985b..c79207b9cb51 100644
--- a/Grammar/python.gram
+++ b/Grammar/python.gram
@@ -112,6 +112,7 @@ simple_stmts[asdl_stmt_seq*]:
 # will throw a SyntaxError.
 simple_stmt[stmt_ty] (memo):
     | assignment
+    | &"type" type_alias
     | e=star_expressions { _PyAST_Expr(e, EXTRA) }
     | &'return' return_stmt
     | &('import' | 'from') import_stmt
@@ -252,8 +253,8 @@ class_def[stmt_ty]:
 
 class_def_raw[stmt_ty]:
     | invalid_class_def_raw
-    | 'class' a=NAME b=['(' z=[arguments] ')' { z }] ':' c=block {
-        _PyAST_ClassDef(a->v.Name.id,
+    | 'class' a=NAME t=[type_params] b=['(' z=[arguments] ')' { z }] ':' c=block {
+        _PyAST_ClassDef(a->v.Name.id, t,
                      (b) ? ((expr_ty) b)->v.Call.args : NULL,
                      (b) ? ((expr_ty) b)->v.Call.keywords : NULL,
                      c, NULL, EXTRA) }
@@ -267,16 +268,16 @@ function_def[stmt_ty]:
 
 function_def_raw[stmt_ty]:
     | invalid_def_raw
-    | 'def' n=NAME &&'(' params=[params] ')' a=['->' z=expression { z }] &&':' tc=[func_type_comment] b=block {
-        _PyAST_FunctionDef(n->v.Name.id,
+    | 'def' n=NAME t=[type_params] &&'(' params=[params] ')' a=['->' z=expression { z }] &&':' tc=[func_type_comment] b=block {
+        _PyAST_FunctionDef(n->v.Name.id, t,
                         (params) ? params : CHECK(arguments_ty, _PyPegen_empty_arguments(p)),
                         b, NULL, a, NEW_TYPE_COMMENT(p, tc), EXTRA) }
-    | ASYNC 'def' n=NAME &&'(' params=[params] ')' a=['->' z=expression { z }] &&':' tc=[func_type_comment] b=block {
+    | ASYNC 'def' n=NAME t=[type_params] &&'(' params=[params] ')' a=['->' z=expression { z }] &&':' tc=[func_type_comment] b=block {
         CHECK_VERSION(
             stmt_ty,
             5,
             "Async functions are",
-            _PyAST_AsyncFunctionDef(n->v.Name.id,
+            _PyAST_AsyncFunctionDef(n->v.Name.id, t,
                             (params) ? params : CHECK(arguments_ty, _PyPegen_empty_arguments(p)),
                             b, NULL, a, NEW_TYPE_COMMENT(p, tc), EXTRA)
         ) }
@@ -628,6 +629,39 @@ keyword_patterns[asdl_seq*]:
 keyword_pattern[KeyPatternPair*]:
     | arg=NAME '=' value=pattern { _PyPegen_key_pattern_pair(p, arg, value) }
 
+# Type statement
+# ---------------
+
+type_alias[stmt_ty]:
+    | "type" n=NAME t=[type_params] '=' b=expression {
+        CHECK_VERSION(stmt_ty, 12, "Type statement is",
+        _PyAST_TypeAlias(CHECK(expr_ty, _PyPegen_set_expr_context(p, n, Store)), t, b, EXTRA)) }
+
+# Type parameter declaration
+# --------------------------
+
+type_params[asdl_typeparam_seq*]: '[' t=type_param_seq  ']' {
+        CHECK_VERSION(asdl_typeparam_seq *, 12, "Type parameter lists are", t) }
+
+type_param_seq[asdl_typeparam_seq*]: a[asdl_typeparam_seq*]=','.type_param+ [','] { a }
+
+type_param[typeparam_ty] (memo):
+    | a=NAME b=[type_param_bound] { _PyAST_TypeVar(a->v.Name.id, b, EXTRA) }
+    | '*' a=NAME colon=":" e=expression {
+            RAISE_SYNTAX_ERROR_STARTING_FROM(colon, e->kind == Tuple_kind
+                ? "cannot use constraints with TypeVarTuple"
+                : "cannot use bound with TypeVarTuple")
+        }
+    | '*' a=NAME { _PyAST_TypeVarTuple(a->v.Name.id, EXTRA) }
+    | '**' a=NAME colon=":" e=expression {
+            RAISE_SYNTAX_ERROR_STARTING_FROM(colon, e->kind == Tuple_kind
+                ? "cannot use constraints with ParamSpec"
+                : "cannot use bound with ParamSpec")
+        }
+    | '**' a=NAME { _PyAST_ParamSpec(a->v.Name.id, EXTRA) }
+
+type_param_bound[expr_ty]: ":" e=expression { e }
+
 # EXPRESSIONS
 # -----------
 
diff --git a/Include/cpython/funcobject.h b/Include/cpython/funcobject.h
index c716330cc3fb..6f78f5868d01 100644
--- a/Include/cpython/funcobject.h
+++ b/Include/cpython/funcobject.h
@@ -41,6 +41,7 @@ typedef struct {
     PyObject *func_weakreflist; /* List of weak references */
     PyObject *func_module;      /* The __module__ attribute, can be anything */
     PyObject *func_annotations; /* Annotations, a dict or NULL */
+    PyObject *func_typeparams;  /* Tuple of active type variables or NULL */
     vectorcallfunc vectorcall;
     /* Version number for use by specializer.
      * Can set to non-zero when we want to specialize.
diff --git a/Include/internal/pycore_ast.h b/Include/internal/pycore_ast.h
index 36277efe9c5c..9f1cef054150 100644
--- a/Include/internal/pycore_ast.h
+++ b/Include/internal/pycore_ast.h
@@ -51,6 +51,8 @@ typedef struct _pattern *pattern_ty;
 
 typedef struct _type_ignore *type_ignore_ty;
 
+typedef struct _typeparam *typeparam_ty;
+
 
 typedef struct {
     _ASDL_SEQ_HEAD
@@ -147,6 +149,13 @@ typedef struct {
 asdl_type_ignore_seq *_Py_asdl_type_ignore_seq_new(Py_ssize_t size, PyArena
                                                    *arena);
 
+typedef struct {
+    _ASDL_SEQ_HEAD
+    typeparam_ty typed_elements[1];
+} asdl_typeparam_seq;
+
+asdl_typeparam_seq *_Py_asdl_typeparam_seq_new(Py_ssize_t size, PyArena *arena);
+
 
 enum _mod_kind {Module_kind=1, Interactive_kind=2, Expression_kind=3,
                  FunctionType_kind=4};
@@ -176,17 +185,19 @@ struct _mod {
 
 enum _stmt_kind {FunctionDef_kind=1, AsyncFunctionDef_kind=2, ClassDef_kind=3,
                   Return_kind=4, Delete_kind=5, Assign_kind=6,
-                  AugAssign_kind=7, AnnAssign_kind=8, For_kind=9,
-                  AsyncFor_kind=10, While_kind=11, If_kind=12, With_kind=13,
-                  AsyncWith_kind=14, Match_kind=15, Raise_kind=16, Try_kind=17,
-                  TryStar_kind=18, Assert_kind=19, Import_kind=20,
-                  ImportFrom_kind=21, Global_kind=22, Nonlocal_kind=23,
-                  Expr_kind=24, Pass_kind=25, Break_kind=26, Continue_kind=27};
+                  TypeAlias_kind=7, AugAssign_kind=8, AnnAssign_kind=9,
+                  For_kind=10, AsyncFor_kind=11, While_kind=12, If_kind=13,
+                  With_kind=14, AsyncWith_kind=15, Match_kind=16,
+                  Raise_kind=17, Try_kind=18, TryStar_kind=19, Assert_kind=20,
+                  Import_kind=21, ImportFrom_kind=22, Global_kind=23,
+                  Nonlocal_kind=24, Expr_kind=25, Pass_kind=26, Break_kind=27,
+                  Continue_kind=28};
 struct _stmt {
     enum _stmt_kind kind;
     union {
         struct {
             identifier name;
+            asdl_typeparam_seq *typeparams;
             arguments_ty args;
             asdl_stmt_seq *body;
             asdl_expr_seq *decorator_list;
@@ -196,6 +207,7 @@ struct _stmt {
 
         struct {
             identifier name;
+            asdl_typeparam_seq *typeparams;
             arguments_ty args;
             asdl_stmt_seq *body;
             asdl_expr_seq *decorator_list;
@@ -205,6 +217,7 @@ struct _stmt {
 
         struct {
             identifier name;
+            asdl_typeparam_seq *typeparams;
             asdl_expr_seq *bases;
             asdl_keyword_seq *keywords;
             asdl_stmt_seq *body;
@@ -225,6 +238,12 @@ struct _stmt {
             string type_comment;
         } Assign;
 
+        struct {
+            expr_ty name;
+            asdl_typeparam_seq *typeparams;
+            expr_ty value;
+        } TypeAlias;
+
         struct {
             expr_ty target;
             operator_ty op;
@@ -630,6 +649,30 @@ struct _type_ignore {
     } v;
 };
 
+enum _typeparam_kind {TypeVar_kind=1, ParamSpec_kind=2, TypeVarTuple_kind=3};
+struct _typeparam {
+    enum _typeparam_kind kind;
+    union {
+        struct {
+            identifier name;
+            expr_ty bound;
+        } TypeVar;
+
+        struct {
+            identifier name;
+        } ParamSpec;
+
+        struct {
+            identifier name;
+        } TypeVarTuple;
+
+    } v;
+    int lineno;
+    int col_offset;
+    int end_lineno;
+    int end_col_offset;
+};
+
 
 // Note: these macros affect function definitions, not only call sites.
 mod_ty _PyAST_Module(asdl_stmt_seq * body, asdl_type_ignore_seq * type_ignores,
@@ -638,21 +681,22 @@ mod_ty _PyAST_Interactive(asdl_stmt_seq * body, PyArena *arena);
 mod_ty _PyAST_Expression(expr_ty body, PyArena *arena);
 mod_ty _PyAST_FunctionType(asdl_expr_seq * argtypes, expr_ty returns, PyArena
                            *arena);
-stmt_ty _PyAST_FunctionDef(identifier name, arguments_ty args, asdl_stmt_seq *
-                           body, asdl_expr_seq * decorator_list, expr_ty
-                           returns, string type_comment, int lineno, int
-                           col_offset, int end_lineno, int end_col_offset,
-                           PyArena *arena);
-stmt_ty _PyAST_AsyncFunctionDef(identifier name, arguments_ty args,
-                                asdl_stmt_seq * body, asdl_expr_seq *
-                                decorator_list, expr_ty returns, string
-                                type_comment, int lineno, int col_offset, int
-                                end_lineno, int end_col_offset, PyArena *arena);
-stmt_ty _PyAST_ClassDef(identifier name, asdl_expr_seq * bases,
-                        asdl_keyword_seq * keywords, asdl_stmt_seq * body,
-                        asdl_expr_seq * decorator_list, int lineno, int
-                        col_offset, int end_lineno, int end_col_offset, PyArena
-                        *arena);
+stmt_ty _PyAST_FunctionDef(identifier name, asdl_typeparam_seq * typeparams,
+                           arguments_ty args, asdl_stmt_seq * body,
+                           asdl_expr_seq * decorator_list, expr_ty returns,
+                           string type_comment, int lineno, int col_offset, int
+                           end_lineno, int end_col_offset, PyArena *arena);
+stmt_ty _PyAST_AsyncFunctionDef(identifier name, asdl_typeparam_seq *
+                                typeparams, arguments_ty args, asdl_stmt_seq *
+                                body, asdl_expr_seq * decorator_list, expr_ty
+                                returns, string type_comment, int lineno, int
+                                col_offset, int end_lineno, int end_col_offset,
+                                PyArena *arena);
+stmt_ty _PyAST_ClassDef(identifier name, asdl_typeparam_seq * typeparams,
+                        asdl_expr_seq * bases, asdl_keyword_seq * keywords,
+                        asdl_stmt_seq * body, asdl_expr_seq * decorator_list,
+                        int lineno, int col_offset, int end_lineno, int
+                        end_col_offset, PyArena *arena);
 stmt_ty _PyAST_Return(expr_ty value, int lineno, int col_offset, int
                       end_lineno, int end_col_offset, PyArena *arena);
 stmt_ty _PyAST_Delete(asdl_expr_seq * targets, int lineno, int col_offset, int
@@ -660,6 +704,9 @@ stmt_ty _PyAST_Delete(asdl_expr_seq * targets, int lineno, int col_offset, int
 stmt_ty _PyAST_Assign(asdl_expr_seq * targets, expr_ty value, string
                       type_comment, int lineno, int col_offset, int end_lineno,
                       int end_col_offset, PyArena *arena);
+stmt_ty _PyAST_TypeAlias(expr_ty name, asdl_typeparam_seq * typeparams, expr_ty
+                         value, int lineno, int col_offset, int end_lineno, int
+                         end_col_offset, PyArena *arena);
 stmt_ty _PyAST_AugAssign(expr_ty target, operator_ty op, expr_ty value, int
                          lineno, int col_offset, int end_lineno, int
                          end_col_offset, PyArena *arena);
@@ -844,6 +891,14 @@ pattern_ty _PyAST_MatchOr(asdl_pattern_seq * patterns, int lineno, int
                           col_offset, int end_lineno, int end_col_offset,
                           PyArena *arena);
 type_ignore_ty _PyAST_TypeIgnore(int lineno, string tag, PyArena *arena);
+typeparam_ty _PyAST_TypeVar(identifier name, expr_ty bound, int lineno, int
+                            col_offset, int end_lineno, int end_col_offset,
+                            PyArena *arena);
+typeparam_ty _PyAST_ParamSpec(identifier name, int lineno, int col_offset, int
+                              end_lineno, int end_col_offset, PyArena *arena);
+typeparam_ty _PyAST_TypeVarTuple(identifier name, int lineno, int col_offset,
+                                 int end_lineno, int end_col_offset, PyArena
+                                 *arena);
 
 
 PyObject* PyAST_mod2obj(mod_ty t);
diff --git a/Include/internal/pycore_ast_state.h b/Include/internal/pycore_ast_state.h
index f15b4905eed1..e723ead577b8 100644
--- a/Include/internal/pycore_ast_state.h
+++ b/Include/internal/pycore_ast_state.h
@@ -118,6 +118,7 @@ struct ast_state {
     PyObject *Not_type;
     PyObject *Or_singleton;
     PyObject *Or_type;
+    PyObject *ParamSpec_type;
     PyObject *Pass_type;
     PyObject *Pow_singleton;
     PyObject *Pow_type;
@@ -137,7 +138,10 @@ struct ast_state {
     PyObject *TryStar_type;
     PyObject *Try_type;
     PyObject *Tuple_type;
+    PyObject *TypeAlias_type;
     PyObject *TypeIgnore_type;
+    PyObject *TypeVarTuple_type;
+    PyObject *TypeVar_type;
     PyObject *UAdd_singleton;
     PyObject *UAdd_type;
     PyObject *USub_singleton;
@@ -166,6 +170,7 @@ struct ast_state {
     PyObject *bases;
     PyObject *body;
     PyObject *boolop_type;
+    PyObject *bound;
     PyObject *cases;
     PyObject *cause;
     PyObject *cls;
@@ -243,6 +248,8 @@ struct ast_state {
     PyObject *type_comment;
     PyObject *type_ignore_type;
     PyObject *type_ignores;
+    PyObject *typeparam_type;
+    PyObject *typeparams;
     PyObject *unaryop_type;
     PyObject *upper;
     PyObject *value;
diff --git a/Include/internal/pycore_function.h b/Include/internal/pycore_function.h
index 11988149843f..ecbb7001e7d8 100644
--- a/Include/internal/pycore_function.h
+++ b/Include/internal/pycore_function.h
@@ -17,6 +17,8 @@ struct _py_func_state {
 extern PyFunctionObject* _PyFunction_FromConstructor(PyFrameConstructor *constr);
 
 extern uint32_t _PyFunction_GetVersionForCurrentState(PyFunctionObject *func);
+extern PyObject *_Py_set_function_type_params(
+    PyThreadState* unused, PyObject *func, PyObject *type_params);
 
 #ifdef __cplusplus
 }
diff --git a/Include/internal/pycore_global_objects.h b/Include/internal/pycore_global_objects.h
index 64d9384df9c5..40cc04d5d170 100644
--- a/Include/internal/pycore_global_objects.h
+++ b/Include/internal/pycore_global_objects.h
@@ -68,6 +68,14 @@ struct _Py_interp_cached_objects {
     PyObject *type_slots_pname;
     pytype_slotdef *type_slots_ptrs[MAX_EQUIV];
 
+    /* TypeVar and related types */
+    PyTypeObject *generic_type;
+    PyTypeObject *typevar_type;
+    PyTypeObject *typevartuple_type;
+    PyTypeObject *paramspec_type;
+    PyTypeObject *paramspecargs_type;
+    PyTypeObject *paramspeckwargs_type;
+    PyTypeObject *typealias_type;
 };
 
 #define _Py_INTERP_STATIC_OBJECT(interp, NAME) \
diff --git a/Include/internal/pycore_global_objects_fini_generated.h b/Include/internal/pycore_global_objects_fini_generated.h
index 7e495817981f..24a268ac8c43 100644
--- a/Include/internal/pycore_global_objects_fini_generated.h
+++ b/Include/internal/pycore_global_objects_fini_generated.h
@@ -555,15 +555,19 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(dbl_close_br));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(dbl_open_br));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(dbl_percent));
+    _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(defaults));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(dot));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(dot_locals));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(empty));
+    _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(generic_base));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(json_decoder));
+    _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(kwdefaults));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(list_err));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(newline));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(open_br));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(percent));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(shim_name));
+    _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(type_params));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_STR(utf_8));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(CANCELLED));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(FINISHED));
@@ -602,6 +606,8 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__class__));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__class_getitem__));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__classcell__));
+    _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__classdict__));
+    _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__classdictcell__));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__complex__));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__contains__));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__copy__));
@@ -724,6 +730,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__subclasshook__));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__truediv__));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__trunc__));
+    _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__type_params__));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__typing_is_unpacked_typevartuple__));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__typing_prepare_subst__));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(__typing_subst__));
@@ -779,8 +786,11 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(after_in_child));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(after_in_parent));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(aggregate_class));
+    _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(alias));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(append));
+    _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(arg));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(argdefs));
+    _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(args));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(arguments));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(argv));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(as_integer_ratio));
@@ -795,6 +805,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(big));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(binary_form));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(block));
+    _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(bound));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(buffer));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(buffer_callback));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(buffer_size));
@@ -850,11 +861,13 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(compile_mode));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(consts));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(context));
+    _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(contravariant));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(cookie));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(copy));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(copyreg));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(coro));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(count));
+    _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(covariant));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(cwd));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(d));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(data));
@@ -964,6 +977,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(incoming));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(indexgroup));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(inf));
+    _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(infer_variance));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(inheritable));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(initial));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(initial_bytes));
@@ -1080,6 +1094,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(optimize));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(options));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(order));
+    _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(origin));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(out_fd));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(outgoing));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(overlapped));
@@ -1213,6 +1228,7 @@ _PyStaticObjects_CheckRefcnt(PyInterpreterState *interp) {
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(twice));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(txt));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(type));
+    _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(type_params));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(tz));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(tzname));
     _PyStaticObject_CheckRefcnt((PyObject *)&_Py_ID(uid));
diff --git a/Include/internal/pycore_global_strings.h b/Include/internal/pycore_global_strings.h
index 8ebfee85c87c..c1005d051552 100644
--- a/Include/internal/pycore_global_strings.h
+++ b/Include/internal/pycore_global_strings.h
@@ -40,15 +40,19 @@ struct _Py_global_strings {
         STRUCT_FOR_STR(dbl_close_br, "}}")
         STRUCT_FOR_STR(dbl_open_br, "{{")
         STRUCT_FOR_STR(dbl_percent, "%%")
+        STRUCT_FOR_STR(defaults, ".defaults")
         STRUCT_FOR_STR(dot, ".")
         STRUCT_FOR_STR(dot_locals, ".<locals>")
         STRUCT_FOR_STR(empty, "")
+        STRUCT_FOR_STR(generic_base, ".generic_base")
         STRUCT_FOR_STR(json_decoder, "json.decoder")
+        STRUCT_FOR_STR(kwdefaults, ".kwdefaults")
         STRUCT_FOR_STR(list_err, "list index out of range")
         STRUCT_FOR_STR(newline, "\n")
         STRUCT_FOR_STR(open_br, "{")
         STRUCT_FOR_STR(percent, "%")
         STRUCT_FOR_STR(shim_name, "<shim>")
+        STRUCT_FOR_STR(type_params, ".type_params")
         STRUCT_FOR_STR(utf_8, "utf-8")
     } literals;
 
@@ -90,6 +94,8 @@ struct _Py_global_strings {
         STRUCT_FOR_ID(__class__)
         STRUCT_FOR_ID(__class_getitem__)
         STRUCT_FOR_ID(__classcell__)
+        STRUCT_FOR_ID(__classdict__)
+        STRUCT_FOR_ID(__classdictcell__)
         STRUCT_FOR_ID(__complex__)
         STRUCT_FOR_ID(__contains__)
         STRUCT_FOR_ID(__copy__)
@@ -212,6 +218,7 @@ struct _Py_global_strings {
         STRUCT_FOR_ID(__subclasshook__)
         STRUCT_FOR_ID(__truediv__)
         STRUCT_FOR_ID(__trunc__)
+        STRUCT_FOR_ID(__type_params__)
         STRUCT_FOR_ID(__typing_is_unpacked_typevartuple__)
         STRUCT_FOR_ID(__typing_prepare_subst__)
         STRUCT_FOR_ID(__typing_subst__)
@@ -267,8 +274,11 @@ struct _Py_global_strings {
         STRUCT_FOR_ID(after_in_child)
         STRUCT_FOR_ID(after_in_parent)
         STRUCT_FOR_ID(aggregate_class)
+        STRUCT_FOR_ID(alias)
         STRUCT_FOR_ID(append)
+        STRUCT_FOR_ID(arg)
         STRUCT_FOR_ID(argdefs)
+        STRUCT_FOR_ID(args)
         STRUCT_FOR_ID(arguments)
         STRUCT_FOR_ID(argv)
         STRUCT_FOR_ID(as_integer_ratio)
@@ -283,6 +293,7 @@ struct _Py_global_strings {
         STRUCT_FOR_ID(big)
         STRUCT_FOR_ID(binary_form)
         STRUCT_FOR_ID(block)
+        STRUCT_FOR_ID(bound)
         STRUCT_FOR_ID(buffer)
         STRUCT_FOR_ID(buffer_callback)
         STRUCT_FOR_ID(buffer_size)
@@ -338,11 +349,13 @@ struct _Py_global_strings {
         STRUCT_FOR_ID(compile_mode)
         STRUCT_FOR_ID(consts)
         STRUCT_FOR_ID(context)
+        STRUCT_FOR_ID(contravariant)
         STRUCT_FOR_ID(cookie)
         STRUCT_FOR_ID(copy)
         STRUCT_FOR_ID(copyreg)
         STRUCT_FOR_ID(coro)
         STRUCT_FOR_ID(count)
+        STRUCT_FOR_ID(covariant)
         STRUCT_FOR_ID(cwd)
         STRUCT_FOR_ID(d)
         STRUCT_FOR_ID(data)
@@ -452,6 +465,7 @@ struct _Py_global_strings {
         STRUCT_FOR_ID(incoming)
         STRUCT_FOR_ID(indexgroup)
         STRUCT_FOR_ID(inf)
+        STRUCT_FOR_ID(infer_variance)
         STRUCT_FOR_ID(inheritable)
         STRUCT_FOR_ID(initial)
         STRUCT_FOR_ID(initial_bytes)
@@ -568,6 +582,7 @@ struct _Py_global_strings {
         STRUCT_FOR_ID(optimize)
         STRUCT_FOR_ID(options)
         STRUCT_FOR_ID(order)
+        STRUCT_FOR_ID(origin)
         STRUCT_FOR_ID(out_fd)
         STRUCT_FOR_ID(outgoing)
         STRUCT_FOR_ID(overlapped)
@@ -701,6 +716,7 @@ struct _Py_global_strings {
         STRUCT_FOR_ID(twice)
         STRUCT_FOR_ID(txt)
         STRUCT_FOR_ID(type)
+        STRUCT_FOR_ID(type_params)
         STRUCT_FOR_ID(tz)
         STRUCT_FOR_ID(tzname)
         STRUCT_FOR_ID(uid)
diff --git a/Include/internal/pycore_intrinsics.h b/Include/internal/pycore_intrinsics.h
index 3902059a04b9..39f15681b7b2 100644
--- a/Include/internal/pycore_intrinsics.h
+++ b/Include/internal/pycore_intrinsics.h
@@ -8,15 +8,23 @@
 #define INTRINSIC_ASYNC_GEN_WRAP                 4
 #define INTRINSIC_UNARY_POSITIVE                 5
 #define INTRINSIC_LIST_TO_TUPLE                  6
+#define INTRINSIC_TYPEVAR                        7
+#define INTRINSIC_PARAMSPEC                      8
+#define INTRINSIC_TYPEVARTUPLE                   9
+#define INTRINSIC_SUBSCRIPT_GENERIC             10
+#define INTRINSIC_TYPEALIAS                     11
 
-#define MAX_INTRINSIC_1                          6
+#define MAX_INTRINSIC_1                         11
 
 
 /* Binary Functions: */
 #define INTRINSIC_2_INVALID                      0
 #define INTRINSIC_PREP_RERAISE_STAR              1
+#define INTRINSIC_TYPEVAR_WITH_BOUND             2
+#define INTRINSIC_TYPEVAR_WITH_CONSTRAINTS       3
+#define INTRINSIC_SET_FUNCTION_TYPE_PARAMS       4
 
-#define MAX_INTRINSIC_2                          1
+#define MAX_INTRINSIC_2                          4
 
 typedef PyObject *(*instrinsic_func1)(PyThreadState* tstate, PyObject *value);
 typedef PyObject *(*instrinsic_func2)(PyThreadState* tstate, PyObject *value1, PyObject *value2);
diff --git a/Include/internal/pycore_opcode.h b/Include/internal/pycore_opcode.h
index e823e1bfb5d4..c2fa5692dbe4 100644
--- a/Include/internal/pycore_opcode.h
+++ b/Include/internal/pycore_opcode.h
@@ -167,7 +167,6 @@ const uint8_t _PyOpcode_Deopt[256] = {
     [LOAD_ATTR_SLOT] = LOAD_ATTR,
     [LOAD_ATTR_WITH_HINT] = LOAD_ATTR,
     [LOAD_BUILD_CLASS] = LOAD_BUILD_CLASS,
-    [LOAD_CLASSDEREF] = LOAD_CLASSDEREF,
     [LOAD_CLOSURE] = LOAD_CLOSURE,
     [LOAD_CONST] = LOAD_CONST,
     [LOAD_CONST__LOAD_FAST] = LOAD_CONST,
@@ -177,9 +176,12 @@ const uint8_t _PyOpcode_Deopt[256] = {
     [LOAD_FAST_CHECK] = LOAD_FAST_CHECK,
     [LOAD_FAST__LOAD_CONST] = LOAD_FAST,
     [LOAD_FAST__LOAD_FAST] = LOAD_FAST,
+    [LOAD_FROM_DICT_OR_DEREF] = LOAD_FROM_DICT_OR_DEREF,
+    [LOAD_FROM_DICT_OR_GLOBALS] = LOAD_FROM_DICT_OR_GLOBALS,
     [LOAD_GLOBAL] = LOAD_GLOBAL,
     [LOAD_GLOBAL_BUILTIN] = LOAD_GLOBAL,
     [LOAD_GLOBAL_MODULE] = LOAD_GLOBAL,
+    [LOAD_LOCALS] = LOAD_LOCALS,
     [LOAD_NAME] = LOAD_NAME,
     [LOAD_SUPER_ATTR] = LOAD_SUPER_ATTR,
     [LOAD_SUPER_ATTR_ATTR] = LOAD_SUPER_ATTR,
@@ -329,8 +331,8 @@ static const char *const _PyOpcode_OpName[267] = {
     [LOAD_CONST__LOAD_FAST] = "LOAD_CONST__LOAD_FAST",
     [SETUP_ANNOTATIONS] = "SETUP_ANNOTATIONS",
     [LOAD_FAST__LOAD_CONST] = "LOAD_FAST__LOAD_CONST",
+    [LOAD_LOCALS] = "LOAD_LOCALS",
     [LOAD_FAST__LOAD_FAST] = "LOAD_FAST__LOAD_FAST",
-    [LOAD_GLOBAL_BUILTIN] = "LOAD_GLOBAL_BUILTIN",
     [POP_EXCEPT] = "POP_EXCEPT",
     [STORE_NAME] = "STORE_NAME",
     [DELETE_NAME] = "DELETE_NAME",
@@ -353,9 +355,9 @@ static const char *const _PyOpcode_OpName[267] = {
     [IMPORT_NAME] = "IMPORT_NAME",
     [IMPORT_FROM] = "IMPORT_FROM",
     [JUMP_FORWARD] = "JUMP_FORWARD",
+    [LOAD_GLOBAL_BUILTIN] = "LOAD_GLOBAL_BUILTIN",
     [LOAD_GLOBAL_MODULE] = "LOAD_GLOBAL_MODULE",
     [STORE_ATTR_INSTANCE_VALUE] = "STORE_ATTR_INSTANCE_VALUE",
-    [STORE_ATTR_SLOT] = "STORE_ATTR_SLOT",
     [POP_JUMP_IF_FALSE] = "POP_JUMP_IF_FALSE",
     [POP_JUMP_IF_TRUE] = "POP_JUMP_IF_TRUE",
     [LOAD_GLOBAL] = "LOAD_GLOBAL",
@@ -390,7 +392,7 @@ static const char *const _PyOpcode_OpName[267] = {
     [LIST_APPEND] = "LIST_APPEND",
     [SET_ADD] = "SET_ADD",
     [MAP_ADD] = "MAP_ADD",
-    [LOAD_CLASSDEREF] = "LOAD_CLASSDEREF",
+    [STORE_ATTR_SLOT] = "STORE_ATTR_SLOT",
     [COPY_FREE_VARS] = "COPY_FREE_VARS",
     [YIELD_VALUE] = "YIELD_VALUE",
     [RESUME] = "RESUME",
@@ -417,8 +419,8 @@ static const char *const _PyOpcode_OpName[267] = {
     [KW_NAMES] = "KW_NAMES",
     [CALL_INTRINSIC_1] = "CALL_INTRINSIC_1",
     [CALL_INTRINSIC_2] = "CALL_INTRINSIC_2",
-    [175] = "<175>",
-    [176] = "<176>",
+    [LOAD_FROM_DICT_OR_GLOBALS] = "LOAD_FROM_DICT_OR_GLOBALS",
+    [LOAD_FROM_DICT_OR_DEREF] = "LOAD_FROM_DICT_OR_DEREF",
     [177] = "<177>",
     [178] = "<178>",
     [179] = "<179>",
@@ -515,8 +517,6 @@ static const char *const _PyOpcode_OpName[267] = {
 #define EXTRA_CASES \
     case 169: \
     case 170: \
-    case 175: \
-    case 176: \
     case 177: \
     case 178: \
     case 179: \
diff --git a/Include/internal/pycore_runtime_init_generated.h b/Include/internal/pycore_runtime_init_generated.h
index 7b9c73dd1edf..ff1dee6eacfe 100644
--- a/Include/internal/pycore_runtime_init_generated.h
+++ b/Include/internal/pycore_runtime_init_generated.h
@@ -546,15 +546,19 @@ extern "C" {
     INIT_STR(dbl_close_br, "}}"), \
     INIT_STR(dbl_open_br, "{{"), \
     INIT_STR(dbl_percent, "%%"), \
+    INIT_STR(defaults, ".defaults"), \
     INIT_STR(dot, "."), \
     INIT_STR(dot_locals, ".<locals>"), \
     INIT_STR(empty, ""), \
+    INIT_STR(generic_base, ".generic_base"), \
     INIT_STR(json_decoder, "json.decoder"), \
+    INIT_STR(kwdefaults, ".kwdefaults"), \
     INIT_STR(list_err, "list index out of range"), \
     INIT_STR(newline, "\n"), \
     INIT_STR(open_br, "{"), \
     INIT_STR(percent, "%"), \
     INIT_STR(shim_name, "<shim>"), \
+    INIT_STR(type_params, ".type_params"), \
     INIT_STR(utf_8, "utf-8"), \
 }
 
@@ -596,6 +600,8 @@ extern "C" {
     INIT_ID(__class__), \
     INIT_ID(__class_getitem__), \
     INIT_ID(__classcell__), \
+    INIT_ID(__classdict__), \
+    INIT_ID(__classdictcell__), \
     INIT_ID(__complex__), \
     INIT_ID(__contains__), \
     INIT_ID(__copy__), \
@@ -718,6 +724,7 @@ extern "C" {
     INIT_ID(__subclasshook__), \
     INIT_ID(__truediv__), \
     INIT_ID(__trunc__), \
+    INIT_ID(__type_params__), \
     INIT_ID(__typing_is_unpacked_typevartuple__), \
     INIT_ID(__typing_prepare_subst__), \
     INIT_ID(__typing_subst__), \
@@ -773,8 +780,11 @@ extern "C" {
     INIT_ID(after_in_child), \
     INIT_ID(after_in_parent), \
     INIT_ID(aggregate_class), \
+    INIT_ID(alias), \
     INIT_ID(append), \
+    INIT_ID(arg), \
     INIT_ID(argdefs), \
+    INIT_ID(args), \
     INIT_ID(arguments), \
     INIT_ID(argv), \
     INIT_ID(as_integer_ratio), \
@@ -789,6 +799,7 @@ extern "C" {
     INIT_ID(big), \
     INIT_ID(binary_form), \
     INIT_ID(block), \
+    INIT_ID(bound), \
     INIT_ID(buffer), \
     INIT_ID(buffer_callback), \
     INIT_ID(buffer_size), \
@@ -844,11 +855,13 @@ extern "C" {
     INIT_ID(compile_mode), \
     INIT_ID(consts), \
     INIT_ID(context), \
+    INIT_ID(contravariant), \
     INIT_ID(cookie), \
     INIT_ID(copy), \
     INIT_ID(copyreg), \
     INIT_ID(coro), \
     INIT_ID(count), \
+    INIT_ID(covariant), \
     INIT_ID(cwd), \
     INIT_ID(d), \
     INIT_ID(data), \
@@ -958,6 +971,7 @@ extern "C" {
     INIT_ID(incoming), \
     INIT_ID(indexgroup), \
     INIT_ID(inf), \
+    INIT_ID(infer_variance), \
     INIT_ID(inheritable), \
     INIT_ID(initial), \
     INIT_ID(initial_bytes), \
@@ -1074,6 +1088,7 @@ extern "C" {
     INIT_ID(optimize), \
     INIT_ID(options), \
     INIT_ID(order), \
+    INIT_ID(origin), \
     INIT_ID(out_fd), \
     INIT_ID(outgoing), \
     INIT_ID(overlapped), \
@@ -1207,6 +1222,7 @@ extern "C" {
     INIT_ID(twice), \
     INIT_ID(txt), \
     INIT_ID(type), \
+    INIT_ID(type_params), \
     INIT_ID(tz), \
     INIT_ID(tzname), \
     INIT_ID(uid), \
diff --git a/Include/internal/pycore_symtable.h b/Include/internal/pycore_symtable.h
index 9a005be5402c..3fa825d0a837 100644
--- a/Include/internal/pycore_symtable.h
+++ b/Include/internal/pycore_symtable.h
@@ -10,8 +10,17 @@ extern "C" {
 
 struct _mod;   // Type defined in pycore_ast.h
 
-typedef enum _block_type { FunctionBlock, ClassBlock, ModuleBlock, AnnotationBlock }
-    _Py_block_ty;
+typedef enum _block_type {
+    FunctionBlock, ClassBlock, ModuleBlock,
+    // Used for annotations if 'from __future__ import annotations' is active.
+    // Annotation blocks cannot bind names and are not evaluated.
+    AnnotationBlock,
+    // Used for generics and type aliases. These work mostly like functions
+    // (see PEP 695 for details). The three different blocks function identically;
+    // they are different enum entries only so that error messages can be more
+    // precise.
+    TypeVarBoundBlock, TypeAliasBlock, TypeParamBlock
+} _Py_block_ty;
 
 typedef enum _comprehension_type {
     NoComprehension = 0,
@@ -49,7 +58,7 @@ typedef struct _symtable_entry {
     PyObject *ste_varnames;  /* list of function parameters */
     PyObject *ste_children;  /* list of child blocks */
     PyObject *ste_directives;/* locations of global and nonlocal statements */
-    _Py_block_ty ste_type;   /* module, class, function or annotation */
+    _Py_block_ty ste_type;
     int ste_nested;      /* true if block is nested */
     unsigned ste_free : 1;        /* true if block has free variables */
     unsigned ste_child_free : 1;  /* true if a child block has free vars,
@@ -64,8 +73,12 @@ typedef struct _symtable_entry {
     unsigned ste_needs_class_closure : 1; /* for class scopes, true if a
                                              closure over __class__
                                              should be created */
+    unsigned ste_needs_classdict : 1; /* for class scopes, true if a closure
+                                         over the class dict should be created */
     unsigned ste_comp_inlined : 1; /* true if this comprehension is inlined */
     unsigned ste_comp_iter_target : 1; /* true if visiting comprehension target */
+    unsigned ste_can_see_class_scope : 1; /* true if this block can see names bound in an
+                                             enclosing class scope */
     int ste_comp_iter_expr; /* non-zero if visiting a comprehension range expression */
     int ste_lineno;          /* first line of block */
     int ste_col_offset;      /* offset of first line of block */
@@ -82,6 +95,7 @@ extern PyTypeObject PySTEntry_Type;
 
 extern long _PyST_GetSymbol(PySTEntryObject *, PyObject *);
 extern int _PyST_GetScope(PySTEntryObject *, PyObject *);
+extern int _PyST_IsFunctionLike(PySTEntryObject *);
 
 extern struct symtable* _PySymtable_Build(
     struct _mod *mod,
@@ -105,6 +119,7 @@ extern PyObject* _Py_Mangle(PyObject *p, PyObject *name);
 #define DEF_IMPORT 2<<6        /* assignment occurred via import */
 #define DEF_ANNOT 2<<7         /* this name is annotated */
 #define DEF_COMP_ITER 2<<8     /* this name is a comprehension iteration variable */
+#define DEF_TYPE_PARAM 2<<9    /* this name is a type parameter */
 
 #define DEF_BOUND (DEF_LOCAL | DEF_PARAM | DEF_IMPORT)
 
diff --git a/Include/internal/pycore_typevarobject.h b/Include/internal/pycore_typevarobject.h
new file mode 100644
index 000000000000..2035e47e9230
--- /dev/null
+++ b/Include/internal/pycore_typevarobject.h
@@ -0,0 +1,22 @@
+#ifndef Py_INTERNAL_TYPEVAROBJECT_H
+#define Py_INTERNAL_TYPEVAROBJECT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef Py_BUILD_CORE
+#  error "this header requires Py_BUILD_CORE define"
+#endif
+
+extern PyObject *_Py_make_typevar(PyObject *, PyObject *, PyObject *);
+extern PyObject *_Py_make_paramspec(PyThreadState *, PyObject *);
+extern PyObject *_Py_make_typevartuple(PyThreadState *, PyObject *);
+extern PyObject *_Py_make_typealias(PyThreadState *, PyObject *);
+extern PyObject *_Py_subscript_generic(PyThreadState *, PyObject *);
+extern int _Py_initialize_generic(PyInterpreterState *);
+extern void _Py_clear_generic_types(PyInterpreterState *);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_INTERNAL_TYPEVAROBJECT_H */
diff --git a/Include/internal/pycore_unicodeobject_generated.h b/Include/internal/pycore_unicodeobject_generated.h
index 8e086edbdf81..ba6b37f1bf55 100644
--- a/Include/internal/pycore_unicodeobject_generated.h
+++ b/Include/internal/pycore_unicodeobject_generated.h
@@ -123,6 +123,12 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
     string = &_Py_ID(__classcell__);
     assert(_PyUnicode_CheckConsistency(string, 1));
     _PyUnicode_InternInPlace(interp, &string);
+    string = &_Py_ID(__classdict__);
+    assert(_PyUnicode_CheckConsistency(string, 1));
+    _PyUnicode_InternInPlace(interp, &string);
+    string = &_Py_ID(__classdictcell__);
+    assert(_PyUnicode_CheckConsistency(string, 1));
+    _PyUnicode_InternInPlace(interp, &string);
     string = &_Py_ID(__complex__);
     assert(_PyUnicode_CheckConsistency(string, 1));
     _PyUnicode_InternInPlace(interp, &string);
@@ -489,6 +495,9 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
     string = &_Py_ID(__trunc__);
     assert(_PyUnicode_CheckConsistency(string, 1));
     _PyUnicode_InternInPlace(interp, &string);
+    string = &_Py_ID(__type_params__);
+    assert(_PyUnicode_CheckConsistency(string, 1));
+    _PyUnicode_InternInPlace(interp, &string);
     string = &_Py_ID(__typing_is_unpacked_typevartuple__);
     assert(_PyUnicode_CheckConsistency(string, 1));
     _PyUnicode_InternInPlace(interp, &string);
@@ -654,12 +663,21 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
     string = &_Py_ID(aggregate_class);
     assert(_PyUnicode_CheckConsistency(string, 1));
     _PyUnicode_InternInPlace(interp, &string);
+    string = &_Py_ID(alias);
+    assert(_PyUnicode_CheckConsistency(string, 1));
+    _PyUnicode_InternInPlace(interp, &string);
     string = &_Py_ID(append);
     assert(_PyUnicode_CheckConsistency(string, 1));
     _PyUnicode_InternInPlace(interp, &string);
+    string = &_Py_ID(arg);
+    assert(_PyUnicode_CheckConsistency(string, 1));
+    _PyUnicode_InternInPlace(interp, &string);
     string = &_Py_ID(argdefs);
     assert(_PyUnicode_CheckConsistency(string, 1));
     _PyUnicode_InternInPlace(interp, &string);
+    string = &_Py_ID(args);
+    assert(_PyUnicode_CheckConsistency(string, 1));
+    _PyUnicode_InternInPlace(interp, &string);
     string = &_Py_ID(arguments);
     assert(_PyUnicode_CheckConsistency(string, 1));
     _PyUnicode_InternInPlace(interp, &string);
@@ -702,6 +720,9 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
     string = &_Py_ID(block);
     assert(_PyUnicode_CheckConsistency(string, 1));
     _PyUnicode_InternInPlace(interp, &string);
+    string = &_Py_ID(bound);
+    assert(_PyUnicode_CheckConsistency(string, 1));
+    _PyUnicode_InternInPlace(interp, &string);
     string = &_Py_ID(buffer);
     assert(_PyUnicode_CheckConsistency(string, 1));
     _PyUnicode_InternInPlace(interp, &string);
@@ -867,6 +888,9 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
     string = &_Py_ID(context);
     assert(_PyUnicode_CheckConsistency(string, 1));
     _PyUnicode_InternInPlace(interp, &string);
+    string = &_Py_ID(contravariant);
+    assert(_PyUnicode_CheckConsistency(string, 1));
+    _PyUnicode_InternInPlace(interp, &string);
     string = &_Py_ID(cookie);
     assert(_PyUnicode_CheckConsistency(string, 1));
     _PyUnicode_InternInPlace(interp, &string);
@@ -882,6 +906,9 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
     string = &_Py_ID(count);
     assert(_PyUnicode_CheckConsistency(string, 1));
     _PyUnicode_InternInPlace(interp, &string);
+    string = &_Py_ID(covariant);
+    assert(_PyUnicode_CheckConsistency(string, 1));
+    _PyUnicode_InternInPlace(interp, &string);
     string = &_Py_ID(cwd);
     assert(_PyUnicode_CheckConsistency(string, 1));
     _PyUnicode_InternInPlace(interp, &string);
@@ -1209,6 +1236,9 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
     string = &_Py_ID(inf);
     assert(_PyUnicode_CheckConsistency(string, 1));
     _PyUnicode_InternInPlace(interp, &string);
+    string = &_Py_ID(infer_variance);
+    assert(_PyUnicode_CheckConsistency(string, 1));
+    _PyUnicode_InternInPlace(interp, &string);
     string = &_Py_ID(inheritable);
     assert(_PyUnicode_CheckConsistency(string, 1));
     _PyUnicode_InternInPlace(interp, &string);
@@ -1557,6 +1587,9 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
     string = &_Py_ID(order);
     assert(_PyUnicode_CheckConsistency(string, 1));
     _PyUnicode_InternInPlace(interp, &string);
+    string = &_Py_ID(origin);
+    assert(_PyUnicode_CheckConsistency(string, 1));
+    _PyUnicode_InternInPlace(interp, &string);
     string = &_Py_ID(out_fd);
     assert(_PyUnicode_CheckConsistency(string, 1));
     _PyUnicode_InternInPlace(interp, &string);
@@ -1956,6 +1989,9 @@ _PyUnicode_InitStaticStrings(PyInterpreterState *interp) {
     string = &_Py_ID(type);
     assert(_PyUnicode_CheckConsistency(string, 1));
     _PyUnicode_InternInPlace(interp, &string);
+    string = &_Py_ID(type_params);
+    assert(_PyUnicode_CheckConsistency(string, 1));
+    _PyUnicode_InternInPlace(interp, &string);
     string = &_Py_ID(tz);
     assert(_PyUnicode_CheckConsistency(string, 1));
     _PyUnicode_InternInPlace(interp, &string);
diff --git a/Include/opcode.h b/Include/opcode.h
index c3b6e5dce49a..dea7687c39da 100644
--- a/Include/opcode.h
+++ b/Include/opcode.h
@@ -45,6 +45,7 @@ extern "C" {
 #define RETURN_GENERATOR                        75
 #define RETURN_VALUE                            83
 #define SETUP_ANNOTATIONS                       85
+#define LOAD_LOCALS                             87
 #define POP_EXCEPT                              89
 #define HAVE_ARGUMENT                           90
 #define STORE_NAME                              90
@@ -102,7 +103,6 @@ extern "C" {
 #define LIST_APPEND                            145
 #define SET_ADD                                146
 #define MAP_ADD                                147
-#define LOAD_CLASSDEREF                        148
 #define COPY_FREE_VARS                         149
 #define YIELD_VALUE                            150
 #define RESUME                                 151
@@ -118,6 +118,8 @@ extern "C" {
 #define KW_NAMES                               172
 #define CALL_INTRINSIC_1                       173
 #define CALL_INTRINSIC_2                       174
+#define LOAD_FROM_DICT_OR_GLOBALS              175
+#define LOAD_FROM_DICT_OR_DEREF                176
 #define MIN_INSTRUMENTED_OPCODE                238
 #define INSTRUMENTED_POP_JUMP_IF_NONE          238
 #define INSTRUMENTED_POP_JUMP_IF_NOT_NONE      239
@@ -199,11 +201,11 @@ extern "C" {
 #define LOAD_ATTR_METHOD_WITH_VALUES            82
 #define LOAD_CONST__LOAD_FAST                   84
 #define LOAD_FAST__LOAD_CONST                   86
-#define LOAD_FAST__LOAD_FAST                    87
-#define LOAD_GLOBAL_BUILTIN                     88
-#define LOAD_GLOBAL_MODULE                     111
-#define STORE_ATTR_INSTANCE_VALUE              112
-#define STORE_ATTR_SLOT                        113
+#define LOAD_FAST__LOAD_FAST                    88
+#define LOAD_GLOBAL_BUILTIN                    111
+#define LOAD_GLOBAL_MODULE                     112
+#define STORE_ATTR_INSTANCE_VALUE              113
+#define STORE_ATTR_SLOT                        148
 #define STORE_ATTR_WITH_HINT                   153
 #define STORE_FAST__LOAD_FAST                  154
 #define STORE_FAST__STORE_FAST                 158
diff --git a/Lib/ast.py b/Lib/ast.py
index 65152047a223..08904afb2031 100644
--- a/Lib/ast.py
+++ b/Lib/ast.py
@@ -1051,6 +1051,7 @@ def visit_ClassDef(self, node):
             self.fill("@")
             self.traverse(deco)
         self.fill("class " + node.name)
+        self._typeparams_helper(node.typeparams)
         with self.delimit_if("(", ")", condition = node.bases or node.keywords):
             comma = False
             for e in node.bases:
@@ -1082,6 +1083,7 @@ def _function_helper(self, node, fill_suffix):
             self.traverse(deco)
         def_str = fill_suffix + " " + node.name
         self.fill(def_str)
+        self._typeparams_helper(node.typeparams)
         with self.delimit("(", ")"):
             self.traverse(node.args)
         if node.returns:
@@ -1090,6 +1092,30 @@ def _function_helper(self, node, fill_suffix):
         with self.block(extra=self.get_type_comment(node)):
             self._write_docstring_and_traverse_body(node)
 
+    def _typeparams_helper(self, typeparams):
+        if typeparams is not None and len(typeparams) > 0:
+            with self.delimit("[", "]"):
+                self.interleave(lambda: self.write(", "), self.traverse, typeparams)
+
+    def visit_TypeVar(self, node):
+        self.write(node.name)
+        if node.bound:
+            self.write(": ")
+            self.traverse(node.bound)
+
+    def visit_TypeVarTuple(self, node):
+        self.write("*" + node.name)
+
+    def visit_ParamSpec(self, node):
+        self.write("**" + node.name)
+
+    def visit_TypeAlias(self, node):
+        self.fill("type ")
+        self.traverse(node.name)
+        self._typeparams_helper(node.typeparams)
+        self.write(" = ")
+        self.traverse(node.value)
+
     def visit_For(self, node):
         self._for_helper("for ", node)
 
diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py
index 3ca5a1aea28a..73ac4405cb54 100644
--- a/Lib/importlib/_bootstrap_external.py
+++ b/Lib/importlib/_bootstrap_external.py
@@ -444,6 +444,7 @@ def _write_atomic(path, data, mode=0o666):
 #     Python 3.12b1 3528 (Add LOAD_SUPER_ATTR_METHOD specialization)
 #     Python 3.12b1 3529 (Inline list/dict/set comprehensions)
 #     Python 3.12b1 3530 (Shrink the LOAD_SUPER_ATTR caches)
+#     Python 3.12b1 3531 (Add PEP 695 changes)
 
 #     Python 3.13 will start with 3550
 
@@ -460,7 +461,7 @@ def _write_atomic(path, data, mode=0o666):
 # Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array
 # in PC/launcher.c must also be updated.
 
-MAGIC_NUMBER = (3530).to_bytes(2, 'little') + b'\r\n'
+MAGIC_NUMBER = (3531).to_bytes(2, 'little') + b'\r\n'
 
 _RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little')  # For import.c
 
diff --git a/Lib/keyword.py b/Lib/keyword.py
index cc2b46b7229d..e22c837835e7 100644
--- a/Lib/keyword.py
+++ b/Lib/keyword.py
@@ -56,7 +56,8 @@
 softkwlist = [
     '_',
     'case',
-    'match'
+    'match',
+    'type'
 ]
 
 iskeyword = frozenset(kwlist).__contains__
diff --git a/Lib/opcode.py b/Lib/opcode.py
index 155466b1ab85..97d0a654a03a 100644
--- a/Lib/opcode.py
+++ b/Lib/opcode.py
@@ -131,6 +131,7 @@ def pseudo_op(name, op, real_ops):
 def_op('RETURN_VALUE', 83)
 
 def_op('SETUP_ANNOTATIONS', 85)
+def_op('LOAD_LOCALS', 87)
 
 def_op('POP_EXCEPT', 89)
 
@@ -206,7 +207,6 @@ def pseudo_op(name, op, real_ops):
 def_op('LIST_APPEND', 145)
 def_op('SET_ADD', 146)
 def_op('MAP_ADD', 147)
-def_op('LOAD_CLASSDEREF', 148)
 hasfree.append(148)
 def_op('COPY_FREE_VARS', 149)
 def_op('YIELD_VALUE', 150)
@@ -228,6 +228,10 @@ def pseudo_op(name, op, real_ops):
 def_op('CALL_INTRINSIC_1', 173)
 def_op('CALL_INTRINSIC_2', 174)
 
+name_op('LOAD_FROM_DICT_OR_GLOBALS', 175)
+def_op('LOAD_FROM_DICT_OR_DEREF', 176)
+hasfree.append(176)
+
 # Instrumented instructions
 MIN_INSTRUMENTED_OPCODE = 238
 
@@ -318,12 +322,20 @@ def pseudo_op(name, op, real_ops):
     "INTRINSIC_ASYNC_GEN_WRAP",
     "INTRINSIC_UNARY_POSITIVE",
     "INTRINSIC_LIST_TO_TUPLE",
+    "INTRINSIC_TYPEVAR",
+    "INTRINSIC_PARAMSPEC",
+    "INTRINSIC_TYPEVARTUPLE",
+    "INTRINSIC_SUBSCRIPT_GENERIC",
+    "INTRINSIC_TYPEALIAS",
 ]
 
 _intrinsic_2_descs = [
-    'INTRINSIC_2_INVALID',
-    'INTRINSIC_PREP_RERAISE_STAR',
-    ]
+    "INTRINSIC_2_INVALID",
+    "INTRINSIC_PREP_RERAISE_STAR",
+    "INTRINSIC_TYPEVAR_WITH_BOUND",
+    "INTRINSIC_TYPEVAR_WITH_CONSTRAINTS",
+    "INTRINSIC_SET_FUNCTION_TYPE_PARAMS",
+]
 
 _specializations = {
     "BINARY_OP": [
diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py
index d063837baee2..d555c53fee50 100644
--- a/Lib/test/support/__init__.py
+++ b/Lib/test/support/__init__.py
@@ -12,6 +12,7 @@
 import stat
 import sys
 import sysconfig
+import textwrap
 import time
 import types
 import unittest
@@ -619,6 +620,14 @@ def sortdict(dict):
     withcommas = ", ".join(reprpairs)
     return "{%s}" % withcommas
 
+
+def run_code(code: str) -> dict[str, object]:
+    """Run a piece of code after dedenting it, and return its global namespace."""
+    ns = {}
+    exec(textwrap.dedent(code), ns)
+    return ns
+
+
 def check_syntax_error(testcase, statement, errtext='', *, lineno=None, offset=None):
     with testcase.assertRaisesRegex(SyntaxError, errtext) as cm:
         compile(statement, '<test string>', 'exec')
diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py
index 34808ed8562e..cf128e1e8cd0 100644
--- a/Lib/test/test_ast.py
+++ b/Lib/test/test_ast.py
@@ -181,7 +181,22 @@ def to_tuple(t):
     "def f(a=1, /, b=2, *, c): pass",
     "def f(a=1, /, b=2, *, c=4, **kwargs): pass",
     "def f(a=1, /, b=2, *, c, **kwargs): pass",
-
+    # Type aliases
+    "type X = int",
+    "type X[T] = int",
+    "type X[T, *Ts, **P] = (T, Ts, P)",
+    "type X[T: int, *Ts, **P] = (T, Ts, P)",
+    "type X[T: (int, str), *Ts, **P] = (T, Ts, P)",
+    # Generic classes
+    "class X[T]: pass",
+    "class X[T, *Ts, **P]: pass",
+    "class X[T: int, *Ts, **P]: pass",
+    "class X[T: (int, str), *Ts, **P]: pass",
+    # Generic functions
+    "def f[T](): pass",
+    "def f[T, *Ts, **P](): pass",
+    "def f[T: int, *Ts, **P](): pass",
+    "def f[T: (int, str), *Ts, **P](): pass",
 ]
 
 # These are compiled through "single"
@@ -262,7 +277,6 @@ def to_tuple(t):
   "()",
   # Combination
   "a.b.c.d(a.b[1:2])",
-
 ]
 
 # TODO: expr_context, slice, boolop, operator, unaryop, cmpop, comprehension
@@ -1013,6 +1027,18 @@ def test_exception_groups_feature_version(self):
         with self.assertRaises(SyntaxError):
             ast.parse(code, feature_version=(3, 10))
 
+    def test_type_params_feature_version(self):
+        samples = [
+            "type X = int",
+            "class X[T]: pass",
+            "def f[T](): pass",
+        ]
+        for sample in samples:
+            with self.subTest(sample):
+                ast.parse(sample)
+                with self.assertRaises(SyntaxError):
+                    ast.parse(sample, feature_version=(3, 11))
+
     def test_invalid_major_feature_version(self):
         with self.assertRaises(ValueError):
             ast.parse('pass', feature_version=(2, 7))
@@ -1557,16 +1583,16 @@ def arguments(args=None, posonlyargs=None, vararg=None,
 
     def test_funcdef(self):
         a = ast.arguments([], [], None, [], [], None, [])
-        f = ast.FunctionDef("x", a, [], [], None)
+        f = ast.FunctionDef("x", [], a, [], [], None)
         self.stmt(f, "empty body on FunctionDef")
-        f = ast.FunctionDef("x", a, [ast.Pass()], [ast.Name("x", ast.Store())],
+        f = ast.FunctionDef("x", [], a, [ast.Pass()], [ast.Name("x", ast.Store())],
                             None)
         self.stmt(f, "must have Load context")
-        f = ast.FunctionDef("x", a, [ast.Pass()], [],
+        f = ast.FunctionDef("x", [], a, [ast.Pass()], [],
                             ast.Name("x", ast.Store()))
         self.stmt(f, "must have Load context")
         def fac(args):
-            return ast.FunctionDef("x", args, [ast.Pass()], [], None)
+            return ast.FunctionDef("x", [], args, [ast.Pass()], [], None)
         self._check_arguments(fac, self.stmt)
 
     def test_classdef(self):
@@ -1579,7 +1605,7 @@ def cls(bases=None, keywords=None, body=None, decorator_list=None):
                 body = [ast.Pass()]
             if decorator_list is None:
                 decorator_list = []
-            return ast.ClassDef("myclass", bases, keywords,
+            return ast.ClassDef("myclass", [], bases, keywords,
                                 body, decorator_list)
         self.stmt(cls(bases=[ast.Name("x", ast.Store())]),
                   "must have Load context")
@@ -2869,23 +2895,23 @@ def main():
 exec_results = [
 ('Module', [('Expr', (1, 0, 1, 4), ('Constant', (1, 0, 1, 4), None, None))], []),
 ('Module', [('Expr', (1, 0, 1, 18), ('Constant', (1, 0, 1, 18), 'module docstring', None))], []),
-('Module', [('FunctionDef', (1, 0, 1, 13), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (1, 9, 1, 13))], [], None, None)], []),
-('Module', [('FunctionDef', (1, 0, 1, 29), 'f', ('arguments', [], [], None, [], [], None, []), [('Expr', (1, 9, 1, 29), ('Constant', (1, 9, 1, 29), 'function docstring', None))], [], None, None)], []),
-('Module', [('FunctionDef', (1, 0, 1, 14), 'f', ('arguments', [], [('arg', (1, 6, 1, 7), 'a', None, None)], None, [], [], None, []), [('Pass', (1, 10, 1, 14))], [], None, None)], []),
-('Module', [('FunctionDef', (1, 0, 1, 16), 'f', ('arguments', [], [('arg', (1, 6, 1, 7), 'a', None, None)], None, [], [], None, [('Constant', (1, 8, 1, 9), 0, None)]), [('Pass', (1, 12, 1, 16))], [], None, None)], []),
-('Module', [('FunctionDef', (1, 0, 1, 18), 'f', ('arguments', [], [], ('arg', (1, 7, 1, 11), 'args', None, None), [], [], None, []), [('Pass', (1, 14, 1, 18))], [], None, None)], []),
-('Module', [('FunctionDef', (1, 0, 1, 23), 'f', ('arguments', [], [], ('arg', (1, 7, 1, 16), 'args', ('Starred', (1, 13, 1, 16), ('Name', (1, 14, 1, 16), 'Ts', ('Load',)), ('Load',)), None), [], [], None, []), [('Pass', (1, 19, 1, 23))], [], None, None)], []),
-('Module', [('FunctionDef', (1, 0, 1, 36), 'f', ('arguments', [], [], ('arg', (1, 7, 1, 29), 'args', ('Starred', (1, 13, 1, 29), ('Subscript', (1, 14, 1, 29), ('Name', (1, 14, 1, 19), 'tuple', ('Load',)), ('Tuple', (1, 20, 1, 28), [('Name', (1, 20, 1, 23), 'int', ('Load',)), ('Constant', (1, 25, 1, 28), Ellipsis, None)], ('Load',)), ('Load',)), ('Load',)), None), [], [], None, []), [('Pass', (1, 32, 1, 36))], [], None, None)], []),
-('Module', [('FunctionDef', (1, 0, 1, 36), 'f', ('arguments', [], [], ('arg', (1, 7, 1, 29), 'args', ('Starred', (1, 13, 1, 29), ('Subscript', (1, 14, 1, 29), ('Name', (1, 14, 1, 19), 'tuple', ('Load',)), ('Tuple', (1, 20, 1, 28), [('Name', (1, 20, 1, 23), 'int', ('Load',)), ('Starred', (1, 25, 1, 28), ('Name', (1, 26, 1, 28), 'Ts', ('Load',)), ('Load',))], ('Load',)), ('Load',)), ('Load',)), None), [], [], None, []), [('Pass', (1, 32, 1, 36))], [], None, None)], []),
-('Module', [('FunctionDef', (1, 0, 1, 21), 'f', ('arguments', [], [], None, [], [], ('arg', (1, 8, 1, 14), 'kwargs', None, None), []), [('Pass', (1, 17, 1, 21))], [], None, None)], []),
-('Module', [('FunctionDef', (1, 0, 1, 71), 'f', ('arguments', [], [('arg', (1, 6, 1, 7), 'a', None, None), ('arg', (1, 9, 1, 10), 'b', None, None), ('arg', (1, 14, 1, 15), 'c', None, None), ('arg', (1, 22, 1, 23), 'd', None, None), ('arg', (1, 28, 1, 29), 'e', None, None)], ('arg', (1, 35, 1, 39), 'args', None, None), [('arg', (1, 41, 1, 42), 'f', None, None)], [('Constant', (1, 43, 1, 45), 42, None)], ('arg', (1, 49, 1, 55), 'kwargs', None, None), [('Constant', (1, 11, 1, 12), 1, None), ('Constant', (1, 16, 1, 20), None, None), ('List', (1, 24, 1, 26), [], ('Load',)), ('Dict', (1, 30, 1, 32), [], [])]), [('Expr', (1, 58, 1, 71), ('Constant', (1, 58, 1, 71), 'doc for f()', None))], [], None, None)], []),
-('Module', [('FunctionDef', (1, 0, 1, 27), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (1, 23, 1, 27))], [], ('Subscript', (1, 11, 1, 21), ('Name', (1, 11, 1, 16), 'tuple', ('Load',)), ('Tuple', (1, 17, 1, 20), [('Starred', (1, 17, 1, 20), ('Name', (1, 18, 1, 20), 'Ts', ('Load',)), ('Load',))], ('Load',)), ('Load',)), None)], []),
-('Module', [('FunctionDef', (1, 0, 1, 32), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (1, 28, 1, 32))], [], ('Subscript', (1, 11, 1, 26), ('Name', (1, 11, 1, 16), 'tuple', ('Load',)), ('Tuple', (1, 17, 1, 25), [('Name', (1, 17, 1, 20), 'int', ('Load',)), ('Starred', (1, 22, 1, 25), ('Name', (1, 23, 1, 25), 'Ts', ('Load',)), ('Load',))], ('Load',)), ('Load',)), None)], []),
-('Module', [('FunctionDef', (1, 0, 1, 45), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (1, 41, 1, 45))], [], ('Subscript', (1, 11, 1, 39), ('Name', (1, 11, 1, 16), 'tuple', ('Load',)), ('Tuple', (1, 17, 1, 38), [('Name', (1, 17, 1, 20), 'int', ('Load',)), ('Starred', (1, 22, 1, 38), ('Subscript', (1, 23, 1, 38), ('Name', (1, 23, 1, 28), 'tuple', ('Load',)), ('Tuple', (1, 29, 1, 37), [('Name', (1, 29, 1, 32), 'int', ('Load',)), ('Constant', (1, 34, 1, 37), Ellipsis, None)], ('Load',)), ('Load',)), ('Load',))], ('Load',)), ('Load',)), None)], []),
-('Module', [('ClassDef', (1, 0, 1, 12), 'C', [], [], [('Pass', (1, 8, 1, 12))], [])], []),
-('Module', [('ClassDef', (1, 0, 1, 32), 'C', [], [], [('Expr', (1, 9, 1, 32), ('Constant', (1, 9, 1, 32), 'docstring for class C', None))], [])], []),
-('Module', [('ClassDef', (1, 0, 1, 21), 'C', [('Name', (1, 8, 1, 14), 'object', ('Load',))], [], [('Pass', (1, 17, 1, 21))], [])], []),
-('Module', [('FunctionDef', (1, 0, 1, 16), 'f', ('arguments', [], [], None, [], [], None, []), [('Return', (1, 8, 1, 16), ('Constant', (1, 15, 1, 16), 1, None))], [], None, None)], []),
+('Module', [('FunctionDef', (1, 0, 1, 13), 'f', [], ('arguments', [], [], None, [], [], None, []), [('Pass', (1, 9, 1, 13))], [], None, None)], []),
+('Module', [('FunctionDef', (1, 0, 1, 29), 'f', [], ('arguments', [], [], None, [], [], None, []), [('Expr', (1, 9, 1, 29), ('Constant', (1, 9, 1, 29), 'function docstring', None))], [], None, None)], []),
+('Module', [('FunctionDef', (1, 0, 1, 14), 'f', [], ('arguments', [], [('arg', (1, 6, 1, 7), 'a', None, None)], None, [], [], None, []), [('Pass', (1, 10, 1, 14))], [], None, None)], []),
+('Module', [('FunctionDef', (1, 0, 1, 16), 'f', [], ('arguments', [], [('arg', (1, 6, 1, 7), 'a', None, None)], None, [], [], None, [('Constant', (1, 8, 1, 9), 0, None)]), [('Pass', (1, 12, 1, 16))], [], None, None)], []),
+('Module', [('FunctionDef', (1, 0, 1, 18), 'f', [], ('arguments', [], [], ('arg', (1, 7, 1, 11), 'args', None, None), [], [], None, []), [('Pass', (1, 14, 1, 18))], [], None, None)], []),
+('Module', [('FunctionDef', (1, 0, 1, 23), 'f', [], ('arguments', [], [], ('arg', (1, 7, 1, 16), 'args', ('Starred', (1, 13, 1, 16), ('Name', (1, 14, 1, 16), 'Ts', ('Load',)), ('Load',)), None), [], [], None, []), [('Pass', (1, 19, 1, 23))], [], None, None)], []),
+('Module', [('FunctionDef', (1, 0, 1, 36), 'f', [], ('arguments', [], [], ('arg', (1, 7, 1, 29), 'args', ('Starred', (1, 13, 1, 29), ('Subscript', (1, 14, 1, 29), ('Name', (1, 14, 1, 19), 'tuple', ('Load',)), ('Tuple', (1, 20, 1, 28), [('Name', (1, 20, 1, 23), 'int', ('Load',)), ('Constant', (1, 25, 1, 28), Ellipsis, None)], ('Load',)), ('Load',)), ('Load',)), None), [], [], None, []), [('Pass', (1, 32, 1, 36))], [], None, None)], []),
+('Module', [('FunctionDef', (1, 0, 1, 36), 'f', [], ('arguments', [], [], ('arg', (1, 7, 1, 29), 'args', ('Starred', (1, 13, 1, 29), ('Subscript', (1, 14, 1, 29), ('Name', (1, 14, 1, 19), 'tuple', ('Load',)), ('Tuple', (1, 20, 1, 28), [('Name', (1, 20, 1, 23), 'int', ('Load',)), ('Starred', (1, 25, 1, 28), ('Name', (1, 26, 1, 28), 'Ts', ('Load',)), ('Load',))], ('Load',)), ('Load',)), ('Load',)), None), [], [], None, []), [('Pass', (1, 32, 1, 36))], [], None, None)], []),
+('Module', [('FunctionDef', (1, 0, 1, 21), 'f', [], ('arguments', [], [], None, [], [], ('arg', (1, 8, 1, 14), 'kwargs', None, None), []), [('Pass', (1, 17, 1, 21))], [], None, None)], []),
+('Module', [('FunctionDef', (1, 0, 1, 71), 'f', [], ('arguments', [], [('arg', (1, 6, 1, 7), 'a', None, None), ('arg', (1, 9, 1, 10), 'b', None, None), ('arg', (1, 14, 1, 15), 'c', None, None), ('arg', (1, 22, 1, 23), 'd', None, None), ('arg', (1, 28, 1, 29), 'e', None, None)], ('arg', (1, 35, 1, 39), 'args', None, None), [('arg', (1, 41, 1, 42), 'f', None, None)], [('Constant', (1, 43, 1, 45), 42, None)], ('arg', (1, 49, 1, 55), 'kwargs', None, None), [('Constant', (1, 11, 1, 12), 1, None), ('Constant', (1, 16, 1, 20), None, None), ('List', (1, 24, 1, 26), [], ('Load',)), ('Dict', (1, 30, 1, 32), [], [])]), [('Expr', (1, 58, 1, 71), ('Constant', (1, 58, 1, 71), 'doc for f()', None))], [], None, None)], []),
+('Module', [('FunctionDef', (1, 0, 1, 27), 'f', [], ('arguments', [], [], None, [], [], None, []), [('Pass', (1, 23, 1, 27))], [], ('Subscript', (1, 11, 1, 21), ('Name', (1, 11, 1, 16), 'tuple', ('Load',)), ('Tuple', (1, 17, 1, 20), [('Starred', (1, 17, 1, 20), ('Name', (1, 18, 1, 20), 'Ts', ('Load',)), ('Load',))], ('Load',)), ('Load',)), None)], []),
+('Module', [('FunctionDef', (1, 0, 1, 32), 'f', [], ('arguments', [], [], None, [], [], None, []), [('Pass', (1, 28, 1, 32))], [], ('Subscript', (1, 11, 1, 26), ('Name', (1, 11, 1, 16), 'tuple', ('Load',)), ('Tuple', (1, 17, 1, 25), [('Name', (1, 17, 1, 20), 'int', ('Load',)), ('Starred', (1, 22, 1, 25), ('Name', (1, 23, 1, 25), 'Ts', ('Load',)), ('Load',))], ('Load',)), ('Load',)), None)], []),
+('Module', [('FunctionDef', (1, 0, 1, 45), 'f', [], ('arguments', [], [], None, [], [], None, []), [('Pass', (1, 41, 1, 45))], [], ('Subscript', (1, 11, 1, 39), ('Name', (1, 11, 1, 16), 'tuple', ('Load',)), ('Tuple', (1, 17, 1, 38), [('Name', (1, 17, 1, 20), 'int', ('Load',)), ('Starred', (1, 22, 1, 38), ('Subscript', (1, 23, 1, 38), ('Name', (1, 23, 1, 28), 'tuple', ('Load',)), ('Tuple', (1, 29, 1, 37), [('Name', (1, 29, 1, 32), 'int', ('Load',)), ('Constant', (1, 34, 1, 37), Ellipsis, None)], ('Load',)), ('Load',)), ('Load',))], ('Load',)), ('Load',)), None)], []),
+('Module', [('ClassDef', (1, 0, 1, 12), 'C', [], [], [], [('Pass', (1, 8, 1, 12))], [])], []),
+('Module', [('ClassDef', (1, 0, 1, 32), 'C', [], [], [], [('Expr', (1, 9, 1, 32), ('Constant', (1, 9, 1, 32), 'docstring for class C', None))], [])], []),
+('Module', [('ClassDef', (1, 0, 1, 21), 'C', [], [('Name', (1, 8, 1, 14), 'object', ('Load',))], [], [('Pass', (1, 17, 1, 21))], [])], []),
+('Module', [('FunctionDef', (1, 0, 1, 16), 'f', [], ('arguments', [], [], None, [], [], None, []), [('Return', (1, 8, 1, 16), ('Constant', (1, 15, 1, 16), 1, None))], [], None, None)], []),
 ('Module', [('Delete', (1, 0, 1, 5), [('Name', (1, 4, 1, 5), 'v', ('Del',))])], []),
 ('Module', [('Assign', (1, 0, 1, 5), [('Name', (1, 0, 1, 1), 'v', ('Store',))], ('Constant', (1, 4, 1, 5), 1, None), None)], []),
 ('Module', [('Assign', (1, 0, 1, 7), [('Tuple', (1, 0, 1, 3), [('Name', (1, 0, 1, 1), 'a', ('Store',)), ('Name', (1, 2, 1, 3), 'b', ('Store',))], ('Store',))], ('Name', (1, 6, 1, 7), 'c', ('Load',)), None)], []),
@@ -2922,28 +2948,41 @@ def main():
 ('Module', [('Expr', (1, 0, 1, 20), ('DictComp', (1, 0, 1, 20), ('Name', (1, 1, 1, 2), 'a', ('Load',)), ('Name', (1, 5, 1, 6), 'b', ('Load',)), [('comprehension', ('Tuple', (1, 11, 1, 14), [('Name', (1, 11, 1, 12), 'v', ('Store',)), ('Name', (1, 13, 1, 14), 'w', ('Store',))], ('Store',)), ('Name', (1, 18, 1, 19), 'x', ('Load',)), [], 0)]))], []),
 ('Module', [('Expr', (1, 0, 1, 19), ('SetComp', (1, 0, 1, 19), ('Name', (1, 1, 1, 2), 'r', ('Load',)), [('comprehension', ('Name', (1, 7, 1, 8), 'l', ('Store',)), ('Name', (1, 12, 1, 13), 'x', ('Load',)), [('Name', (1, 17, 1, 18), 'g', ('Load',))], 0)]))], []),
 ('Module', [('Expr', (1, 0, 1, 16), ('SetComp', (1, 0, 1, 16), ('Name', (1, 1, 1, 2), 'r', ('Load',)), [('comprehension', ('Tuple', (1, 7, 1, 10), [('Name', (1, 7, 1, 8), 'l', ('Store',)), ('Name', (1, 9, 1, 10), 'm', ('Store',))], ('Store',)), ('Name', (1, 14, 1, 15), 'x', ('Load',)), [], 0)]))], []),
-('Module', [('AsyncFunctionDef', (1, 0, 3, 18), 'f', ('arguments', [], [], None, [], [], None, []), [('Expr', (2, 1, 2, 17), ('Constant', (2, 1, 2, 17), 'async function', None)), ('Expr', (3, 1, 3, 18), ('Await', (3, 1, 3, 18), ('Call', (3, 7, 3, 18), ('Name', (3, 7, 3, 16), 'something', ('Load',)), [], [])))], [], None, None)], []),
-('Module', [('AsyncFunctionDef', (1, 0, 3, 8), 'f', ('arguments', [], [], None, [], [], None, []), [('AsyncFor', (2, 1, 3, 8), ('Name', (2, 11, 2, 12), 'e', ('Store',)), ('Name', (2, 16, 2, 17), 'i', ('Load',)), [('Expr', (2, 19, 2, 20), ('Constant', (2, 19, 2, 20), 1, None))], [('Expr', (3, 7, 3, 8), ('Constant', (3, 7, 3, 8), 2, None))], None)], [], None, None)], []),
-('Module', [('AsyncFunctionDef', (1, 0, 2, 21), 'f', ('arguments', [], [], None, [], [], None, []), [('AsyncWith', (2, 1, 2, 21), [('withitem', ('Name', (2, 12, 2, 13), 'a', ('Load',)), ('Name', (2, 17, 2, 18), 'b', ('Store',)))], [('Expr', (2, 20, 2, 21), ('Constant', (2, 20, 2, 21), 1, None))], None)], [], None, None)], []),
+('Module', [('AsyncFunctionDef', (1, 0, 3, 18), 'f', [], ('arguments', [], [], None, [], [], None, []), [('Expr', (2, 1, 2, 17), ('Constant', (2, 1, 2, 17), 'async function', None)), ('Expr', (3, 1, 3, 18), ('Await', (3, 1, 3, 18), ('Call', (3, 7, 3, 18), ('Name', (3, 7, 3, 16), 'something', ('Load',)), [], [])))], [], None, None)], []),
+('Module', [('AsyncFunctionDef', (1, 0, 3, 8), 'f', [], ('arguments', [], [], None, [], [], None, []), [('AsyncFor', (2, 1, 3, 8), ('Name', (2, 11, 2, 12), 'e', ('Store',)), ('Name', (2, 16, 2, 17), 'i', ('Load',)), [('Expr', (2, 19, 2, 20), ('Constant', (2, 19, 2, 20), 1, None))], [('Expr', (3, 7, 3, 8), ('Constant', (3, 7, 3, 8), 2, None))], None)], [], None, None)], []),
+('Module', [('AsyncFunctionDef', (1, 0, 2, 21), 'f', [], ('arguments', [], [], None, [], [], None, []), [('AsyncWith', (2, 1, 2, 21), [('withitem', ('Name', (2, 12, 2, 13), 'a', ('Load',)), ('Name', (2, 17, 2, 18), 'b', ('Store',)))], [('Expr', (2, 20, 2, 21), ('Constant', (2, 20, 2, 21), 1, None))], None)], [], None, None)], []),
 ('Module', [('Expr', (1, 0, 1, 14), ('Dict', (1, 0, 1, 14), [None, ('Constant', (1, 10, 1, 11), 2, None)], [('Dict', (1, 3, 1, 8), [('Constant', (1, 4, 1, 5), 1, None)], [('Constant', (1, 6, 1, 7), 2, None)]), ('Constant', (1, 12, 1, 13), 3, None)]))], []),
 ('Module', [('Expr', (1, 0, 1, 12), ('Set', (1, 0, 1, 12), [('Starred', (1, 1, 1, 8), ('Set', (1, 2, 1, 8), [('Constant', (1, 3, 1, 4), 1, None), ('Constant', (1, 6, 1, 7), 2, None)]), ('Load',)), ('Constant', (1, 10, 1, 11), 3, None)]))], []),
-('Module', [('AsyncFunctionDef', (1, 0, 2, 21), 'f', ('arguments', [], [], None, [], [], None, []), [('Expr', (2, 1, 2, 21), ('ListComp', (2, 1, 2, 21), ('Name', (2, 2, 2, 3), 'i', ('Load',)), [('comprehension', ('Name', (2, 14, 2, 15), 'b', ('Store',)), ('Name', (2, 19, 2, 20), 'c', ('Load',)), [], 1)]))], [], None, None)], []),
-('Module', [('FunctionDef', (4, 0, 4, 13), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (4, 9, 4, 13))], [('Name', (1, 1, 1, 6), 'deco1', ('Load',)), ('Call', (2, 1, 2, 8), ('Name', (2, 1, 2, 6), 'deco2', ('Load',)), [], []), ('Call', (3, 1, 3, 9), ('Name', (3, 1, 3, 6), 'deco3', ('Load',)), [('Constant', (3, 7, 3, 8), 1, None)], [])], None, None)], []),
-('Module', [('AsyncFunctionDef', (4, 0, 4, 19), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (4, 15, 4, 19))], [('Name', (1, 1, 1, 6), 'deco1', ('Load',)), ('Call', (2, 1, 2, 8), ('Name', (2, 1, 2, 6), 'deco2', ('Load',)), [], []), ('Call', (3, 1, 3, 9), ('Name', (3, 1, 3, 6), 'deco3', ('Load',)), [('Constant', (3, 7, 3, 8), 1, None)], [])], None, None)], []),
-('Module', [('ClassDef', (4, 0, 4, 13), 'C', [], [], [('Pass', (4, 9, 4, 13))], [('Name', (1, 1, 1, 6), 'deco1', ('Load',)), ('Call', (2, 1, 2, 8), ('Name', (2, 1, 2, 6), 'deco2', ('Load',)), [], []), ('Call', (3, 1, 3, 9), ('Name', (3, 1, 3, 6), 'deco3', ('Load',)), [('Constant', (3, 7, 3, 8), 1, None)], [])])], []),
-('Module', [('FunctionDef', (2, 0, 2, 13), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (2, 9, 2, 13))], [('Call', (1, 1, 1, 19), ('Name', (1, 1, 1, 5), 'deco', ('Load',)), [('GeneratorExp', (1, 5, 1, 19), ('Name', (1, 6, 1, 7), 'a', ('Load',)), [('comprehension', ('Name', (1, 12, 1, 13), 'a', ('Store',)), ('Name', (1, 17, 1, 18), 'b', ('Load',)), [], 0)])], [])], None, None)], []),
-('Module', [('FunctionDef', (2, 0, 2, 13), 'f', ('arguments', [], [], None, [], [], None, []), [('Pass', (2, 9, 2, 13))], [('Attribute', (1, 1, 1, 6), ('Attribute', (1, 1, 1, 4), ('Name', (1, 1, 1, 2), 'a', ('Load',)), 'b', ('Load',)), 'c', ('Load',))], None, None)], []),
+('Module', [('AsyncFunctionDef', (1, 0, 2, 21), 'f', [], ('arguments', [], [], None, [], [], None, []), [('Expr', (2, 1, 2, 21), ('ListComp', (2, 1, 2, 21), ('Name', (2, 2, 2, 3), 'i', ('Load',)), [('comprehension', ('Name', (2, 14, 2, 15), 'b', ('Store',)), ('Name', (2, 19, 2, 20), 'c', ('Load',)), [], 1)]))], [], None, None)], []),
+('Module', [('FunctionDef', (4, 0, 4, 13), 'f', [], ('arguments', [], [], None, [], [], None, []), [('Pass', (4, 9, 4, 13))], [('Name', (1, 1, 1, 6), 'deco1', ('Load',)), ('Call', (2, 1, 2, 8), ('Name', (2, 1, 2, 6), 'deco2', ('Load',)), [], []), ('Call', (3, 1, 3, 9), ('Name', (3, 1, 3, 6), 'deco3', ('Load',)), [('Constant', (3, 7, 3, 8), 1, None)], [])], None, None)], []),
+('Module', [('AsyncFunctionDef', (4, 0, 4, 19), 'f', [], ('arguments', [], [], None, [], [], None, []), [('Pass', (4, 15, 4, 19))], [('Name', (1, 1, 1, 6), 'deco1', ('Load',)), ('Call', (2, 1, 2, 8), ('Name', (2, 1, 2, 6), 'deco2', ('Load',)), [], []), ('Call', (3, 1, 3, 9), ('Name', (3, 1, 3, 6), 'deco3', ('Load',)), [('Constant', (3, 7, 3, 8), 1, None)], [])], None, None)], []),
+('Module', [('ClassDef', (4, 0, 4, 13), 'C', [], [], [], [('Pass', (4, 9, 4, 13))], [('Name', (1, 1, 1, 6), 'deco1', ('Load',)), ('Call', (2, 1, 2, 8), ('Name', (2, 1, 2, 6), 'deco2', ('Load',)), [], []), ('Call', (3, 1, 3, 9), ('Name', (3, 1, 3, 6), 'deco3', ('Load',)), [('Constant', (3, 7, 3, 8), 1, None)], [])])], []),
+('Module', [('FunctionDef', (2, 0, 2, 13), 'f', [], ('arguments', [], [], None, [], [], None, []), [('Pass', (2, 9, 2, 13))], [('Call', (1, 1, 1, 19), ('Name', (1, 1, 1, 5), 'deco', ('Load',)), [('GeneratorExp', (1, 5, 1, 19), ('Name', (1, 6, 1, 7), 'a', ('Load',)), [('comprehension', ('Name', (1, 12, 1, 13), 'a', ('Store',)), ('Name', (1, 17, 1, 18), 'b', ('Load',)), [], 0)])], [])], None, None)], []),
+('Module', [('FunctionDef', (2, 0, 2, 13), 'f', [], ('arguments', [], [], None, [], [], None, []), [('Pass', (2, 9, 2, 13))], [('Attribute', (1, 1, 1, 6), ('Attribute', (1, 1, 1, 4), ('Name', (1, 1, 1, 2), 'a', ('Load',)), 'b', ('Load',)), 'c', ('Load',))], None, None)], []),
 ('Module', [('Expr', (1, 0, 1, 8), ('NamedExpr', (1, 1, 1, 7), ('Name', (1, 1, 1, 2), 'a', ('Store',)), ('Constant', (1, 6, 1, 7), 1, None)))], []),
-('Module', [('FunctionDef', (1, 0, 1, 18), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [], None, [], [], None, []), [('Pass', (1, 14, 1, 18))], [], None, None)], []),
-('Module', [('FunctionDef', (1, 0, 1, 26), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 12, 1, 13), 'c', None, None), ('arg', (1, 15, 1, 16), 'd', None, None), ('arg', (1, 18, 1, 19), 'e', None, None)], None, [], [], None, []), [('Pass', (1, 22, 1, 26))], [], None, None)], []),
-('Module', [('FunctionDef', (1, 0, 1, 29), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 12, 1, 13), 'c', None, None)], None, [('arg', (1, 18, 1, 19), 'd', None, None), ('arg', (1, 21, 1, 22), 'e', None, None)], [None, None], None, []), [('Pass', (1, 25, 1, 29))], [], None, None)], []),
-('Module', [('FunctionDef', (1, 0, 1, 39), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 12, 1, 13), 'c', None, None)], None, [('arg', (1, 18, 1, 19), 'd', None, None), ('arg', (1, 21, 1, 22), 'e', None, None)], [None, None], ('arg', (1, 26, 1, 32), 'kwargs', None, None), []), [('Pass', (1, 35, 1, 39))], [], None, None)], []),
-('Module', [('FunctionDef', (1, 0, 1, 20), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [], None, [], [], None, [('Constant', (1, 8, 1, 9), 1, None)]), [('Pass', (1, 16, 1, 20))], [], None, None)], []),
-('Module', [('FunctionDef', (1, 0, 1, 29), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 14, 1, 15), 'b', None, None), ('arg', (1, 19, 1, 20), 'c', None, None)], None, [], [], None, [('Constant', (1, 8, 1, 9), 1, None), ('Constant', (1, 16, 1, 17), 2, None), ('Constant', (1, 21, 1, 22), 4, None)]), [('Pass', (1, 25, 1, 29))], [], None, None)], []),
-('Module', [('FunctionDef', (1, 0, 1, 32), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 14, 1, 15), 'b', None, None)], None, [('arg', (1, 22, 1, 23), 'c', None, None)], [('Constant', (1, 24, 1, 25), 4, None)], None, [('Constant', (1, 8, 1, 9), 1, None), ('Constant', (1, 16, 1, 17), 2, None)]), [('Pass', (1, 28, 1, 32))], [], None, None)], []),
-('Module', [('FunctionDef', (1, 0, 1, 30), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 14, 1, 15), 'b', None, None)], None, [('arg', (1, 22, 1, 23), 'c', None, None)], [None], None, [('Constant', (1, 8, 1, 9), 1, None), ('Constant', (1, 16, 1, 17), 2, None)]), [('Pass', (1, 26, 1, 30))], [], None, None)], []),
-('Module', [('FunctionDef', (1, 0, 1, 42), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 14, 1, 15), 'b', None, None)], None, [('arg', (1, 22, 1, 23), 'c', None, None)], [('Constant', (1, 24, 1, 25), 4, None)], ('arg', (1, 29, 1, 35), 'kwargs', None, None), [('Constant', (1, 8, 1, 9), 1, None), ('Constant', (1, 16, 1, 17), 2, None)]), [('Pass', (1, 38, 1, 42))], [], None, None)], []),
-('Module', [('FunctionDef', (1, 0, 1, 40), 'f', ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 14, 1, 15), 'b', None, None)], None, [('arg', (1, 22, 1, 23), 'c', None, None)], [None], ('arg', (1, 27, 1, 33), 'kwargs', None, None), [('Constant', (1, 8, 1, 9), 1, None), ('Constant', (1, 16, 1, 17), 2, None)]), [('Pass', (1, 36, 1, 40))], [], None, None)], []),
+('Module', [('FunctionDef', (1, 0, 1, 18), 'f', [], ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [], None, [], [], None, []), [('Pass', (1, 14, 1, 18))], [], None, None)], []),
+('Module', [('FunctionDef', (1, 0, 1, 26), 'f', [], ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 12, 1, 13), 'c', None, None), ('arg', (1, 15, 1, 16), 'd', None, None), ('arg', (1, 18, 1, 19), 'e', None, None)], None, [], [], None, []), [('Pass', (1, 22, 1, 26))], [], None, None)], []),
+('Module', [('FunctionDef', (1, 0, 1, 29), 'f', [], ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 12, 1, 13), 'c', None, None)], None, [('arg', (1, 18, 1, 19), 'd', None, None), ('arg', (1, 21, 1, 22), 'e', None, None)], [None, None], None, []), [('Pass', (1, 25, 1, 29))], [], None, None)], []),
+('Module', [('FunctionDef', (1, 0, 1, 39), 'f', [], ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 12, 1, 13), 'c', None, None)], None, [('arg', (1, 18, 1, 19), 'd', None, None), ('arg', (1, 21, 1, 22), 'e', None, None)], [None, None], ('arg', (1, 26, 1, 32), 'kwargs', None, None), []), [('Pass', (1, 35, 1, 39))], [], None, None)], []),
+('Module', [('FunctionDef', (1, 0, 1, 20), 'f', [], ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [], None, [], [], None, [('Constant', (1, 8, 1, 9), 1, None)]), [('Pass', (1, 16, 1, 20))], [], None, None)], []),
+('Module', [('FunctionDef', (1, 0, 1, 29), 'f', [], ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 14, 1, 15), 'b', None, None), ('arg', (1, 19, 1, 20), 'c', None, None)], None, [], [], None, [('Constant', (1, 8, 1, 9), 1, None), ('Constant', (1, 16, 1, 17), 2, None), ('Constant', (1, 21, 1, 22), 4, None)]), [('Pass', (1, 25, 1, 29))], [], None, None)], []),
+('Module', [('FunctionDef', (1, 0, 1, 32), 'f', [], ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 14, 1, 15), 'b', None, None)], None, [('arg', (1, 22, 1, 23), 'c', None, None)], [('Constant', (1, 24, 1, 25), 4, None)], None, [('Constant', (1, 8, 1, 9), 1, None), ('Constant', (1, 16, 1, 17), 2, None)]), [('Pass', (1, 28, 1, 32))], [], None, None)], []),
+('Module', [('FunctionDef', (1, 0, 1, 30), 'f', [], ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 14, 1, 15), 'b', None, None)], None, [('arg', (1, 22, 1, 23), 'c', None, None)], [None], None, [('Constant', (1, 8, 1, 9), 1, None), ('Constant', (1, 16, 1, 17), 2, None)]), [('Pass', (1, 26, 1, 30))], [], None, None)], []),
+('Module', [('FunctionDef', (1, 0, 1, 42), 'f', [], ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 14, 1, 15), 'b', None, None)], None, [('arg', (1, 22, 1, 23), 'c', None, None)], [('Constant', (1, 24, 1, 25), 4, None)], ('arg', (1, 29, 1, 35), 'kwargs', None, None), [('Constant', (1, 8, 1, 9), 1, None), ('Constant', (1, 16, 1, 17), 2, None)]), [('Pass', (1, 38, 1, 42))], [], None, None)], []),
+('Module', [('FunctionDef', (1, 0, 1, 40), 'f', [], ('arguments', [('arg', (1, 6, 1, 7), 'a', None, None)], [('arg', (1, 14, 1, 15), 'b', None, None)], None, [('arg', (1, 22, 1, 23), 'c', None, None)], [None], ('arg', (1, 27, 1, 33), 'kwargs', None, None), [('Constant', (1, 8, 1, 9), 1, None), ('Constant', (1, 16, 1, 17), 2, None)]), [('Pass', (1, 36, 1, 40))], [], None, None)], []),
+('Module', [('TypeAlias', (1, 0, 1, 12), ('Name', (1, 5, 1, 6), 'X', ('Store',)), [], ('Name', (1, 9, 1, 12), 'int', ('Load',)))], []),
+('Module', [('TypeAlias', (1, 0, 1, 15), ('Name', (1, 5, 1, 6), 'X', ('Store',)), [('TypeVar', (1, 7, 1, 8), 'T', None)], ('Name', (1, 12, 1, 15), 'int', ('Load',)))], []),
+('Module', [('TypeAlias', (1, 0, 1, 32), ('Name', (1, 5, 1, 6), 'X', ('Store',)), [('TypeVar', (1, 7, 1, 8), 'T', None), ('TypeVarTuple', (1, 10, 1, 13), 'Ts'), ('ParamSpec', (1, 15, 1, 18), 'P')], ('Tuple', (1, 22, 1, 32), [('Name', (1, 23, 1, 24), 'T', ('Load',)), ('Name', (1, 26, 1, 28), 'Ts', ('Load',)), ('Name', (1, 30, 1, 31), 'P', ('Load',))], ('Load',)))], []),
+('Module', [('TypeAlias', (1, 0, 1, 37), ('Name', (1, 5, 1, 6), 'X', ('Store',)), [('TypeVar', (1, 7, 1, 13), 'T', ('Name', (1, 10, 1, 13), 'int', ('Load',))), ('TypeVarTuple', (1, 15, 1, 18), 'Ts'), ('ParamSpec', (1, 20, 1, 23), 'P')], ('Tuple', (1, 27, 1, 37), [('Name', (1, 28, 1, 29), 'T', ('Load',)), ('Name', (1, 31, 1, 33), 'Ts', ('Load',)), ('Name', (1, 35, 1, 36), 'P', ('Load',))], ('Load',)))], []),
+('Module', [('TypeAlias', (1, 0, 1, 44), ('Name', (1, 5, 1, 6), 'X', ('Store',)), [('TypeVar', (1, 7, 1, 20), 'T', ('Tuple', (1, 10, 1, 20), [('Name', (1, 11, 1, 14), 'int', ('Load',)), ('Name', (1, 16, 1, 19), 'str', ('Load',))], ('Load',))), ('TypeVarTuple', (1, 22, 1, 25), 'Ts'), ('ParamSpec', (1, 27, 1, 30), 'P')], ('Tuple', (1, 34, 1, 44), [('Name', (1, 35, 1, 36), 'T', ('Load',)), ('Name', (1, 38, 1, 40), 'Ts', ('Load',)), ('Name', (1, 42, 1, 43), 'P', ('Load',))], ('Load',)))], []),
+('Module', [('ClassDef', (1, 0, 1, 16), 'X', [('TypeVar', (1, 8, 1, 9), 'T', None)], [], [], [('Pass', (1, 12, 1, 16))], [])], []),
+('Module', [('ClassDef', (1, 0, 1, 26), 'X', [('TypeVar', (1, 8, 1, 9), 'T', None), ('TypeVarTuple', (1, 11, 1, 14), 'Ts'), ('ParamSpec', (1, 16, 1, 19), 'P')], [], [], [('Pass', (1, 22, 1, 26))], [])], []),
+('Module', [('ClassDef', (1, 0, 1, 31), 'X', [('TypeVar', (1, 8, 1, 14), 'T', ('Name', (1, 11, 1, 14), 'int', ('Load',))), ('TypeVarTuple', (1, 16, 1, 19), 'Ts'), ('ParamSpec', (1, 21, 1, 24), 'P')], [], [], [('Pass', (1, 27, 1, 31))], [])], []),
+('Module', [('ClassDef', (1, 0, 1, 38), 'X', [('TypeVar', (1, 8, 1, 21), 'T', ('Tuple', (1, 11, 1, 21), [('Name', (1, 12, 1, 15), 'int', ('Load',)), ('Name', (1, 17, 1, 20), 'str', ('Load',))], ('Load',))), ('TypeVarTuple', (1, 23, 1, 26), 'Ts'), ('ParamSpec', (1, 28, 1, 31), 'P')], [], [], [('Pass', (1, 34, 1, 38))], [])], []),
+('Module', [('FunctionDef', (1, 0, 1, 16), 'f', [('TypeVar', (1, 6, 1, 7), 'T', None)], ('arguments', [], [], None, [], [], None, []), [('Pass', (1, 12, 1, 16))], [], None, None)], []),
+('Module', [('FunctionDef', (1, 0, 1, 26), 'f', [('TypeVar', (1, 6, 1, 7), 'T', None), ('TypeVarTuple', (1, 9, 1, 12), 'Ts'), ('ParamSpec', (1, 14, 1, 17), 'P')], ('arguments', [], [], None, [], [], None, []), [('Pass', (1, 22, 1, 26))], [], None, None)], []),
+('Module', [('FunctionDef', (1, 0, 1, 31), 'f', [('TypeVar', (1, 6, 1, 12), 'T', ('Name', (1, 9, 1, 12), 'int', ('Load',))), ('TypeVarTuple', (1, 14, 1, 17), 'Ts'), ('ParamSpec', (1, 19, 1, 22), 'P')], ('arguments', [], [], None, [], [], None, []), [('Pass', (1, 27, 1, 31))], [], None, None)], []),
+('Module', [('FunctionDef', (1, 0, 1, 38), 'f', [('TypeVar', (1, 6, 1, 19), 'T', ('Tuple', (1, 9, 1, 19), [('Name', (1, 10, 1, 13), 'int', ('Load',)), ('Name', (1, 15, 1, 18), 'str', ('Load',))], ('Load',))), ('TypeVarTuple', (1, 21, 1, 24), 'Ts'), ('ParamSpec', (1, 26, 1, 29), 'P')], ('arguments', [], [], None, [], [], None, []), [('Pass', (1, 34, 1, 38))], [], None, None)], []),
 ]
 single_results = [
 ('Interactive', [('Expr', (1, 0, 1, 3), ('BinOp', (1, 0, 1, 3), ('Constant', (1, 0, 1, 1), 1, None), ('Add',), ('Constant', (1, 2, 1, 3), 2, None)))]),
diff --git a/Lib/test/test_keyword.py b/Lib/test/test_keyword.py
index f329f88fa01d..858e5de3b92e 100644
--- a/Lib/test/test_keyword.py
+++ b/Lib/test/test_keyword.py
@@ -39,7 +39,8 @@ def test_async_and_await_are_keywords(self):
         self.assertIn("async", keyword.kwlist)
         self.assertIn("await", keyword.kwlist)
 
-    def test_match_and_case_are_soft_keywords(self):
+    def test_soft_keywords(self):
+        self.assertIn("type", keyword.softkwlist)
         self.assertIn("match", keyword.softkwlist)
         self.assertIn("case", keyword.softkwlist)
         self.assertIn("_", keyword.softkwlist)
diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py
index e1db450bf8a2..d81501f6f1df 100644
--- a/Lib/test/test_sys.py
+++ b/Lib/test/test_sys.py
@@ -1449,7 +1449,7 @@ def func():
         check(x, size('3Pi3c7P2ic??2P'))
         # function
         def func(): pass
-        check(func, size('14Pi'))
+        check(func, size('15Pi'))
         class c():
             @staticmethod
             def foo():
diff --git a/Lib/test/test_type_aliases.py b/Lib/test/test_type_aliases.py
new file mode 100644
index 000000000000..d2abb932f589
--- /dev/null
+++ b/Lib/test/test_type_aliases.py
@@ -0,0 +1,204 @@
+import types
+import unittest
+from test.support import check_syntax_error, run_code
+
+from typing import Callable, TypeAliasType, TypeVar, get_args
+
+
+class TypeParamsInvalidTest(unittest.TestCase):
+    def test_name_collision_01(self):
+        check_syntax_error(self, """type TA1[A, **A] = None""", "duplicate type parameter 'A'")
+
+    def test_name_non_collision_02(self):
+        ns = run_code("""type TA1[A] = lambda A: A""")
+        self.assertIsInstance(ns["TA1"], TypeAliasType)
+        self.assertTrue(callable(ns["TA1"].__value__))
+        self.assertEqual("arg", ns["TA1"].__value__("arg"))
+
+    def test_name_non_collision_03(self):
+        ns = run_code("""
+            class Outer[A]:
+                type TA1[A] = None
+            """
+        )
+        outer_A, = ns["Outer"].__type_params__
+        inner_A, = ns["Outer"].TA1.__type_params__
+        self.assertIsNot(outer_A, inner_A)
+
+
+class TypeParamsAccessTest(unittest.TestCase):
+    def test_alias_access_01(self):
+        ns = run_code("type TA1[A, B] = dict[A, B]")
+        alias = ns["TA1"]
+        self.assertIsInstance(alias, TypeAliasType)
+        self.assertEqual(alias.__type_params__, get_args(alias.__value__))
+
+    def test_alias_access_02(self):
+        ns = run_code("""
+            type TA1[A, B] = TA1[A, B] | int
+            """
+        )
+        alias = ns["TA1"]
+        self.assertIsInstance(alias, TypeAliasType)
+        A, B = alias.__type_params__
+        self.assertEqual(alias.__value__, alias[A, B] | int)
+
+    def test_alias_access_03(self):
+        ns = run_code("""
+            class Outer[A]:
+                def inner[B](self):
+                    type TA1[C] = TA1[A, B] | int
+                    return TA1
+            """
+        )
+        cls = ns["Outer"]
+        A, = cls.__type_params__
+        B, = cls.inner.__type_params__
+        alias = cls.inner(None)
+        self.assertIsInstance(alias, TypeAliasType)
+        alias2 = cls.inner(None)
+        self.assertIsNot(alias, alias2)
+        self.assertEqual(len(alias.__type_params__), 1)
+
+        self.assertEqual(alias.__value__, alias[A, B] | int)
+
+
+class TypeParamsAliasValueTest(unittest.TestCase):
+    def test_alias_value_01(self):
+        type TA1 = int
+
+        self.assertIsInstance(TA1, TypeAliasType)
+        self.assertEqual(TA1.__value__, int)
+        self.assertEqual(TA1.__parameters__, ())
+        self.assertEqual(TA1.__type_params__, ())
+
+        type TA2 = TA1 | str
+
+        self.assertIsInstance(TA2, TypeAliasType)
+        a, b = TA2.__value__.__args__
+        self.assertEqual(a, TA1)
+        self.assertEqual(b, str)
+        self.assertEqual(TA2.__parameters__, ())
+        self.assertEqual(TA2.__type_params__, ())
+
+    def test_alias_value_02(self):
+        class Parent[A]:
+            type TA1[B] = dict[A, B]
+
+        self.assertIsInstance(Parent.TA1, TypeAliasType)
+        self.assertEqual(len(Parent.TA1.__parameters__), 1)
+        self.assertEqual(len(Parent.__parameters__), 1)
+        a, = Parent.__parameters__
+        b, = Parent.TA1.__parameters__
+        self.assertEqual(Parent.__type_params__, (a,))
+        self.assertEqual(Parent.TA1.__type_params__, (b,))
+        self.assertEqual(Parent.TA1.__value__, dict[a, b])
+
+    def test_alias_value_03(self):
+        def outer[A]():
+            type TA1[B] = dict[A, B]
+            return TA1
+
+        o = outer()
+        self.assertIsInstance(o, TypeAliasType)
+        self.assertEqual(len(o.__parameters__), 1)
+        self.assertEqual(len(outer.__type_params__), 1)
+        b = o.__parameters__[0]
+        self.assertEqual(o.__type_params__, (b,))
+
+    def test_alias_value_04(self):
+        def more_generic[T, *Ts, **P]():
+            type TA[T2, *Ts2, **P2] = tuple[Callable[P, tuple[T, *Ts]], Callable[P2, tuple[T2, *Ts2]]]
+            return TA
+
+        alias = more_generic()
+        self.assertIsInstance(alias, TypeAliasType)
+        T2, Ts2, P2 = alias.__type_params__
+        self.assertEqual(alias.__parameters__, (T2, *Ts2, P2))
+        T, Ts, P = more_generic.__type_params__
+        self.assertEqual(alias.__value__, tuple[Callable[P, tuple[T, *Ts]], Callable[P2, tuple[T2, *Ts2]]])
+
+    def test_subscripting(self):
+        type NonGeneric = int
+        type Generic[A] = dict[A, A]
+        type VeryGeneric[T, *Ts, **P] = Callable[P, tuple[T, *Ts]]
+
+        with self.assertRaises(TypeError):
+            NonGeneric[int]
+
+        specialized = Generic[int]
+        self.assertIsInstance(specialized, types.GenericAlias)
+        self.assertIs(specialized.__origin__, Generic)
+        self.assertEqual(specialized.__args__, (int,))
+
+        specialized2 = VeryGeneric[int, str, float, [bool, range]]
+        self.assertIsInstance(specialized2, types.GenericAlias)
+        self.assertIs(specialized2.__origin__, VeryGeneric)
+        self.assertEqual(specialized2.__args__, (int, str, float, [bool, range]))
+
+    def test_repr(self):
+        type Simple = int
+        self.assertEqual(repr(Simple), "Simple")
+
+    def test_recursive_repr(self):
+        type Recursive = Recursive
+        self.assertEqual(repr(Recursive), "Recursive")
+
+        type X = list[Y]
+        type Y = list[X]
+        self.assertEqual(repr(X), "X")
+
+
+class TypeAliasConstructorTest(unittest.TestCase):
+    def test_basic(self):
+        TA = TypeAliasType("TA", int)
+        self.assertEqual(TA.__name__, "TA")
+        self.assertIs(TA.__value__, int)
+        self.assertEqual(TA.__type_params__, ())
+
+    def test_generic(self):
+        T = TypeVar("T")
+        TA = TypeAliasType("TA", list[T], type_params=(T,))
+        self.assertEqual(TA.__name__, "TA")
+        self.assertEqual(TA.__value__, list[T])
+        self.assertEqual(TA.__type_params__, (T,))
+
+    def test_keywords(self):
+        TA = TypeAliasType(name="TA", value=int)
+        self.assertEqual(TA.__name__, "TA")
+        self.assertIs(TA.__value__, int)
+        self.assertEqual(TA.__type_params__, ())
+
+    def test_errors(self):
+        with self.assertRaises(TypeError):
+            TypeAliasType()
+        with self.assertRaises(TypeError):
+            TypeAliasType("TA")
+        with self.assertRaises(TypeError):
+            TypeAliasType("TA", list, ())
+        with self.assertRaises(TypeError):
+            TypeAliasType("TA", list, type_params=42)
+
+
+class TypeAliasTypeTest(unittest.TestCase):
+    def test_immutable(self):
+        with self.assertRaises(TypeError):
+            TypeAliasType.whatever = "not allowed"
+
+    def test_no_subclassing(self):
+        with self.assertRaisesRegex(TypeError, "not an acceptable base type"):
+            class MyAlias(TypeAliasType):
+                pass
+
+    def test_union(self):
+        type Alias1 = int
+        type Alias2 = str
+        union = Alias1 | Alias2
+        self.assertIsInstance(union, types.UnionType)
+        self.assertEqual(get_args(union), (Alias1, Alias2))
+        union2 = Alias1 | list[float]
+        self.assertIsInstance(union2, types.UnionType)
+        self.assertEqual(get_args(union2), (Alias1, list[float]))
+        union3 = list[range] | Alias1
+        self.assertIsInstance(union3, types.UnionType)
+        self.assertEqual(get_args(union3), (list[range], Alias1))
diff --git a/Lib/test/test_type_params.py b/Lib/test/test_type_params.py
new file mode 100644
index 000000000000..3ca13c21c61a
--- /dev/null
+++ b/Lib/test/test_type_params.py
@@ -0,0 +1,847 @@
+import asyncio
+import textwrap
+import types
+import unittest
+from test.support import requires_working_socket, check_syntax_error, run_code
+
+from typing import Generic, Sequence, TypeVar, TypeVarTuple, ParamSpec, get_args
+
+
+class TypeParamsInvalidTest(unittest.TestCase):
+    def test_name_collision_01(self):
+        check_syntax_error(self, """def func[**A, A](): ...""")
+
+    def test_name_non_collision_02(self):
+        ns = run_code("""def func[A](A): return A""")
+        func = ns["func"]
+        self.assertEqual(func(1), 1)
+        A, = func.__type_params__
+        self.assertEqual(A.__name__, "A")
+
+    def test_name_non_collision_03(self):
+        ns = run_code("""def func[A](*A): return A""")
+        func = ns["func"]
+        self.assertEqual(func(1), (1,))
+        A, = func.__type_params__
+        self.assertEqual(A.__name__, "A")
+
+    def test_name_non_collision_04(self):
+        # Mangled names should not cause a conflict.
+        ns = run_code("""
+            class ClassA:
+                def func[__A](self, __A): return __A
+            """
+        )
+        cls = ns["ClassA"]
+        self.assertEqual(cls().func(1), 1)
+        A, = cls.func.__type_params__
+        self.assertEqual(A.__name__, "__A")
+
+    def test_name_non_collision_05(self):
+        ns = run_code("""
+            class ClassA:
+                def func[_ClassA__A](self, __A): return __A
+            """
+        )
+        cls = ns["ClassA"]
+        self.assertEqual(cls().func(1), 1)
+        A, = cls.func.__type_params__
+        self.assertEqual(A.__name__, "_ClassA__A")
+
+    def test_name_non_collision_06(self):
+        ns = run_code("""
+            class ClassA[X]:
+                def func(self, X): return X
+            """
+        )
+        cls = ns["ClassA"]
+        self.assertEqual(cls().func(1), 1)
+        X, = cls.__type_params__
+        self.assertEqual(X.__name__, "X")
+
+    def test_name_non_collision_07(self):
+        ns = run_code("""
+            class ClassA[X]:
+                def func(self):
+                    X = 1
+                    return X
+            """
+        )
+        cls = ns["ClassA"]
+        self.assertEqual(cls().func(), 1)
+        X, = cls.__type_params__
+        self.assertEqual(X.__name__, "X")
+
+    def test_name_non_collision_08(self):
+        ns = run_code("""
+            class ClassA[X]:
+                def func(self):
+                    return [X for X in [1, 2]]
+            """
+        )
+        cls = ns["ClassA"]
+        self.assertEqual(cls().func(), [1, 2])
+        X, = cls.__type_params__
+        self.assertEqual(X.__name__, "X")
+
+    def test_name_non_collision_9(self):
+        ns = run_code("""
+            class ClassA[X]:
+                def func[X](self):
+                    ...
+            """
+        )
+        cls = ns["ClassA"]
+        outer_X, = cls.__type_params__
+        inner_X, = cls.func.__type_params__
+        self.assertEqual(outer_X.__name__, "X")
+        self.assertEqual(inner_X.__name__, "X")
+        self.assertIsNot(outer_X, inner_X)
+
+    def test_name_non_collision_10(self):
+        ns = run_code("""
+            class ClassA[X]:
+                X: int
+            """
+        )
+        cls = ns["ClassA"]
+        X, = cls.__type_params__
+        self.assertEqual(X.__name__, "X")
+        self.assertIs(cls.__annotations__["X"], int)
+
+    def test_name_non_collision_13(self):
+        ns = run_code("""
+            X = 1
+            def outer():
+                def inner[X]():
+                    global X
+                    X = 2
+                return inner
+            """
+        )
+        self.assertEqual(ns["X"], 1)
+        outer = ns["outer"]
+        outer()()
+        self.assertEqual(ns["X"], 2)
+
+    def test_disallowed_expressions(self):
+        check_syntax_error(self, "type X = (yield)")
+        check_syntax_error(self, "type X = (yield from x)")
+        check_syntax_error(self, "type X = (await 42)")
+        check_syntax_error(self, "async def f(): type X = (yield)")
+        check_syntax_error(self, "type X = (y := 3)")
+        check_syntax_error(self, "class X[T: (yield)]: pass")
+        check_syntax_error(self, "class X[T: (yield from x)]: pass")
+        check_syntax_error(self, "class X[T: (await 42)]: pass")
+        check_syntax_error(self, "class X[T: (y := 3)]: pass")
+        check_syntax_error(self, "class X[T](y := Sequence[T]): pass")
+        check_syntax_error(self, "def f[T](y: (x := Sequence[T])): pass")
+
+
+class TypeParamsNonlocalTest(unittest.TestCase):
+    def test_nonlocal_disallowed_01(self):
+        code = """
+            def outer():
+                X = 1
+                def inner[X]():
+                    nonlocal X
+                return X
+            """
+        check_syntax_error(self, code)
+
+    def test_nonlocal_disallowed_02(self):
+        code = """
+            def outer2[T]():
+                def inner1():
+                    nonlocal T
+        """
+        check_syntax_error(self, textwrap.dedent(code))
+
+    def test_nonlocal_disallowed_03(self):
+        code = """
+            class Cls[T]:
+                nonlocal T
+        """
+        check_syntax_error(self, textwrap.dedent(code))
+
+    def test_nonlocal_allowed(self):
+        code = """
+            def func[T]():
+                T = "func"
+                def inner():
+                    nonlocal T
+                    T = "inner"
+                inner()
+                assert T == "inner"
+        """
+        ns = run_code(code)
+        func = ns["func"]
+        T, = func.__type_params__
+        self.assertEqual(T.__name__, "T")
+
+
+class TypeParamsAccessTest(unittest.TestCase):
+    def test_class_access_01(self):
+        ns = run_code("""
+            class ClassA[A, B](dict[A, B]):
+                ...
+            """
+        )
+        cls = ns["ClassA"]
+        A, B = cls.__type_params__
+        self.assertEqual(types.get_original_bases(cls), (dict[A, B], Generic[A, B]))
+
+    def test_class_access_02(self):
+        ns = run_code("""
+            class MyMeta[A, B](type): ...
+            class ClassA[A, B](metaclass=MyMeta[A, B]):
+                ...
+            """
+        )
+        meta = ns["MyMeta"]
+        cls = ns["ClassA"]
+        A1, B1 = meta.__type_params__
+        A2, B2 = cls.__type_params__
+        self.assertIsNot(A1, A2)
+        self.assertIsNot(B1, B2)
+        self.assertIs(type(cls), meta)
+
+    def test_class_access_03(self):
+        code = """
+            def my_decorator(a):
+                ...
+            @my_decorator(A)
+            class ClassA[A, B]():
+                ...
+            """
+
+        with self.assertRaisesRegex(NameError, "name 'A' is not defined"):
+            run_code(code)
+
+    def test_function_access_01(self):
+        ns = run_code("""
+            def func[A, B](a: dict[A, B]):
+                ...
+            """
+        )
+        func = ns["func"]
+        A, B = func.__type_params__
+        self.assertEqual(func.__annotations__["a"], dict[A, B])
+
+    def test_function_access_02(self):
+        code = """
+            def func[A](a = list[A]()):
+                ...
+            """
+
+        with self.assertRaisesRegex(NameError, "name 'A' is not defined"):
+            run_code(code)
+
+    def test_function_access_03(self):
+        code = """
+            def my_decorator(a):
+                ...
+            @my_decorator(A)
+            def func[A]():
+                ...
+            """
+
+        with self.assertRaisesRegex(NameError, "name 'A' is not defined"):
+            run_code(code)
+
+    def test_method_access_01(self):
+        ns = run_code("""
+            class ClassA:
+                x = int
+                def func[T](self, a: x, b: T):
+                    ...
+            """
+        )
+        cls = ns["ClassA"]
+        self.assertIs(cls.func.__annotations__["a"], int)
+        T, = cls.func.__type_params__
+        self.assertIs(cls.func.__annotations__["b"], T)
+
+    def test_nested_access_01(self):
+        ns = run_code("""
+            class ClassA[A]:
+                def funcB[B](self):
+                    class ClassC[C]:
+                        def funcD[D](self):
+                            return lambda: (A, B, C, D)
+                    return ClassC
+            """
+        )
+        cls = ns["ClassA"]
+        A, = cls.__type_params__
+        B, = cls.funcB.__type_params__
+        classC = cls().funcB()
+        C, = classC.__type_params__
+        D, = classC.funcD.__type_params__
+        self.assertEqual(classC().funcD()(), (A, B, C, D))
+
+    def test_out_of_scope_01(self):
+        code = """
+            class ClassA[T]: ...
+            x = T
+            """
+
+        with self.assertRaisesRegex(NameError, "name 'T' is not defined"):
+            run_code(code)
+
+    def test_out_of_scope_02(self):
+        code = """
+            class ClassA[A]:
+                def funcB[B](self): ...
+
+                x = B
+            """
+
+        with self.assertRaisesRegex(NameError, "name 'B' is not defined"):
+            run_code(code)
+
+    def test_class_scope_interaction_01(self):
+        ns = run_code("""
+            class C:
+                x = 1
+                def method[T](self, arg: x): pass
+        """)
+        cls = ns["C"]
+        self.assertEqual(cls.method.__annotations__["arg"], 1)
+
+    def test_class_scope_interaction_02(self):
+        ns = run_code("""
+            class C:
+                class Base: pass
+                class Child[T](Base): pass
+        """)
+        cls = ns["C"]
+        self.assertEqual(cls.Child.__bases__, (cls.Base, Generic))
+        T, = cls.Child.__type_params__
+        self.assertEqual(types.get_original_bases(cls.Child), (cls.Base, Generic[T]))
+
+    def test_class_deref(self):
+        ns = run_code("""
+            class C[T]:
+                T = "class"
+                type Alias = T
+        """)
+        cls = ns["C"]
+        self.assertEqual(cls.Alias.__value__, "class")
+
+    def test_shadowing_nonlocal(self):
+        ns = run_code("""
+            def outer[T]():
+                T = "outer"
+                def inner():
+                    nonlocal T
+                    T = "inner"
+                    return T
+                return lambda: T, inner
+        """)
+        outer = ns["outer"]
+        T, = outer.__type_params__
+        self.assertEqual(T.__name__, "T")
+        getter, inner = outer()
+        self.assertEqual(getter(), "outer")
+        self.assertEqual(inner(), "inner")
+        self.assertEqual(getter(), "inner")
+
+    def test_reference_previous_typevar(self):
+        def func[S, T: Sequence[S]]():
+            pass
+
+        S, T = func.__type_params__
+        self.assertEqual(T.__bound__, Sequence[S])
+
+    def test_super(self):
+        class Base:
+            def meth(self):
+                return "base"
+
+        class Child(Base):
+            # Having int in the annotation ensures the class gets cells for both
+            # __class__ and __classdict__
+            def meth[T](self, arg: int) -> T:
+                return super().meth() + "child"
+
+        c = Child()
+        self.assertEqual(c.meth(1), "basechild")
+
+    def test_type_alias_containing_lambda(self):
+        type Alias[T] = lambda: T
+        T, = Alias.__type_params__
+        self.assertIs(Alias.__value__(), T)
+
+    def test_class_base_containing_lambda(self):
+        # Test that scopes nested inside hidden functions work correctly
+        outer_var = "outer"
+        class Base[T]: ...
+        class Child[T](Base[lambda: (int, outer_var, T)]): ...
+        base, _ = types.get_original_bases(Child)
+        func, = get_args(base)
+        T, = Child.__type_params__
+        self.assertEqual(func(), (int, "outer", T))
+
+    def test_comprehension_01(self):
+        type Alias[T: ([T for T in (T, [1])[1]], T)] = [T for T in T.__name__]
+        self.assertEqual(Alias.__value__, ["T"])
+        T, = Alias.__type_params__
+        self.assertEqual(T.__constraints__, ([1], T))
+
+    def test_comprehension_02(self):
+        type Alias[T: [lambda: T for T in (T, [1])[1]]] = [lambda: T for T in T.__name__]
+        func, = Alias.__value__
+        self.assertEqual(func(), "T")
+        T, = Alias.__type_params__
+        func, = T.__bound__
+        self.assertEqual(func(), 1)
+
+
+def global_generic_func[T]():
+    pass
+
+class GlobalGenericClass[T]:
+    pass
+
+
+class TypeParamsLazyEvaluationTest(unittest.TestCase):
+    def test_qualname(self):
+        class Foo[T]:
+            pass
+
+        def func[T]():
+            pass
+
+        self.assertEqual(Foo.__qualname__, "TypeParamsLazyEvaluationTest.test_qualname.<locals>.Foo")
+        self.assertEqual(func.__qualname__, "TypeParamsLazyEvaluationTest.test_qualname.<locals>.func")
+        self.assertEqual(global_generic_func.__qualname__, "global_generic_func")
+        self.assertEqual(GlobalGenericClass.__qualname__, "GlobalGenericClass")
+
+    def test_recursive_class(self):
+        class Foo[T: Foo, U: (Foo, Foo)]:
+            pass
+
+        type_params = Foo.__type_params__
+        self.assertEqual(len(type_params), 2)
+        self.assertEqual(type_params[0].__name__, "T")
+        self.assertEqual(type_params[0].__bound__, Foo)
+        self.assertEqual(type_params[0].__constraints__, None)
+
+        self.assertEqual(type_params[1].__name__, "U")
+        self.assertEqual(type_params[1].__bound__, None)
+        self.assertEqual(type_params[1].__constraints__, (Foo, Foo))
+
+    def test_evaluation_error(self):
+        class Foo[T: Undefined, U: (Undefined,)]:
+            pass
+
+        type_params = Foo.__type_params__
+        with self.assertRaises(NameError):
+            type_params[0].__bound__
+        self.assertEqual(type_params[0].__constraints__, None)
+        self.assertEqual(type_params[1].__bound__, None)
+        with self.assertRaises(NameError):
+            type_params[1].__constraints__
+
+        Undefined = "defined"
+        self.assertEqual(type_params[0].__bound__, "defined")
+        self.assertEqual(type_params[0].__constraints__, None)
+
+        self.assertEqual(type_params[1].__bound__, None)
+        self.assertEqual(type_params[1].__constraints__, ("defined",))
+
+
+class TypeParamsClassScopeTest(unittest.TestCase):
+    def test_alias(self):
+        class X:
+            T = int
+            type U = T
+        self.assertIs(X.U.__value__, int)
+
+        ns = run_code("""
+            glb = "global"
+            class X:
+                cls = "class"
+                type U = (glb, cls)
+        """)
+        cls = ns["X"]
+        self.assertEqual(cls.U.__value__, ("global", "class"))
+
+    def test_bound(self):
+        class X:
+            T = int
+            def foo[U: T](self): ...
+        self.assertIs(X.foo.__type_params__[0].__bound__, int)
+
+        ns = run_code("""
+            glb = "global"
+            class X:
+                cls = "class"
+                def foo[T: glb, U: cls](self): ...
+        """)
+        cls = ns["X"]
+        T, U = cls.foo.__type_params__
+        self.assertEqual(T.__bound__, "global")
+        self.assertEqual(U.__bound__, "class")
+
+    def test_modified_later(self):
+        class X:
+            T = int
+            def foo[U: T](self): ...
+            type Alias = T
+        X.T = float
+        self.assertIs(X.foo.__type_params__[0].__bound__, float)
+        self.assertIs(X.Alias.__value__, float)
+
+    def test_binding_uses_global(self):
+        ns = run_code("""
+            x = "global"
+            def outer():
+                x = "nonlocal"
+                class Cls:
+                    type Alias = x
+                    val = Alias.__value__
+                    def meth[T: x](self, arg: x): ...
+                    bound = meth.__type_params__[0].__bound__
+                    annotation = meth.__annotations__["arg"]
+                    x = "class"
+                return Cls
+        """)
+        cls = ns["outer"]()
+        self.assertEqual(cls.val, "global")
+        self.assertEqual(cls.bound, "global")
+        self.assertEqual(cls.annotation, "global")
+
+    def test_no_binding_uses_nonlocal(self):
+        ns = run_code("""
+            x = "global"
+            def outer():
+                x = "nonlocal"
+                class Cls:
+                    type Alias = x
+                    val = Alias.__value__
+                    def meth[T: x](self, arg: x): ...
+                    bound = meth.__type_params__[0].__bound__
+                return Cls
+        """)
+        cls = ns["outer"]()
+        self.assertEqual(cls.val, "nonlocal")
+        self.assertEqual(cls.bound, "nonlocal")
+        self.assertEqual(cls.meth.__annotations__["arg"], "nonlocal")
+
+    def test_explicit_global(self):
+        ns = run_code("""
+            x = "global"
+            def outer():
+                x = "nonlocal"
+                class Cls:
+                    global x
+                    type Alias = x
+                Cls.x = "class"
+                return Cls
+        """)
+        cls = ns["outer"]()
+        self.assertEqual(cls.Alias.__value__, "global")
+
+    def test_explicit_global_with_no_static_bound(self):
+        ns = run_code("""
+            def outer():
+                class Cls:
+                    global x
+                    type Alias = x
+                Cls.x = "class"
+                return Cls
+        """)
+        ns["x"] = "global"
+        cls = ns["outer"]()
+        self.assertEqual(cls.Alias.__value__, "global")
+
+    def test_explicit_global_with_assignment(self):
+        ns = run_code("""
+            x = "global"
+            def outer():
+                x = "nonlocal"
+                class Cls:
+                    global x
+                    type Alias = x
+                    x = "global from class"
+                Cls.x = "class"
+                return Cls
+        """)
+        cls = ns["outer"]()
+        self.assertEqual(cls.Alias.__value__, "global from class")
+
+    def test_explicit_nonlocal(self):
+        ns = run_code("""
+            x = "global"
+            def outer():
+                x = "nonlocal"
+                class Cls:
+                    nonlocal x
+                    type Alias = x
+                    x = "class"
+                return Cls
+        """)
+        cls = ns["outer"]()
+        self.assertEqual(cls.Alias.__value__, "class")
+
+
+class TypeParamsManglingTest(unittest.TestCase):
+    def test_mangling(self):
+        class Foo[__T]:
+            param = __T
+            def meth[__U](self, arg: __T, arg2: __U):
+                return (__T, __U)
+            type Alias[__V] = (__T, __V)
+
+        T = Foo.__type_params__[0]
+        self.assertEqual(T.__name__, "__T")
+        U = Foo.meth.__type_params__[0]
+        self.assertEqual(U.__name__, "__U")
+        V = Foo.Alias.__type_params__[0]
+        self.assertEqual(V.__name__, "__V")
+
+        anno = Foo.meth.__annotations__
+        self.assertIs(anno["arg"], T)
+        self.assertIs(anno["arg2"], U)
+        self.assertEqual(Foo().meth(1, 2), (T, U))
+
+        self.assertEqual(Foo.Alias.__value__, (T, V))
+
+
+class TypeParamsComplexCallsTest(unittest.TestCase):
+    def test_defaults(self):
+        # Generic functions with both defaults and kwdefaults trigger a specific code path
+        # in the compiler.
+        def func[T](a: T = "a", *, b: T = "b"):
+            return (a, b)
+
+        T, = func.__type_params__
+        self.assertIs(func.__annotations__["a"], T)
+        self.assertIs(func.__annotations__["b"], T)
+        self.assertEqual(func(), ("a", "b"))
+        self.assertEqual(func(1), (1, "b"))
+        self.assertEqual(func(b=2), ("a", 2))
+
+    def test_complex_base(self):
+        class Base:
+            def __init_subclass__(cls, **kwargs) -> None:
+                cls.kwargs = kwargs
+
+        kwargs = {"c": 3}
+        # Base classes with **kwargs trigger a different code path in the compiler.
+        class C[T](Base, a=1, b=2, **kwargs):
+            pass
+
+        T, = C.__type_params__
+        self.assertEqual(T.__name__, "T")
+        self.assertEqual(C.kwargs, {"a": 1, "b": 2, "c": 3})
+
+        bases = (Base,)
+        class C2[T](*bases, **kwargs):
+            pass
+
+        T, = C2.__type_params__
+        self.assertEqual(T.__name__, "T")
+        self.assertEqual(C2.kwargs, {"c": 3})
+
+
+class TypeParamsTraditionalTypeVarsTest(unittest.TestCase):
+    def test_traditional_01(self):
+        code = """
+            from typing import Generic
+            class ClassA[T](Generic[T]): ...
+        """
+
+        with self.assertRaisesRegex(TypeError, r"Cannot inherit from Generic\[...\] multiple times."):
+            run_code(code)
+
+    def test_traditional_02(self):
+        from typing import TypeVar
+        S = TypeVar("S")
+        with self.assertRaises(TypeError):
+            class ClassA[T](dict[T, S]): ...
+
+    def test_traditional_03(self):
+        # This does not generate a runtime error, but it should be
+        # flagged as an error by type checkers.
+        from typing import TypeVar
+        S = TypeVar("S")
+        def func[T](a: T, b: S) -> T | S:
+            return a
+
+
+class TypeParamsTypeVarTest(unittest.TestCase):
+    def test_typevar_01(self):
+        def func1[A: str, B: str | int, C: (int, str)]():
+            return (A, B, C)
+
+        a, b, c = func1()
+
+        self.assertIsInstance(a, TypeVar)
+        self.assertEqual(a.__bound__, str)
+        self.assertTrue(a.__infer_variance__)
+        self.assertFalse(a.__covariant__)
+        self.assertFalse(a.__contravariant__)
+
+        self.assertIsInstance(b, TypeVar)
+        self.assertEqual(b.__bound__, str | int)
+        self.assertTrue(b.__infer_variance__)
+        self.assertFalse(b.__covariant__)
+        self.assertFalse(b.__contravariant__)
+
+        self.assertIsInstance(c, TypeVar)
+        self.assertEqual(c.__bound__, None)
+        self.assertEqual(c.__constraints__, (int, str))
+        self.assertTrue(c.__infer_variance__)
+        self.assertFalse(c.__covariant__)
+        self.assertFalse(c.__contravariant__)
+
+    def test_typevar_generator(self):
+        def get_generator[A]():
+            def generator1[C]():
+                yield C
+
+            def generator2[B]():
+                yield A
+                yield B
+                yield from generator1()
+            return generator2
+
+        gen = get_generator()
+
+        a, b, c = [x for x in gen()]
+
+        self.assertIsInstance(a, TypeVar)
+        self.assertEqual(a.__name__, "A")
+        self.assertIsInstance(b, TypeVar)
+        self.assertEqual(b.__name__, "B")
+        self.assertIsInstance(c, TypeVar)
+        self.assertEqual(c.__name__, "C")
+
+    @requires_working_socket()
+    def test_typevar_coroutine(self):
+        def get_coroutine[A]():
+            async def coroutine[B]():
+                return (A, B)
+            return coroutine
+
+        co = get_coroutine()
+
+        self.addCleanup(asyncio.set_event_loop_policy, None)
+        a, b = asyncio.run(co())
+
+        self.assertIsInstance(a, TypeVar)
+        self.assertEqual(a.__name__, "A")
+        self.assertIsInstance(b, TypeVar)
+        self.assertEqual(b.__name__, "B")
+
+
+class TypeParamsTypeVarTupleTest(unittest.TestCase):
+    def test_typevartuple_01(self):
+        code = """def func1[*A: str](): pass"""
+        check_syntax_error(self, code, "cannot use bound with TypeVarTuple")
+        code = """def func1[*A: (int, str)](): pass"""
+        check_syntax_error(self, code, "cannot use constraints with TypeVarTuple")
+        code = """class X[*A: str]: pass"""
+        check_syntax_error(self, code, "cannot use bound with TypeVarTuple")
+        code = """class X[*A: (int, str)]: pass"""
+        check_syntax_error(self, code, "cannot use constraints with TypeVarTuple")
+        code = """type X[*A: str] = int"""
+        check_syntax_error(self, code, "cannot use bound with TypeVarTuple")
+        code = """type X[*A: (int, str)] = int"""
+        check_syntax_error(self, code, "cannot use constraints with TypeVarTuple")
+
+    def test_typevartuple_02(self):
+        def func1[*A]():
+            return A
+
+        a = func1()
+        self.assertIsInstance(a, TypeVarTuple)
+
+
+class TypeParamsTypeVarParamSpecTest(unittest.TestCase):
+    def test_paramspec_01(self):
+        code = """def func1[**A: str](): pass"""
+        check_syntax_error(self, code, "cannot use bound with ParamSpec")
+        code = """def func1[**A: (int, str)](): pass"""
+        check_syntax_error(self, code, "cannot use constraints with ParamSpec")
+        code = """class X[**A: str]: pass"""
+        check_syntax_error(self, code, "cannot use bound with ParamSpec")
+        code = """class X[**A: (int, str)]: pass"""
+        check_syntax_error(self, code, "cannot use constraints with ParamSpec")
+        code = """type X[**A: str] = int"""
+        check_syntax_error(self, code, "cannot use bound with ParamSpec")
+        code = """type X[**A: (int, str)] = int"""
+        check_syntax_error(self, code, "cannot use constraints with ParamSpec")
+
+    def test_paramspec_02(self):
+        def func1[**A]():
+            return A
+
+        a = func1()
+        self.assertIsInstance(a, ParamSpec)
+        self.assertTrue(a.__infer_variance__)
+        self.assertFalse(a.__covariant__)
+        self.assertFalse(a.__contravariant__)
+
+
+class TypeParamsTypeParamsDunder(unittest.TestCase):
+    def test_typeparams_dunder_class_01(self):
+        class Outer[A, B]:
+            class Inner[C, D]:
+                @staticmethod
+                def get_typeparams():
+                    return A, B, C, D
+
+        a, b, c, d = Outer.Inner.get_typeparams()
+        self.assertEqual(Outer.__type_params__, (a, b))
+        self.assertEqual(Outer.Inner.__type_params__, (c, d))
+
+        self.assertEqual(Outer.__parameters__, (a, b))
+        self.assertEqual(Outer.Inner.__parameters__, (c, d))
+
+    def test_typeparams_dunder_class_02(self):
+        class ClassA:
+            pass
+
+        self.assertEqual(ClassA.__type_params__, ())
+
+    def test_typeparams_dunder_class_03(self):
+        code = """
+            class ClassA[A]():
+                pass
+            ClassA.__type_params__ = ()
+        """
+
+        with self.assertRaisesRegex(AttributeError, "attribute '__type_params__' of 'type' objects is not writable"):
+            run_code(code)
+
+    def test_typeparams_dunder_function_01(self):
+        def outer[A, B]():
+            def inner[C, D]():
+                return A, B, C, D
+
+            return inner
+
+        inner = outer()
+        a, b, c, d = inner()
+        self.assertEqual(outer.__type_params__, (a, b))
+        self.assertEqual(inner.__type_params__, (c, d))
+
+    def test_typeparams_dunder_function_02(self):
+        def func1():
+            pass
+
+        self.assertEqual(func1.__type_params__, ())
+
+    def test_typeparams_dunder_function_03(self):
+        code = """
+            def func[A]():
+                pass
+            func.__type_params__ = ()
+        """
+
+        with self.assertRaisesRegex(AttributeError, "attribute '__type_params__' of 'function' objects is not writable"):
+            run_code(code)
diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py
index e1c6a8a7f376..71aff87dcaa3 100644
--- a/Lib/test/test_typing.py
+++ b/Lib/test/test_typing.py
@@ -48,11 +48,8 @@
 from test import _typed_dict_helper
 
 
-py_typing = import_helper.import_fresh_module('typing', blocked=['_typing'])
-c_typing = import_helper.import_fresh_module('typing', fresh=['_typing'])
-
-
 CANNOT_SUBCLASS_TYPE = 'Cannot subclass special typing classes'
+NOT_A_BASE_TYPE = "type 'typing.%s' is not an acceptable base type"
 CANNOT_SUBCLASS_INSTANCE = 'Cannot subclass an instance of %s'
 
 
@@ -430,7 +427,7 @@ def test_no_redefinition(self):
         self.assertNotEqual(TypeVar('T', int, str), TypeVar('T', int, str))
 
     def test_cannot_subclass(self):
-        with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE):
+        with self.assertRaisesRegex(TypeError, NOT_A_BASE_TYPE % 'TypeVar'):
             class V(TypeVar): pass
         T = TypeVar("T")
         with self.assertRaisesRegex(TypeError,
@@ -446,6 +443,9 @@ def test_bound_errors(self):
             TypeVar('X', bound=Union)
         with self.assertRaises(TypeError):
             TypeVar('X', str, float, bound=Employee)
+        with self.assertRaisesRegex(TypeError,
+                                    r"Bound must be a type\. Got \(1, 2\)\."):
+            TypeVar('X', bound=(1, 2))
 
     def test_missing__name__(self):
         # See bpo-39942
@@ -1161,7 +1161,7 @@ class A(Generic[Unpack[Ts]]): pass
         self.assertEndsWith(repr(K[float, str]), 'A[float, str, typing.Unpack[typing.Tuple[str, ...]]]')
 
     def test_cannot_subclass(self):
-        with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE):
+        with self.assertRaisesRegex(TypeError, NOT_A_BASE_TYPE % 'TypeVarTuple'):
             class C(TypeVarTuple): pass
         Ts = TypeVarTuple('Ts')
         with self.assertRaisesRegex(TypeError,
@@ -6444,34 +6444,27 @@ def foo(a: A) -> Optional[BaseException]:
 class TestModules(TestCase):
     func_names = ['_idfunc']
 
-    def test_py_functions(self):
-        for fname in self.func_names:
-            self.assertEqual(getattr(py_typing, fname).__module__, 'typing')
-
-    @skipUnless(c_typing, 'requires _typing')
     def test_c_functions(self):
         for fname in self.func_names:
-            self.assertEqual(getattr(c_typing, fname).__module__, '_typing')
+            self.assertEqual(getattr(typing, fname).__module__, '_typing')
 
 
-class NewTypeTests:
+class NewTypeTests(BaseTestCase):
     def cleanup(self):
-        for f in self.module._cleanups:
+        for f in typing._cleanups:
             f()
 
     @classmethod
     def setUpClass(cls):
-        sys.modules['typing'] = cls.module
         global UserId
-        UserId = cls.module.NewType('UserId', int)
-        cls.UserName = cls.module.NewType(cls.__qualname__ + '.UserName', str)
+        UserId = typing.NewType('UserId', int)
+        cls.UserName = typing.NewType(cls.__qualname__ + '.UserName', str)
 
     @classmethod
     def tearDownClass(cls):
         global UserId
         del UserId
         del cls.UserName
-        sys.modules['typing'] = typing
 
     def tearDown(self):
         self.cleanup()
@@ -6491,11 +6484,11 @@ class D(UserId):
     def test_or(self):
         for cls in (int, self.UserName):
             with self.subTest(cls=cls):
-                self.assertEqual(UserId | cls, self.module.Union[UserId, cls])
-                self.assertEqual(cls | UserId, self.module.Union[cls, UserId])
+                self.assertEqual(UserId | cls, typing.Union[UserId, cls])
+                self.assertEqual(cls | UserId, typing.Union[cls, UserId])
 
-                self.assertEqual(self.module.get_args(UserId | cls), (UserId, cls))
-                self.assertEqual(self.module.get_args(cls | UserId), (cls, UserId))
+                self.assertEqual(typing.get_args(UserId | cls), (UserId, cls))
+                self.assertEqual(typing.get_args(cls | UserId), (cls, UserId))
 
     def test_special_attrs(self):
         self.assertEqual(UserId.__name__, 'UserId')
@@ -6516,7 +6509,7 @@ def test_repr(self):
                          f'{__name__}.{self.__class__.__qualname__}.UserName')
 
     def test_pickle(self):
-        UserAge = self.module.NewType('UserAge', float)
+        UserAge = typing.NewType('UserAge', float)
         for proto in range(pickle.HIGHEST_PROTOCOL + 1):
             with self.subTest(proto=proto):
                 pickled = pickle.dumps(UserId, proto)
@@ -6548,15 +6541,6 @@ class ProUserId(UserId):
                 ...
 
 
-class NewTypePythonTests(NewTypeTests, BaseTestCase):
-    module = py_typing
-
-
- at skipUnless(c_typing, 'requires _typing')
-class NewTypeCTests(NewTypeTests, BaseTestCase):
-    module = c_typing
-
-
 class NamedTupleTests(BaseTestCase):
     class NestedEmployee(NamedTuple):
         name: str
@@ -8170,11 +8154,11 @@ def test_paramspec_gets_copied(self):
         self.assertEqual(C2[Concatenate[T, P2]].__parameters__, (T, P2))
 
     def test_cannot_subclass(self):
-        with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE):
+        with self.assertRaisesRegex(TypeError, NOT_A_BASE_TYPE % 'ParamSpec'):
             class C(ParamSpec): pass
-        with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE):
+        with self.assertRaisesRegex(TypeError, NOT_A_BASE_TYPE % 'ParamSpecArgs'):
             class C(ParamSpecArgs): pass
-        with self.assertRaisesRegex(TypeError, CANNOT_SUBCLASS_TYPE):
+        with self.assertRaisesRegex(TypeError, NOT_A_BASE_TYPE % 'ParamSpecKwargs'):
             class C(ParamSpecKwargs): pass
         P = ParamSpec('P')
         with self.assertRaisesRegex(TypeError,
diff --git a/Lib/typing.py b/Lib/typing.py
index 61aed0980ac2..8d132e2cbf87 100644
--- a/Lib/typing.py
+++ b/Lib/typing.py
@@ -23,6 +23,7 @@
 import collections
 from collections import defaultdict
 import collections.abc
+import copyreg
 import contextlib
 import functools
 import operator
@@ -32,12 +33,16 @@
 import warnings
 from types import WrapperDescriptorType, MethodWrapperType, MethodDescriptorType, GenericAlias
 
-
-try:
-    from _typing import _idfunc
-except ImportError:
-    def _idfunc(_, x):
-        return x
+from _typing import (
+    _idfunc,
+    TypeVar,
+    ParamSpec,
+    TypeVarTuple,
+    ParamSpecArgs,
+    ParamSpecKwargs,
+    TypeAliasType,
+    Generic,
+)
 
 # Please keep __all__ alphabetized within each category.
 __all__ = [
@@ -149,6 +154,7 @@ def _idfunc(_, x):
     'TYPE_CHECKING',
     'TypeAlias',
     'TypeGuard',
+    'TypeAliasType',
     'Unpack',
 ]
 
@@ -695,6 +701,15 @@ def Union(self, parameters):
         return _UnionGenericAlias(self, parameters, name="Optional")
     return _UnionGenericAlias(self, parameters)
 
+def _make_union(left, right):
+    """Used from the C implementation of TypeVar.
+
+    TypeVar.__or__ calls this instead of returning types.UnionType
+    because we want to allow unions between TypeVars and strings
+    (forward references.)
+    """
+    return Union[left, right]
+
 @_SpecialForm
 def Optional(self, parameters):
     """Optional type.
@@ -926,333 +941,162 @@ def __reduce__(self):
         return self.__name__
 
 
-class _BoundVarianceMixin:
-    """Mixin giving __init__ bound and variance arguments.
-
-    This is used by TypeVar and ParamSpec, which both employ the notions of
-    a type 'bound' (restricting type arguments to be a subtype of some
-    specified type) and type 'variance' (determining subtype relations between
-    generic types).
-    """
-    def __init__(self, bound, covariant, contravariant):
-        """Used to setup TypeVars and ParamSpec's bound, covariant and
-        contravariant attributes.
-        """
-        if covariant and contravariant:
-            raise ValueError("Bivariant types are not supported.")
-        self.__covariant__ = bool(covariant)
-        self.__contravariant__ = bool(contravariant)
-        if bound:
-            self.__bound__ = _type_check(bound, "Bound must be a type.")
-        else:
-            self.__bound__ = None
-
-    def __or__(self, right):
-        return Union[self, right]
-
-    def __ror__(self, left):
-        return Union[left, self]
-
-    def __repr__(self):
-        if self.__covariant__:
-            prefix = '+'
-        elif self.__contravariant__:
-            prefix = '-'
-        else:
-            prefix = '~'
-        return prefix + self.__name__
-
-    def __mro_entries__(self, bases):
-        raise TypeError(f"Cannot subclass an instance of {type(self).__name__}")
-
-
-class TypeVar(_Final, _Immutable, _BoundVarianceMixin, _PickleUsingNameMixin,
-              _root=True):
-    """Type variable.
-
-    Usage::
-
-      T = TypeVar('T')  # Can be anything
-      A = TypeVar('A', str, bytes)  # Must be str or bytes
-
-    Type variables exist primarily for the benefit of static type
-    checkers.  They serve as the parameters for generic types as well
-    as for generic function definitions.  See class Generic for more
-    information on generic types.  Generic functions work as follows:
-
-      def repeat(x: T, n: int) -> List[T]:
-          '''Return a list containing n references to x.'''
-          return [x]*n
-
-      def longest(x: A, y: A) -> A:
-          '''Return the longest of two strings.'''
-          return x if len(x) >= len(y) else y
-
-    The latter example's signature is essentially the overloading
-    of (str, str) -> str and (bytes, bytes) -> bytes.  Also note
-    that if the arguments are instances of some subclass of str,
-    the return type is still plain str.
-
-    At runtime, isinstance(x, T) and issubclass(C, T) will raise TypeError.
-
-    Type variables defined with covariant=True or contravariant=True
-    can be used to declare covariant or contravariant generic types.
-    See PEP 484 for more details. By default generic types are invariant
-    in all type variables.
-
-    Type variables can be introspected. e.g.:
-
-      T.__name__ == 'T'
-      T.__constraints__ == ()
-      T.__covariant__ == False
-      T.__contravariant__ = False
-      A.__constraints__ == (str, bytes)
-
-    Note that only type variables defined in global scope can be pickled.
-    """
-
-    def __init__(self, name, *constraints, bound=None,
-                 covariant=False, contravariant=False):
-        self.__name__ = name
-        super().__init__(bound, covariant, contravariant)
-        if constraints and bound is not None:
-            raise TypeError("Constraints cannot be combined with bound=...")
-        if constraints and len(constraints) == 1:
-            raise TypeError("A single constraint is not allowed")
-        msg = "TypeVar(name, constraint, ...): constraints must be types."
-        self.__constraints__ = tuple(_type_check(t, msg) for t in constraints)
-        def_mod = _caller()
-        if def_mod != 'typing':
-            self.__module__ = def_mod
+def _typevar_subst(self, arg):
+    msg = "Parameters to generic types must be types."
+    arg = _type_check(arg, msg, is_argument=True)
+    if ((isinstance(arg, _GenericAlias) and arg.__origin__ is Unpack) or
+        (isinstance(arg, GenericAlias) and getattr(arg, '__unpacked__', False))):
+        raise TypeError(f"{arg} is not valid as type argument")
+    return arg
 
-    def __typing_subst__(self, arg):
-        msg = "Parameters to generic types must be types."
-        arg = _type_check(arg, msg, is_argument=True)
-        if ((isinstance(arg, _GenericAlias) and arg.__origin__ is Unpack) or
-            (isinstance(arg, GenericAlias) and getattr(arg, '__unpacked__', False))):
-            raise TypeError(f"{arg} is not valid as type argument")
-        return arg
 
+def _typevartuple_prepare_subst(self, alias, args):
+    params = alias.__parameters__
+    typevartuple_index = params.index(self)
+    for param in params[typevartuple_index + 1:]:
+        if isinstance(param, TypeVarTuple):
+            raise TypeError(f"More than one TypeVarTuple parameter in {alias}")
+
+    alen = len(args)
+    plen = len(params)
+    left = typevartuple_index
+    right = plen - typevartuple_index - 1
+    var_tuple_index = None
+    fillarg = None
+    for k, arg in enumerate(args):
+        if not isinstance(arg, type):
+            subargs = getattr(arg, '__typing_unpacked_tuple_args__', None)
+            if subargs and len(subargs) == 2 and subargs[-1] is ...:
+                if var_tuple_index is not None:
+                    raise TypeError("More than one unpacked arbitrary-length tuple argument")
+                var_tuple_index = k
+                fillarg = subargs[0]
+    if var_tuple_index is not None:
+        left = min(left, var_tuple_index)
+        right = min(right, alen - var_tuple_index - 1)
+    elif left + right > alen:
+        raise TypeError(f"Too few arguments for {alias};"
+                        f" actual {alen}, expected at least {plen-1}")
 
-class TypeVarTuple(_Final, _Immutable, _PickleUsingNameMixin, _root=True):
-    """Type variable tuple.
+    return (
+        *args[:left],
+        *([fillarg]*(typevartuple_index - left)),
+        tuple(args[left: alen - right]),
+        *([fillarg]*(plen - right - left - typevartuple_index - 1)),
+        *args[alen - right:],
+    )
 
-    Usage:
 
-      Ts = TypeVarTuple('Ts')  # Can be given any name
+def _paramspec_subst(self, arg):
+    if isinstance(arg, (list, tuple)):
+        arg = tuple(_type_check(a, "Expected a type.") for a in arg)
+    elif not _is_param_expr(arg):
+        raise TypeError(f"Expected a list of types, an ellipsis, "
+                        f"ParamSpec, or Concatenate. Got {arg}")
+    return arg
 
-    Just as a TypeVar (type variable) is a placeholder for a single type,
-    a TypeVarTuple is a placeholder for an *arbitrary* number of types. For
-    example, if we define a generic class using a TypeVarTuple:
 
-      class C(Generic[*Ts]): ...
+def _paramspec_prepare_subst(self, alias, args):
+    params = alias.__parameters__
+    i = params.index(self)
+    if i >= len(args):
+        raise TypeError(f"Too few arguments for {alias}")
+    # Special case where Z[[int, str, bool]] == Z[int, str, bool] in PEP 612.
+    if len(params) == 1 and not _is_param_expr(args[0]):
+        assert i == 0
+        args = (args,)
+    # Convert lists to tuples to help other libraries cache the results.
+    elif isinstance(args[i], list):
+        args = (*args[:i], tuple(args[i]), *args[i+1:])
+    return args
 
-    Then we can parameterize that class with an arbitrary number of type
-    arguments:
 
-      C[int]       # Fine
-      C[int, str]  # Also fine
-      C[()]        # Even this is fine
+ at _tp_cache
+def _generic_class_getitem(cls, params):
+    """Parameterizes a generic class.
 
-    For more details, see PEP 646.
+    At least, parameterizing a generic class is the *main* thing this method
+    does. For example, for some generic class `Foo`, this is called when we
+    do `Foo[int]` - there, with `cls=Foo` and `params=int`.
 
-    Note that only TypeVarTuples defined in global scope can be pickled.
+    However, note that this method is also called when defining generic
+    classes in the first place with `class Foo(Generic[T]): ...`.
     """
+    if not isinstance(params, tuple):
+        params = (params,)
 
-    def __init__(self, name):
-        self.__name__ = name
-
-        # Used for pickling.
-        def_mod = _caller()
-        if def_mod != 'typing':
-            self.__module__ = def_mod
-
-    def __iter__(self):
-        yield Unpack[self]
-
-    def __repr__(self):
-        return self.__name__
+    params = tuple(_type_convert(p) for p in params)
+    is_generic_or_protocol = cls in (Generic, Protocol)
 
-    def __typing_subst__(self, arg):
-        raise TypeError("Substitution of bare TypeVarTuple is not supported")
+    if is_generic_or_protocol:
+        # Generic and Protocol can only be subscripted with unique type variables.
+        if not params:
+            raise TypeError(
+                f"Parameter list to {cls.__qualname__}[...] cannot be empty"
+            )
+        if not all(_is_typevar_like(p) for p in params):
+            raise TypeError(
+                f"Parameters to {cls.__name__}[...] must all be type variables "
+                f"or parameter specification variables.")
+        if len(set(params)) != len(params):
+            raise TypeError(
+                f"Parameters to {cls.__name__}[...] must all be unique")
+    else:
+        # Subscripting a regular Generic subclass.
+        for param in cls.__parameters__:
+            prepare = getattr(param, '__typing_prepare_subst__', None)
+            if prepare is not None:
+                params = prepare(cls, params)
+        _check_generic(cls, params, len(cls.__parameters__))
 
-    def __typing_prepare_subst__(self, alias, args):
-        params = alias.__parameters__
-        typevartuple_index = params.index(self)
-        for param in params[typevartuple_index + 1:]:
+        new_args = []
+        for param, new_arg in zip(cls.__parameters__, params):
             if isinstance(param, TypeVarTuple):
-                raise TypeError(f"More than one TypeVarTuple parameter in {alias}")
-
-        alen = len(args)
-        plen = len(params)
-        left = typevartuple_index
-        right = plen - typevartuple_index - 1
-        var_tuple_index = None
-        fillarg = None
-        for k, arg in enumerate(args):
-            if not isinstance(arg, type):
-                subargs = getattr(arg, '__typing_unpacked_tuple_args__', None)
-                if subargs and len(subargs) == 2 and subargs[-1] is ...:
-                    if var_tuple_index is not None:
-                        raise TypeError("More than one unpacked arbitrary-length tuple argument")
-                    var_tuple_index = k
-                    fillarg = subargs[0]
-        if var_tuple_index is not None:
-            left = min(left, var_tuple_index)
-            right = min(right, alen - var_tuple_index - 1)
-        elif left + right > alen:
-            raise TypeError(f"Too few arguments for {alias};"
-                            f" actual {alen}, expected at least {plen-1}")
-
-        return (
-            *args[:left],
-            *([fillarg]*(typevartuple_index - left)),
-            tuple(args[left: alen - right]),
-            *([fillarg]*(plen - right - left - typevartuple_index - 1)),
-            *args[alen - right:],
-        )
-
-    def __mro_entries__(self, bases):
-        raise TypeError(f"Cannot subclass an instance of {type(self).__name__}")
-
-
-class ParamSpecArgs(_Final, _Immutable, _root=True):
-    """The args for a ParamSpec object.
-
-    Given a ParamSpec object P, P.args is an instance of ParamSpecArgs.
-
-    ParamSpecArgs objects have a reference back to their ParamSpec:
-
-       P.args.__origin__ is P
-
-    This type is meant for runtime introspection and has no special meaning to
-    static type checkers.
-    """
-    def __init__(self, origin):
-        self.__origin__ = origin
-
-    def __repr__(self):
-        return f"{self.__origin__.__name__}.args"
-
-    def __eq__(self, other):
-        if not isinstance(other, ParamSpecArgs):
-            return NotImplemented
-        return self.__origin__ == other.__origin__
-
-    def __mro_entries__(self, bases):
-        raise TypeError(f"Cannot subclass an instance of {type(self).__name__}")
-
-
-class ParamSpecKwargs(_Final, _Immutable, _root=True):
-    """The kwargs for a ParamSpec object.
-
-    Given a ParamSpec object P, P.kwargs is an instance of ParamSpecKwargs.
-
-    ParamSpecKwargs objects have a reference back to their ParamSpec:
-
-       P.kwargs.__origin__ is P
-
-    This type is meant for runtime introspection and has no special meaning to
-    static type checkers.
-    """
-    def __init__(self, origin):
-        self.__origin__ = origin
-
-    def __repr__(self):
-        return f"{self.__origin__.__name__}.kwargs"
-
-    def __eq__(self, other):
-        if not isinstance(other, ParamSpecKwargs):
-            return NotImplemented
-        return self.__origin__ == other.__origin__
-
-    def __mro_entries__(self, bases):
-        raise TypeError(f"Cannot subclass an instance of {type(self).__name__}")
-
-
-class ParamSpec(_Final, _Immutable, _BoundVarianceMixin, _PickleUsingNameMixin,
-                _root=True):
-    """Parameter specification variable.
-
-    Usage::
-
-       P = ParamSpec('P')
-
-    Parameter specification variables exist primarily for the benefit of static
-    type checkers.  They are used to forward the parameter types of one
-    callable to another callable, a pattern commonly found in higher order
-    functions and decorators.  They are only valid when used in ``Concatenate``,
-    or as the first argument to ``Callable``, or as parameters for user-defined
-    Generics.  See class Generic for more information on generic types.  An
-    example for annotating a decorator::
-
-       T = TypeVar('T')
-       P = ParamSpec('P')
-
-       def add_logging(f: Callable[P, T]) -> Callable[P, T]:
-           '''A type-safe decorator to add logging to a function.'''
-           def inner(*args: P.args, **kwargs: P.kwargs) -> T:
-               logging.info(f'{f.__name__} was called')
-               return f(*args, **kwargs)
-           return inner
-
-       @add_logging
-       def add_two(x: float, y: float) -> float:
-           '''Add two numbers together.'''
-           return x + y
-
-    Parameter specification variables defined with covariant=True or
-    contravariant=True can be used to declare covariant or contravariant
-    generic types.  These keyword arguments are valid, but their actual semantics
-    are yet to be decided.  See PEP 612 for details.
-
-    Parameter specification variables can be introspected. e.g.:
-
-       P.__name__ == 'P'
-       P.__bound__ == None
-       P.__covariant__ == False
-       P.__contravariant__ == False
-
-    Note that only parameter specification variables defined in global scope can
-    be pickled.
-    """
+                new_args.extend(new_arg)
+            else:
+                new_args.append(new_arg)
+        params = tuple(new_args)
 
-    @property
-    def args(self):
-        return ParamSpecArgs(self)
+    return _GenericAlias(cls, params)
 
-    @property
-    def kwargs(self):
-        return ParamSpecKwargs(self)
-
-    def __init__(self, name, *, bound=None, covariant=False, contravariant=False):
-        self.__name__ = name
-        super().__init__(bound, covariant, contravariant)
-        def_mod = _caller()
-        if def_mod != 'typing':
-            self.__module__ = def_mod
 
-    def __typing_subst__(self, arg):
-        if isinstance(arg, (list, tuple)):
-            arg = tuple(_type_check(a, "Expected a type.") for a in arg)
-        elif not _is_param_expr(arg):
-            raise TypeError(f"Expected a list of types, an ellipsis, "
-                            f"ParamSpec, or Concatenate. Got {arg}")
-        return arg
+def _generic_init_subclass(cls, *args, **kwargs):
+    super(Generic, cls).__init_subclass__(*args, **kwargs)
+    tvars = []
+    if '__orig_bases__' in cls.__dict__:
+        error = Generic in cls.__orig_bases__
+    else:
+        error = (Generic in cls.__bases__ and
+                    cls.__name__ != 'Protocol' and
+                    type(cls) != _TypedDictMeta)
+    if error:
+        raise TypeError("Cannot inherit from plain Generic")
+    if '__orig_bases__' in cls.__dict__:
+        tvars = _collect_parameters(cls.__orig_bases__)
+        # Look for Generic[T1, ..., Tn].
+        # If found, tvars must be a subset of it.
+        # If not found, tvars is it.
+        # Also check for and reject plain Generic,
+        # and reject multiple Generic[...].
+        gvars = None
+        for base in cls.__orig_bases__:
+            if (isinstance(base, _GenericAlias) and
+                    base.__origin__ is Generic):
+                if gvars is not None:
+                    raise TypeError(
+                        "Cannot inherit from Generic[...] multiple times.")
+                gvars = base.__parameters__
+        if gvars is not None:
+            tvarset = set(tvars)
+            gvarset = set(gvars)
+            if not tvarset <= gvarset:
+                s_vars = ', '.join(str(t) for t in tvars if t not in gvarset)
+                s_args = ', '.join(str(g) for g in gvars)
+                raise TypeError(f"Some type variables ({s_vars}) are"
+                                f" not listed in Generic[{s_args}]")
+            tvars = gvars
+    cls.__parameters__ = tuple(tvars)
 
-    def __typing_prepare_subst__(self, alias, args):
-        params = alias.__parameters__
-        i = params.index(self)
-        if i >= len(args):
-            raise TypeError(f"Too few arguments for {alias}")
-        # Special case where Z[[int, str, bool]] == Z[int, str, bool] in PEP 612.
-        if len(params) == 1 and not _is_param_expr(args[0]):
-            assert i == 0
-            args = (args,)
-        # Convert lists to tuples to help other libraries cache the results.
-        elif isinstance(args[i], list):
-            args = (*args[:i], tuple(args[i]), *args[i+1:])
-        return args
 
 def _is_dunder(attr):
     return attr.startswith('__') and attr.endswith('__')
@@ -1812,113 +1656,6 @@ def __typing_is_unpacked_typevartuple__(self):
         return isinstance(self.__args__[0], TypeVarTuple)
 
 
-class Generic:
-    """Abstract base class for generic types.
-
-    A generic type is typically declared by inheriting from
-    this class parameterized with one or more type variables.
-    For example, a generic mapping type might be defined as::
-
-      class Mapping(Generic[KT, VT]):
-          def __getitem__(self, key: KT) -> VT:
-              ...
-          # Etc.
-
-    This class can then be used as follows::
-
-      def lookup_name(mapping: Mapping[KT, VT], key: KT, default: VT) -> VT:
-          try:
-              return mapping[key]
-          except KeyError:
-              return default
-    """
-    __slots__ = ()
-    _is_protocol = False
-
-    @_tp_cache
-    def __class_getitem__(cls, params):
-        """Parameterizes a generic class.
-
-        At least, parameterizing a generic class is the *main* thing this method
-        does. For example, for some generic class `Foo`, this is called when we
-        do `Foo[int]` - there, with `cls=Foo` and `params=int`.
-
-        However, note that this method is also called when defining generic
-        classes in the first place with `class Foo(Generic[T]): ...`.
-        """
-        if not isinstance(params, tuple):
-            params = (params,)
-
-        params = tuple(_type_convert(p) for p in params)
-        if cls in (Generic, Protocol):
-            # Generic and Protocol can only be subscripted with unique type variables.
-            if not params:
-                raise TypeError(
-                    f"Parameter list to {cls.__qualname__}[...] cannot be empty"
-                )
-            if not all(_is_typevar_like(p) for p in params):
-                raise TypeError(
-                    f"Parameters to {cls.__name__}[...] must all be type variables "
-                    f"or parameter specification variables.")
-            if len(set(params)) != len(params):
-                raise TypeError(
-                    f"Parameters to {cls.__name__}[...] must all be unique")
-        else:
-            # Subscripting a regular Generic subclass.
-            for param in cls.__parameters__:
-                prepare = getattr(param, '__typing_prepare_subst__', None)
-                if prepare is not None:
-                    params = prepare(cls, params)
-            _check_generic(cls, params, len(cls.__parameters__))
-
-            new_args = []
-            for param, new_arg in zip(cls.__parameters__, params):
-                if isinstance(param, TypeVarTuple):
-                    new_args.extend(new_arg)
-                else:
-                    new_args.append(new_arg)
-            params = tuple(new_args)
-
-        return _GenericAlias(cls, params)
-
-    def __init_subclass__(cls, *args, **kwargs):
-        super().__init_subclass__(*args, **kwargs)
-        tvars = []
-        if '__orig_bases__' in cls.__dict__:
-            error = Generic in cls.__orig_bases__
-        else:
-            error = (Generic in cls.__bases__ and
-                        cls.__name__ != 'Protocol' and
-                        type(cls) != _TypedDictMeta)
-        if error:
-            raise TypeError("Cannot inherit from plain Generic")
-        if '__orig_bases__' in cls.__dict__:
-            tvars = _collect_parameters(cls.__orig_bases__)
-            # Look for Generic[T1, ..., Tn].
-            # If found, tvars must be a subset of it.
-            # If not found, tvars is it.
-            # Also check for and reject plain Generic,
-            # and reject multiple Generic[...].
-            gvars = None
-            for base in cls.__orig_bases__:
-                if (isinstance(base, _GenericAlias) and
-                        base.__origin__ is Generic):
-                    if gvars is not None:
-                        raise TypeError(
-                            "Cannot inherit from Generic[...] multiple times.")
-                    gvars = base.__parameters__
-            if gvars is not None:
-                tvarset = set(tvars)
-                gvarset = set(gvars)
-                if not tvarset <= gvarset:
-                    s_vars = ', '.join(str(t) for t in tvars if t not in gvarset)
-                    s_args = ', '.join(str(g) for g in gvars)
-                    raise TypeError(f"Some type variables ({s_vars}) are"
-                                    f" not listed in Generic[{s_args}]")
-                tvars = gvars
-        cls.__parameters__ = tuple(tvars)
-
-
 class _TypingEllipsis:
     """Internal placeholder for ... (ellipsis)."""
 
@@ -2024,6 +1761,18 @@ def _lazy_load_getattr_static():
 
 _cleanups.append(_lazy_load_getattr_static.cache_clear)
 
+def _pickle_psargs(psargs):
+    return ParamSpecArgs, (psargs.__origin__,)
+
+copyreg.pickle(ParamSpecArgs, _pickle_psargs)
+
+def _pickle_pskwargs(pskwargs):
+    return ParamSpecKwargs, (pskwargs.__origin__,)
+
+copyreg.pickle(ParamSpecKwargs, _pickle_pskwargs)
+
+del _pickle_psargs, _pickle_pskwargs
+
 
 class _ProtocolMeta(ABCMeta):
     # This metaclass is really unfortunate and exists only because of
@@ -2943,7 +2692,7 @@ def __new__(cls, typename, bases, ns):
                                module=ns['__module__'])
         nm_tpl.__bases__ = bases
         if Generic in bases:
-            class_getitem = Generic.__class_getitem__.__func__
+            class_getitem = _generic_class_getitem
             nm_tpl.__class_getitem__ = classmethod(class_getitem)
         # update from user namespace without overriding special namedtuple attributes
         for key in ns:
diff --git a/Makefile.pre.in b/Makefile.pre.in
index 7c44b7be5dbe..d66574143267 100644
--- a/Makefile.pre.in
+++ b/Makefile.pre.in
@@ -479,6 +479,7 @@ OBJECT_OBJS=	\
 		Objects/structseq.o \
 		Objects/tupleobject.o \
 		Objects/typeobject.o \
+		Objects/typevarobject.o \
 		Objects/unicodeobject.o \
 		Objects/unicodectype.o \
 		Objects/unionobject.o \
@@ -1767,6 +1768,7 @@ PYTHON_HEADERS= \
 		$(srcdir)/Include/internal/pycore_tracemalloc.h \
 		$(srcdir)/Include/internal/pycore_tuple.h \
 		$(srcdir)/Include/internal/pycore_typeobject.h \
+		$(srcdir)/Include/internal/pycore_typevarobject.h \
 		$(srcdir)/Include/internal/pycore_ucnhash.h \
 		$(srcdir)/Include/internal/pycore_unionobject.h \
 		$(srcdir)/Include/internal/pycore_unicodeobject.h \
diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-04-25-08-43-11.gh-issue-103763.ZLBZk1.rst b/Misc/NEWS.d/next/Core and Builtins/2023-04-25-08-43-11.gh-issue-103763.ZLBZk1.rst
new file mode 100644
index 000000000000..cefe6429ab20
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2023-04-25-08-43-11.gh-issue-103763.ZLBZk1.rst	
@@ -0,0 +1,23 @@
+Implement :pep:`695`, adding syntactic support for generic classes, generic
+functions, and type aliases.
+
+A new ``type X = ...`` syntax is added for type aliases, which resolves at
+runtime to an instance of the new class ``typing.TypeAliasType``.
+The value is lazily evaluated and is accessible through the ``.__value__``
+attribute. This is implemented as a new AST node ``ast.TypeAlias``.
+
+New syntax (``class X[T]: ...``, ``def func[T](): ...``) is added for defining
+generic functions and classes. This is implemented as a new
+``typeparams`` attribute on the AST nodes for classes and functions.
+This node holds instances of the new AST classes ``ast.TypeVar``,
+``ast.ParamSpec``, and ``ast.TypeVarTuple``.
+
+``typing.TypeVar``, ``typing.ParamSpec``, ``typing.ParamSpecArgs``,
+``typing.ParamSpecKwargs``, ``typing.TypeVarTuple``, and
+``typing.Generic`` are now implemented in C rather than Python.
+
+There are new bytecode instructions ``LOAD_LOCALS``,
+``LOAD_CLASSDICT_OR_GLOBAL``, and ``LOAD_CLASSDICT_OR_DEREF``
+to support correct resolution of names in class namespaces.
+
+Patch by Eric Traut, Larry Hastings, and Jelle Zijlstra.
diff --git a/Modules/Setup.bootstrap.in b/Modules/Setup.bootstrap.in
index e3e9b96b0630..8ef0f203a82a 100644
--- a/Modules/Setup.bootstrap.in
+++ b/Modules/Setup.bootstrap.in
@@ -21,6 +21,7 @@ itertools itertoolsmodule.c
 _sre _sre/sre.c
 _thread _threadmodule.c
 time timemodule.c
+_typing _typingmodule.c
 _weakref _weakref.c
 
 # commonly used core modules
diff --git a/Modules/Setup.stdlib.in b/Modules/Setup.stdlib.in
index 95409d48c0da..6db567d71309 100644
--- a/Modules/Setup.stdlib.in
+++ b/Modules/Setup.stdlib.in
@@ -41,7 +41,6 @@
 @MODULE__QUEUE_TRUE at _queue _queuemodule.c
 @MODULE__RANDOM_TRUE at _random _randommodule.c
 @MODULE__STRUCT_TRUE at _struct _struct.c
- at MODULE__TYPING_TRUE@_typing _typingmodule.c
 @MODULE__XXSUBINTERPRETERS_TRUE at _xxsubinterpreters _xxsubinterpretersmodule.c
 @MODULE__XXINTERPCHANNELS_TRUE at _xxinterpchannels _xxinterpchannelsmodule.c
 @MODULE__ZONEINFO_TRUE at _zoneinfo _zoneinfo.c
diff --git a/Modules/_typingmodule.c b/Modules/_typingmodule.c
index 64286375636a..ed2999c0b68b 100644
--- a/Modules/_typingmodule.c
+++ b/Modules/_typingmodule.c
@@ -1,6 +1,11 @@
 /* typing accelerator C extension: _typing module. */
 
+#ifndef Py_BUILD_CORE
+#define Py_BUILD_CORE
+#endif
+
 #include "Python.h"
+#include "internal/pycore_interp.h"
 #include "clinic/_typingmodule.c.h"
 
 /*[clinic input]
@@ -35,7 +40,30 @@ static PyMethodDef typing_methods[] = {
 PyDoc_STRVAR(typing_doc,
 "Accelerators for the typing module.\n");
 
+static int
+_typing_exec(PyObject *m)
+{
+    PyInterpreterState *interp = PyInterpreterState_Get();
+
+#define EXPORT_TYPE(name, typename) \
+    if (PyModule_AddObjectRef(m, name, \
+                              (PyObject *)interp->cached_objects.typename) < 0) { \
+        return -1; \
+    }
+
+    EXPORT_TYPE("TypeVar", typevar_type);
+    EXPORT_TYPE("TypeVarTuple", typevartuple_type);
+    EXPORT_TYPE("ParamSpec", paramspec_type);
+    EXPORT_TYPE("ParamSpecArgs", paramspecargs_type);
+    EXPORT_TYPE("ParamSpecKwargs", paramspeckwargs_type);
+    EXPORT_TYPE("TypeAliasType", typealias_type);
+    EXPORT_TYPE("Generic", generic_type);
+#undef EXPORT_TYPE
+    return 0;
+}
+
 static struct PyModuleDef_Slot _typingmodule_slots[] = {
+    {Py_mod_exec, _typing_exec},
     {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
     {0, NULL}
 };
diff --git a/Objects/clinic/typevarobject.c.h b/Objects/clinic/typevarobject.c.h
new file mode 100644
index 000000000000..54189b984468
--- /dev/null
+++ b/Objects/clinic/typevarobject.c.h
@@ -0,0 +1,786 @@
+/*[clinic input]
+preserve
+[clinic start generated code]*/
+
+#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+#  include "pycore_gc.h"            // PyGC_Head
+#  include "pycore_runtime.h"       // _Py_ID()
+#endif
+
+
+PyDoc_STRVAR(typevar_new__doc__,
+"typevar(name, *constraints, *, bound=None, covariant=False,\n"
+"        contravariant=False, infer_variance=False)\n"
+"--\n"
+"\n"
+"Create a TypeVar.");
+
+static PyObject *
+typevar_new_impl(PyTypeObject *type, PyObject *name, PyObject *constraints,
+                 PyObject *bound, int covariant, int contravariant,
+                 int infer_variance);
+
+static PyObject *
+typevar_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
+{
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+
+    #define NUM_KEYWORDS 5
+    static struct {
+        PyGC_Head _this_is_not_used;
+        PyObject_VAR_HEAD
+        PyObject *ob_item[NUM_KEYWORDS];
+    } _kwtuple = {
+        .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
+        .ob_item = { &_Py_ID(name), &_Py_ID(bound), &_Py_ID(covariant), &_Py_ID(contravariant), &_Py_ID(infer_variance), },
+    };
+    #undef NUM_KEYWORDS
+    #define KWTUPLE (&_kwtuple.ob_base.ob_base)
+
+    #else  // !Py_BUILD_CORE
+    #  define KWTUPLE NULL
+    #endif  // !Py_BUILD_CORE
+
+    static const char * const _keywords[] = {"name", "bound", "covariant", "contravariant", "infer_variance", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "typevar",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[6];
+    PyObject * const *fastargs;
+    Py_ssize_t nargs = PyTuple_GET_SIZE(args);
+    Py_ssize_t noptargs = Py_MIN(nargs, 1) + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 1;
+    PyObject *name;
+    PyObject *constraints = NULL;
+    PyObject *bound = Py_None;
+    int covariant = 0;
+    int contravariant = 0;
+    int infer_variance = 0;
+
+    fastargs = _PyArg_UnpackKeywordsWithVararg(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 1, 0, 1, argsbuf);
+    if (!fastargs) {
+        goto exit;
+    }
+    if (!PyUnicode_Check(fastargs[0])) {
+        _PyArg_BadArgument("typevar", "argument 'name'", "str", fastargs[0]);
+        goto exit;
+    }
+    name = fastargs[0];
+    constraints = fastargs[1];
+    if (!noptargs) {
+        goto skip_optional_kwonly;
+    }
+    if (fastargs[2]) {
+        bound = fastargs[2];
+        if (!--noptargs) {
+            goto skip_optional_kwonly;
+        }
+    }
+    if (fastargs[3]) {
+        covariant = PyObject_IsTrue(fastargs[3]);
+        if (covariant < 0) {
+            goto exit;
+        }
+        if (!--noptargs) {
+            goto skip_optional_kwonly;
+        }
+    }
+    if (fastargs[4]) {
+        contravariant = PyObject_IsTrue(fastargs[4]);
+        if (contravariant < 0) {
+            goto exit;
+        }
+        if (!--noptargs) {
+            goto skip_optional_kwonly;
+        }
+    }
+    infer_variance = PyObject_IsTrue(fastargs[5]);
+    if (infer_variance < 0) {
+        goto exit;
+    }
+skip_optional_kwonly:
+    return_value = typevar_new_impl(type, name, constraints, bound, covariant, contravariant, infer_variance);
+
+exit:
+    Py_XDECREF(constraints);
+    return return_value;
+}
+
+PyDoc_STRVAR(typevar_typing_subst__doc__,
+"__typing_subst__($self, /, arg)\n"
+"--\n"
+"\n");
+
+#define TYPEVAR_TYPING_SUBST_METHODDEF    \
+    {"__typing_subst__", _PyCFunction_CAST(typevar_typing_subst), METH_FASTCALL|METH_KEYWORDS, typevar_typing_subst__doc__},
+
+static PyObject *
+typevar_typing_subst_impl(typevarobject *self, PyObject *arg);
+
+static PyObject *
+typevar_typing_subst(typevarobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+
+    #define NUM_KEYWORDS 1
+    static struct {
+        PyGC_Head _this_is_not_used;
+        PyObject_VAR_HEAD
+        PyObject *ob_item[NUM_KEYWORDS];
+    } _kwtuple = {
+        .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
+        .ob_item = { &_Py_ID(arg), },
+    };
+    #undef NUM_KEYWORDS
+    #define KWTUPLE (&_kwtuple.ob_base.ob_base)
+
+    #else  // !Py_BUILD_CORE
+    #  define KWTUPLE NULL
+    #endif  // !Py_BUILD_CORE
+
+    static const char * const _keywords[] = {"arg", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "__typing_subst__",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[1];
+    PyObject *arg;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    arg = args[0];
+    return_value = typevar_typing_subst_impl(self, arg);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(typevar_reduce__doc__,
+"__reduce__($self, /)\n"
+"--\n"
+"\n");
+
+#define TYPEVAR_REDUCE_METHODDEF    \
+    {"__reduce__", (PyCFunction)typevar_reduce, METH_NOARGS, typevar_reduce__doc__},
+
+static PyObject *
+typevar_reduce_impl(typevarobject *self);
+
+static PyObject *
+typevar_reduce(typevarobject *self, PyObject *Py_UNUSED(ignored))
+{
+    return typevar_reduce_impl(self);
+}
+
+PyDoc_STRVAR(paramspecargs_new__doc__,
+"paramspecargs(origin)\n"
+"--\n"
+"\n"
+"Create a ParamSpecArgs object.");
+
+static PyObject *
+paramspecargs_new_impl(PyTypeObject *type, PyObject *origin);
+
+static PyObject *
+paramspecargs_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
+{
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+
+    #define NUM_KEYWORDS 1
+    static struct {
+        PyGC_Head _this_is_not_used;
+        PyObject_VAR_HEAD
+        PyObject *ob_item[NUM_KEYWORDS];
+    } _kwtuple = {
+        .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
+        .ob_item = { &_Py_ID(origin), },
+    };
+    #undef NUM_KEYWORDS
+    #define KWTUPLE (&_kwtuple.ob_base.ob_base)
+
+    #else  // !Py_BUILD_CORE
+    #  define KWTUPLE NULL
+    #endif  // !Py_BUILD_CORE
+
+    static const char * const _keywords[] = {"origin", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "paramspecargs",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[1];
+    PyObject * const *fastargs;
+    Py_ssize_t nargs = PyTuple_GET_SIZE(args);
+    PyObject *origin;
+
+    fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 1, 0, argsbuf);
+    if (!fastargs) {
+        goto exit;
+    }
+    origin = fastargs[0];
+    return_value = paramspecargs_new_impl(type, origin);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(paramspeckwargs_new__doc__,
+"paramspeckwargs(origin)\n"
+"--\n"
+"\n"
+"Create a ParamSpecKwargs object.");
+
+static PyObject *
+paramspeckwargs_new_impl(PyTypeObject *type, PyObject *origin);
+
+static PyObject *
+paramspeckwargs_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
+{
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+
+    #define NUM_KEYWORDS 1
+    static struct {
+        PyGC_Head _this_is_not_used;
+        PyObject_VAR_HEAD
+        PyObject *ob_item[NUM_KEYWORDS];
+    } _kwtuple = {
+        .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
+        .ob_item = { &_Py_ID(origin), },
+    };
+    #undef NUM_KEYWORDS
+    #define KWTUPLE (&_kwtuple.ob_base.ob_base)
+
+    #else  // !Py_BUILD_CORE
+    #  define KWTUPLE NULL
+    #endif  // !Py_BUILD_CORE
+
+    static const char * const _keywords[] = {"origin", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "paramspeckwargs",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[1];
+    PyObject * const *fastargs;
+    Py_ssize_t nargs = PyTuple_GET_SIZE(args);
+    PyObject *origin;
+
+    fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 1, 0, argsbuf);
+    if (!fastargs) {
+        goto exit;
+    }
+    origin = fastargs[0];
+    return_value = paramspeckwargs_new_impl(type, origin);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(paramspec_new__doc__,
+"paramspec(name, *, bound=None, covariant=False, contravariant=False,\n"
+"          infer_variance=False)\n"
+"--\n"
+"\n"
+"Create a ParamSpec object.");
+
+static PyObject *
+paramspec_new_impl(PyTypeObject *type, PyObject *name, PyObject *bound,
+                   int covariant, int contravariant, int infer_variance);
+
+static PyObject *
+paramspec_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
+{
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+
+    #define NUM_KEYWORDS 5
+    static struct {
+        PyGC_Head _this_is_not_used;
+        PyObject_VAR_HEAD
+        PyObject *ob_item[NUM_KEYWORDS];
+    } _kwtuple = {
+        .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
+        .ob_item = { &_Py_ID(name), &_Py_ID(bound), &_Py_ID(covariant), &_Py_ID(contravariant), &_Py_ID(infer_variance), },
+    };
+    #undef NUM_KEYWORDS
+    #define KWTUPLE (&_kwtuple.ob_base.ob_base)
+
+    #else  // !Py_BUILD_CORE
+    #  define KWTUPLE NULL
+    #endif  // !Py_BUILD_CORE
+
+    static const char * const _keywords[] = {"name", "bound", "covariant", "contravariant", "infer_variance", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "paramspec",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[5];
+    PyObject * const *fastargs;
+    Py_ssize_t nargs = PyTuple_GET_SIZE(args);
+    Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 1;
+    PyObject *name;
+    PyObject *bound = Py_None;
+    int covariant = 0;
+    int contravariant = 0;
+    int infer_variance = 0;
+
+    fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 1, 0, argsbuf);
+    if (!fastargs) {
+        goto exit;
+    }
+    if (!PyUnicode_Check(fastargs[0])) {
+        _PyArg_BadArgument("paramspec", "argument 'name'", "str", fastargs[0]);
+        goto exit;
+    }
+    name = fastargs[0];
+    if (!noptargs) {
+        goto skip_optional_kwonly;
+    }
+    if (fastargs[1]) {
+        bound = fastargs[1];
+        if (!--noptargs) {
+            goto skip_optional_kwonly;
+        }
+    }
+    if (fastargs[2]) {
+        covariant = PyObject_IsTrue(fastargs[2]);
+        if (covariant < 0) {
+            goto exit;
+        }
+        if (!--noptargs) {
+            goto skip_optional_kwonly;
+        }
+    }
+    if (fastargs[3]) {
+        contravariant = PyObject_IsTrue(fastargs[3]);
+        if (contravariant < 0) {
+            goto exit;
+        }
+        if (!--noptargs) {
+            goto skip_optional_kwonly;
+        }
+    }
+    infer_variance = PyObject_IsTrue(fastargs[4]);
+    if (infer_variance < 0) {
+        goto exit;
+    }
+skip_optional_kwonly:
+    return_value = paramspec_new_impl(type, name, bound, covariant, contravariant, infer_variance);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(paramspec_typing_subst__doc__,
+"__typing_subst__($self, /, arg)\n"
+"--\n"
+"\n");
+
+#define PARAMSPEC_TYPING_SUBST_METHODDEF    \
+    {"__typing_subst__", _PyCFunction_CAST(paramspec_typing_subst), METH_FASTCALL|METH_KEYWORDS, paramspec_typing_subst__doc__},
+
+static PyObject *
+paramspec_typing_subst_impl(paramspecobject *self, PyObject *arg);
+
+static PyObject *
+paramspec_typing_subst(paramspecobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+
+    #define NUM_KEYWORDS 1
+    static struct {
+        PyGC_Head _this_is_not_used;
+        PyObject_VAR_HEAD
+        PyObject *ob_item[NUM_KEYWORDS];
+    } _kwtuple = {
+        .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
+        .ob_item = { &_Py_ID(arg), },
+    };
+    #undef NUM_KEYWORDS
+    #define KWTUPLE (&_kwtuple.ob_base.ob_base)
+
+    #else  // !Py_BUILD_CORE
+    #  define KWTUPLE NULL
+    #endif  // !Py_BUILD_CORE
+
+    static const char * const _keywords[] = {"arg", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "__typing_subst__",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[1];
+    PyObject *arg;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    arg = args[0];
+    return_value = paramspec_typing_subst_impl(self, arg);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(paramspec_typing_prepare_subst__doc__,
+"__typing_prepare_subst__($self, /, alias, args)\n"
+"--\n"
+"\n");
+
+#define PARAMSPEC_TYPING_PREPARE_SUBST_METHODDEF    \
+    {"__typing_prepare_subst__", _PyCFunction_CAST(paramspec_typing_prepare_subst), METH_FASTCALL|METH_KEYWORDS, paramspec_typing_prepare_subst__doc__},
+
+static PyObject *
+paramspec_typing_prepare_subst_impl(paramspecobject *self, PyObject *alias,
+                                    PyObject *args);
+
+static PyObject *
+paramspec_typing_prepare_subst(paramspecobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+
+    #define NUM_KEYWORDS 2
+    static struct {
+        PyGC_Head _this_is_not_used;
+        PyObject_VAR_HEAD
+        PyObject *ob_item[NUM_KEYWORDS];
+    } _kwtuple = {
+        .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
+        .ob_item = { &_Py_ID(alias), &_Py_ID(args), },
+    };
+    #undef NUM_KEYWORDS
+    #define KWTUPLE (&_kwtuple.ob_base.ob_base)
+
+    #else  // !Py_BUILD_CORE
+    #  define KWTUPLE NULL
+    #endif  // !Py_BUILD_CORE
+
+    static const char * const _keywords[] = {"alias", "args", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "__typing_prepare_subst__",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[2];
+    PyObject *alias;
+    PyObject *__clinic_args;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    alias = args[0];
+    __clinic_args = args[1];
+    return_value = paramspec_typing_prepare_subst_impl(self, alias, __clinic_args);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(paramspec_reduce__doc__,
+"__reduce__($self, /)\n"
+"--\n"
+"\n");
+
+#define PARAMSPEC_REDUCE_METHODDEF    \
+    {"__reduce__", (PyCFunction)paramspec_reduce, METH_NOARGS, paramspec_reduce__doc__},
+
+static PyObject *
+paramspec_reduce_impl(paramspecobject *self);
+
+static PyObject *
+paramspec_reduce(paramspecobject *self, PyObject *Py_UNUSED(ignored))
+{
+    return paramspec_reduce_impl(self);
+}
+
+PyDoc_STRVAR(typevartuple__doc__,
+"typevartuple(name)\n"
+"--\n"
+"\n"
+"Create a new TypeVarTuple with the given name.");
+
+static PyObject *
+typevartuple_impl(PyTypeObject *type, PyObject *name);
+
+static PyObject *
+typevartuple(PyTypeObject *type, PyObject *args, PyObject *kwargs)
+{
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+
+    #define NUM_KEYWORDS 1
+    static struct {
+        PyGC_Head _this_is_not_used;
+        PyObject_VAR_HEAD
+        PyObject *ob_item[NUM_KEYWORDS];
+    } _kwtuple = {
+        .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
+        .ob_item = { &_Py_ID(name), },
+    };
+    #undef NUM_KEYWORDS
+    #define KWTUPLE (&_kwtuple.ob_base.ob_base)
+
+    #else  // !Py_BUILD_CORE
+    #  define KWTUPLE NULL
+    #endif  // !Py_BUILD_CORE
+
+    static const char * const _keywords[] = {"name", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "typevartuple",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[1];
+    PyObject * const *fastargs;
+    Py_ssize_t nargs = PyTuple_GET_SIZE(args);
+    PyObject *name;
+
+    fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 1, 1, 0, argsbuf);
+    if (!fastargs) {
+        goto exit;
+    }
+    if (!PyUnicode_Check(fastargs[0])) {
+        _PyArg_BadArgument("typevartuple", "argument 'name'", "str", fastargs[0]);
+        goto exit;
+    }
+    name = fastargs[0];
+    return_value = typevartuple_impl(type, name);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(typevartuple_typing_subst__doc__,
+"__typing_subst__($self, /, arg)\n"
+"--\n"
+"\n");
+
+#define TYPEVARTUPLE_TYPING_SUBST_METHODDEF    \
+    {"__typing_subst__", _PyCFunction_CAST(typevartuple_typing_subst), METH_FASTCALL|METH_KEYWORDS, typevartuple_typing_subst__doc__},
+
+static PyObject *
+typevartuple_typing_subst_impl(typevartupleobject *self, PyObject *arg);
+
+static PyObject *
+typevartuple_typing_subst(typevartupleobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+
+    #define NUM_KEYWORDS 1
+    static struct {
+        PyGC_Head _this_is_not_used;
+        PyObject_VAR_HEAD
+        PyObject *ob_item[NUM_KEYWORDS];
+    } _kwtuple = {
+        .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
+        .ob_item = { &_Py_ID(arg), },
+    };
+    #undef NUM_KEYWORDS
+    #define KWTUPLE (&_kwtuple.ob_base.ob_base)
+
+    #else  // !Py_BUILD_CORE
+    #  define KWTUPLE NULL
+    #endif  // !Py_BUILD_CORE
+
+    static const char * const _keywords[] = {"arg", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "__typing_subst__",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[1];
+    PyObject *arg;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    arg = args[0];
+    return_value = typevartuple_typing_subst_impl(self, arg);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(typevartuple_typing_prepare_subst__doc__,
+"__typing_prepare_subst__($self, /, alias, args)\n"
+"--\n"
+"\n");
+
+#define TYPEVARTUPLE_TYPING_PREPARE_SUBST_METHODDEF    \
+    {"__typing_prepare_subst__", _PyCFunction_CAST(typevartuple_typing_prepare_subst), METH_FASTCALL|METH_KEYWORDS, typevartuple_typing_prepare_subst__doc__},
+
+static PyObject *
+typevartuple_typing_prepare_subst_impl(typevartupleobject *self,
+                                       PyObject *alias, PyObject *args);
+
+static PyObject *
+typevartuple_typing_prepare_subst(typevartupleobject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
+{
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+
+    #define NUM_KEYWORDS 2
+    static struct {
+        PyGC_Head _this_is_not_used;
+        PyObject_VAR_HEAD
+        PyObject *ob_item[NUM_KEYWORDS];
+    } _kwtuple = {
+        .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
+        .ob_item = { &_Py_ID(alias), &_Py_ID(args), },
+    };
+    #undef NUM_KEYWORDS
+    #define KWTUPLE (&_kwtuple.ob_base.ob_base)
+
+    #else  // !Py_BUILD_CORE
+    #  define KWTUPLE NULL
+    #endif  // !Py_BUILD_CORE
+
+    static const char * const _keywords[] = {"alias", "args", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "__typing_prepare_subst__",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[2];
+    PyObject *alias;
+    PyObject *__clinic_args;
+
+    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf);
+    if (!args) {
+        goto exit;
+    }
+    alias = args[0];
+    __clinic_args = args[1];
+    return_value = typevartuple_typing_prepare_subst_impl(self, alias, __clinic_args);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(typevartuple_reduce__doc__,
+"__reduce__($self, /)\n"
+"--\n"
+"\n");
+
+#define TYPEVARTUPLE_REDUCE_METHODDEF    \
+    {"__reduce__", (PyCFunction)typevartuple_reduce, METH_NOARGS, typevartuple_reduce__doc__},
+
+static PyObject *
+typevartuple_reduce_impl(typevartupleobject *self);
+
+static PyObject *
+typevartuple_reduce(typevartupleobject *self, PyObject *Py_UNUSED(ignored))
+{
+    return typevartuple_reduce_impl(self);
+}
+
+PyDoc_STRVAR(typealias_reduce__doc__,
+"__reduce__($self, /)\n"
+"--\n"
+"\n");
+
+#define TYPEALIAS_REDUCE_METHODDEF    \
+    {"__reduce__", (PyCFunction)typealias_reduce, METH_NOARGS, typealias_reduce__doc__},
+
+static PyObject *
+typealias_reduce_impl(typealiasobject *self);
+
+static PyObject *
+typealias_reduce(typealiasobject *self, PyObject *Py_UNUSED(ignored))
+{
+    return typealias_reduce_impl(self);
+}
+
+PyDoc_STRVAR(typealias_new__doc__,
+"typealias(name, value, *, type_params=<unrepresentable>)\n"
+"--\n"
+"\n"
+"Create a TypeAliasType.");
+
+static PyObject *
+typealias_new_impl(PyTypeObject *type, PyObject *name, PyObject *value,
+                   PyObject *type_params);
+
+static PyObject *
+typealias_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
+{
+    PyObject *return_value = NULL;
+    #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
+
+    #define NUM_KEYWORDS 3
+    static struct {
+        PyGC_Head _this_is_not_used;
+        PyObject_VAR_HEAD
+        PyObject *ob_item[NUM_KEYWORDS];
+    } _kwtuple = {
+        .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
+        .ob_item = { &_Py_ID(name), &_Py_ID(value), &_Py_ID(type_params), },
+    };
+    #undef NUM_KEYWORDS
+    #define KWTUPLE (&_kwtuple.ob_base.ob_base)
+
+    #else  // !Py_BUILD_CORE
+    #  define KWTUPLE NULL
+    #endif  // !Py_BUILD_CORE
+
+    static const char * const _keywords[] = {"name", "value", "type_params", NULL};
+    static _PyArg_Parser _parser = {
+        .keywords = _keywords,
+        .fname = "typealias",
+        .kwtuple = KWTUPLE,
+    };
+    #undef KWTUPLE
+    PyObject *argsbuf[3];
+    PyObject * const *fastargs;
+    Py_ssize_t nargs = PyTuple_GET_SIZE(args);
+    Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 2;
+    PyObject *name;
+    PyObject *value;
+    PyObject *type_params = NULL;
+
+    fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, 2, 2, 0, argsbuf);
+    if (!fastargs) {
+        goto exit;
+    }
+    if (!PyUnicode_Check(fastargs[0])) {
+        _PyArg_BadArgument("typealias", "argument 'name'", "str", fastargs[0]);
+        goto exit;
+    }
+    name = fastargs[0];
+    value = fastargs[1];
+    if (!noptargs) {
+        goto skip_optional_kwonly;
+    }
+    type_params = fastargs[2];
+skip_optional_kwonly:
+    return_value = typealias_new_impl(type, name, value, type_params);
+
+exit:
+    return return_value;
+}
+/*[clinic end generated code: output=807bcd30ebd10ac3 input=a9049054013a1b77]*/
diff --git a/Objects/funcobject.c b/Objects/funcobject.c
index 78c1144afca2..69898bf722d6 100644
--- a/Objects/funcobject.c
+++ b/Objects/funcobject.c
@@ -127,6 +127,7 @@ _PyFunction_FromConstructor(PyFrameConstructor *constr)
         PyErr_Clear();
     }
     op->func_annotations = NULL;
+    op->func_typeparams = NULL;
     op->vectorcall = _PyFunction_Vectorcall;
     op->func_version = 0;
     _PyObject_GC_TRACK(op);
@@ -202,6 +203,7 @@ PyFunction_NewWithQualName(PyObject *code, PyObject *globals, PyObject *qualname
     op->func_weakreflist = NULL;
     op->func_module = module;
     op->func_annotations = NULL;
+    op->func_typeparams = NULL;
     op->vectorcall = _PyFunction_Vectorcall;
     op->func_version = 0;
     _PyObject_GC_TRACK(op);
@@ -652,6 +654,28 @@ func_set_annotations(PyFunctionObject *op, PyObject *value, void *Py_UNUSED(igno
     return 0;
 }
 
+static PyObject *
+func_get_type_params(PyFunctionObject *op, void *Py_UNUSED(ignored))
+{
+    if (op->func_typeparams == NULL) {
+        return PyTuple_New(0);
+    }
+
+    assert(PyTuple_Check(op->func_typeparams));
+    return Py_NewRef(op->func_typeparams);
+}
+
+PyObject *
+_Py_set_function_type_params(PyThreadState *Py_UNUSED(ignored), PyObject *func,
+                             PyObject *type_params)
+{
+    assert(PyFunction_Check(func));
+    assert(PyTuple_Check(type_params));
+    PyFunctionObject *f = (PyFunctionObject *)func;
+    Py_XSETREF(f->func_typeparams, Py_NewRef(type_params));
+    return Py_NewRef(func);
+}
+
 static PyGetSetDef func_getsetlist[] = {
     {"__code__", (getter)func_get_code, (setter)func_set_code},
     {"__defaults__", (getter)func_get_defaults,
@@ -663,6 +687,7 @@ static PyGetSetDef func_getsetlist[] = {
     {"__dict__", PyObject_GenericGetDict, PyObject_GenericSetDict},
     {"__name__", (getter)func_get_name, (setter)func_set_name},
     {"__qualname__", (getter)func_get_qualname, (setter)func_set_qualname},
+    {"__type_params__", (getter)func_get_type_params, NULL},
     {NULL} /* Sentinel */
 };
 
@@ -783,6 +808,7 @@ func_clear(PyFunctionObject *op)
     Py_CLEAR(op->func_dict);
     Py_CLEAR(op->func_closure);
     Py_CLEAR(op->func_annotations);
+    Py_CLEAR(op->func_typeparams);
     // Don't Py_CLEAR(op->func_code), since code is always required
     // to be non-NULL. Similarly, name and qualname shouldn't be NULL.
     // However, name and qualname could be str subclasses, so they
@@ -837,6 +863,7 @@ func_traverse(PyFunctionObject *f, visitproc visit, void *arg)
     Py_VISIT(f->func_dict);
     Py_VISIT(f->func_closure);
     Py_VISIT(f->func_annotations);
+    Py_VISIT(f->func_typeparams);
     Py_VISIT(f->func_qualname);
     return 0;
 }
diff --git a/Objects/object.c b/Objects/object.c
index a7c79c673d5f..f3118665430d 100644
--- a/Objects/object.c
+++ b/Objects/object.c
@@ -14,6 +14,7 @@
 #include "pycore_pymem.h"         // _PyMem_IsPtrFreed()
 #include "pycore_pystate.h"       // _PyThreadState_GET()
 #include "pycore_symtable.h"      // PySTEntry_Type
+#include "pycore_typevarobject.h" // _PyTypeVar_Type etc., _Py_initialize_generic
 #include "pycore_typeobject.h"    // _PyBufferWrapper_Type
 #include "pycore_unionobject.h"   // _PyUnion_Type
 #include "pycore_interpreteridobject.h"  // _PyInterpreterID_Type
@@ -2139,6 +2140,11 @@ _PyTypes_InitTypes(PyInterpreterState *interp)
         }
     }
 
+    // Must be after static types are initialized
+    if (_Py_initialize_generic(interp) < 0) {
+        return _PyStatus_ERR("Can't initialize generic types");
+    }
+
     return _PyStatus_OK();
 }
 
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index c1525320a7cb..624dc63ce82c 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -1460,6 +1460,18 @@ type_get_annotations(PyTypeObject *type, void *context)
     return annotations;
 }
 
+static PyObject *
+type_get_type_params(PyTypeObject *type, void *context)
+{
+    PyObject *params = PyDict_GetItem(lookup_tp_dict(type), &_Py_ID(__type_params__));
+
+    if (params) {
+        return Py_NewRef(params);
+    }
+
+    return PyTuple_New(0);
+}
+
 static int
 type_set_annotations(PyTypeObject *type, PyObject *value, void *context)
 {
@@ -1536,6 +1548,7 @@ static PyGetSetDef type_getsets[] = {
     {"__doc__", (getter)type_get_doc, (setter)type_set_doc, NULL},
     {"__text_signature__", (getter)type_get_text_signature, NULL, NULL},
     {"__annotations__", (getter)type_get_annotations, (setter)type_set_annotations, NULL},
+    {"__type_params__", (getter)type_get_type_params, NULL, NULL},
     {0}
 };
 
@@ -3130,11 +3143,12 @@ type_new_copy_slots(type_new_ctx *ctx, PyObject *dict)
             goto error;
         }
         if (r > 0) {
-            /* CPython inserts __qualname__ and __classcell__ (when needed)
+            /* CPython inserts these names (when needed)
                into the namespace when creating a class.  They will be deleted
                below so won't act as class variables. */
             if (!_PyUnicode_Equal(slot, &_Py_ID(__qualname__)) &&
-                !_PyUnicode_Equal(slot, &_Py_ID(__classcell__)))
+                !_PyUnicode_Equal(slot, &_Py_ID(__classcell__)) &&
+                !_PyUnicode_Equal(slot, &_Py_ID(__classdictcell__)))
             {
                 PyErr_Format(PyExc_ValueError,
                              "%R in __slots__ conflicts with class variable",
@@ -3585,6 +3599,32 @@ type_new_set_classcell(PyTypeObject *type)
     return 0;
 }
 
+static int
+type_new_set_classdictcell(PyTypeObject *type)
+{
+    PyObject *dict = lookup_tp_dict(type);
+    PyObject *cell = PyDict_GetItemWithError(dict, &_Py_ID(__classdictcell__));
+    if (cell == NULL) {
+        if (PyErr_Occurred()) {
+            return -1;
+        }
+        return 0;
+    }
+
+    /* At least one method requires a reference to the dict of its defining class */
+    if (!PyCell_Check(cell)) {
+        PyErr_Format(PyExc_TypeError,
+                     "__classdictcell__ must be a nonlocal cell, not %.200R",
+                     Py_TYPE(cell));
+        return -1;
+    }
+
+    (void)PyCell_Set(cell, (PyObject *)dict);
+    if (PyDict_DelItem(dict, &_Py_ID(__classdictcell__)) < 0) {
+        return -1;
+    }
+    return 0;
+}
 
 static int
 type_new_set_attrs(const type_new_ctx *ctx, PyTypeObject *type)
@@ -3629,6 +3669,9 @@ type_new_set_attrs(const type_new_ctx *ctx, PyTypeObject *type)
     if (type_new_set_classcell(type) < 0) {
         return -1;
     }
+    if (type_new_set_classdictcell(type) < 0) {
+        return -1;
+    }
     return 0;
 }
 
diff --git a/Objects/typevarobject.c b/Objects/typevarobject.c
new file mode 100644
index 000000000000..b0578756f7df
--- /dev/null
+++ b/Objects/typevarobject.c
@@ -0,0 +1,1620 @@
+// TypeVar, TypeVarTuple, and ParamSpec
+#include "Python.h"
+#include "pycore_object.h"  // _PyObject_GC_TRACK/UNTRACK
+#include "pycore_typevarobject.h"
+#include "pycore_unionobject.h"   // _Py_union_type_or
+#include "structmember.h"
+
+/*[clinic input]
+class typevar "typevarobject *" "&_PyTypeVar_Type"
+class paramspec "paramspecobject *" "&_PyParamSpec_Type"
+class paramspecargs "paramspecattrobject *" "&_PyParamSpecArgs_Type"
+class paramspeckwargs "paramspecattrobject *" "&_PyParamSpecKwargs_Type"
+class typevartuple "typevartupleobject *" "&_PyTypeVarTuple_Type"
+class typealias "typealiasobject *" "&_PyTypeAlias_Type"
+class Generic "PyObject *" "&PyGeneric_Type"
+[clinic start generated code]*/
+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=aa86741931a0f55c]*/
+
+typedef struct {
+    PyObject_HEAD
+    PyObject *name;
+    PyObject *bound;
+    PyObject *evaluate_bound;
+    PyObject *constraints;
+    PyObject *evaluate_constraints;
+    bool covariant;
+    bool contravariant;
+    bool infer_variance;
+} typevarobject;
+
+typedef struct {
+    PyObject_HEAD
+    PyObject *name;
+} typevartupleobject;
+
+typedef struct {
+    PyObject_HEAD
+    PyObject *name;
+    PyObject *bound;
+    bool covariant;
+    bool contravariant;
+    bool infer_variance;
+} paramspecobject;
+
+typedef struct {
+    PyObject_HEAD
+    PyObject *name;
+    PyObject *type_params;
+    PyObject *compute_value;
+    PyObject *value;
+} typealiasobject;
+
+#include "clinic/typevarobject.c.h"
+
+static PyObject *
+call_typing_func_object(const char *name, PyObject **args, size_t nargs)
+{
+    PyObject *typing = PyImport_ImportModule("typing");
+    if (typing == NULL) {
+        return NULL;
+    }
+    PyObject *func = PyObject_GetAttrString(typing, name);
+    if (func == NULL) {
+        Py_DECREF(typing);
+        return NULL;
+    }
+    PyObject *result = PyObject_Vectorcall(func, args, nargs, NULL);
+    Py_DECREF(func);
+    Py_DECREF(typing);
+    return result;
+}
+
+static PyObject *
+type_check(PyObject *arg, const char *msg)
+{
+    // Calling typing.py here leads to bootstrapping problems
+    if (Py_IsNone(arg)) {
+        return Py_NewRef(Py_TYPE(arg));
+    }
+    PyObject *message_str = PyUnicode_FromString(msg);
+    if (message_str == NULL) {
+        return NULL;
+    }
+    PyObject *args[2] = {arg, message_str};
+    PyObject *result = call_typing_func_object("_type_check", args, 2);
+    Py_DECREF(message_str);
+    return result;
+}
+
+/*
+ * Return a typing.Union. This is used as the nb_or (|) operator for
+ * TypeVar and ParamSpec. We use this rather than _Py_union_type_or
+ * (which would produce a types.Union) because historically TypeVar
+ * supported unions with string forward references, and we want to
+ * preserve that behavior. _Py_union_type_or only allows a small set
+ * of types.
+ */
+static PyObject *
+make_union(PyObject *self, PyObject *other)
+{
+    PyObject *args[2] = {self, other};
+    PyObject *result = call_typing_func_object("_make_union", args, 2);
+    return result;
+}
+
+static PyObject *
+caller(void)
+{
+    _PyInterpreterFrame *f = _PyThreadState_GET()->cframe->current_frame;
+    if (f == NULL) {
+        Py_RETURN_NONE;
+    }
+    if (f == NULL || f->f_funcobj == NULL) {
+        Py_RETURN_NONE;
+    }
+    PyObject *r = PyFunction_GetModule(f->f_funcobj);
+    if (!r) {
+        PyErr_Clear();
+        Py_RETURN_NONE;
+    }
+    return Py_NewRef(r);
+}
+
+static PyObject *
+typevartuple_unpack(PyObject *tvt)
+{
+    PyObject *typing = PyImport_ImportModule("typing");
+    if (typing == NULL) {
+        return NULL;
+    }
+    PyObject *unpack = PyObject_GetAttrString(typing, "Unpack");
+    if (unpack == NULL) {
+        Py_DECREF(typing);
+        return NULL;
+    }
+    PyObject *unpacked = PyObject_GetItem(unpack, tvt);
+    Py_DECREF(typing);
+    Py_DECREF(unpack);
+    return unpacked;
+}
+
+static int
+contains_typevartuple(PyTupleObject *params)
+{
+    Py_ssize_t n = PyTuple_GET_SIZE(params);
+    PyTypeObject *tp = PyInterpreterState_Get()->cached_objects.typevartuple_type;
+    for (Py_ssize_t i = 0; i < n; i++) {
+        PyObject *param = PyTuple_GET_ITEM(params, i);
+        if (Py_IS_TYPE(param, tp)) {
+            return 1;
+        }
+    }
+    return 0;
+}
+
+static PyObject *
+unpack_typevartuples(PyObject *params)
+{
+    assert(PyTuple_Check(params));
+    // TypeVarTuple must be unpacked when passed to Generic, so we do that here.
+    if (contains_typevartuple((PyTupleObject *)params)) {
+        Py_ssize_t n = PyTuple_GET_SIZE(params);
+        PyObject *new_params = PyTuple_New(n);
+        if (new_params == NULL) {
+            return NULL;
+        }
+        PyTypeObject *tp = PyInterpreterState_Get()->cached_objects.typevartuple_type;
+        for (Py_ssize_t i = 0; i < n; i++) {
+            PyObject *param = PyTuple_GET_ITEM(params, i);
+            if (Py_IS_TYPE(param, tp)) {
+                PyObject *unpacked = typevartuple_unpack(param);
+                if (unpacked == NULL) {
+                    Py_DECREF(new_params);
+                    return NULL;
+                }
+                PyTuple_SET_ITEM(new_params, i, unpacked);
+            }
+            else {
+                PyTuple_SET_ITEM(new_params, i, Py_NewRef(param));
+            }
+        }
+        return new_params;
+    }
+    else {
+        return Py_NewRef(params);
+    }
+}
+
+static void
+typevar_dealloc(PyObject *self)
+{
+    PyTypeObject *tp = Py_TYPE(self);
+    typevarobject *tv = (typevarobject *)self;
+
+    _PyObject_GC_UNTRACK(self);
+
+    Py_DECREF(tv->name);
+    Py_XDECREF(tv->bound);
+    Py_XDECREF(tv->evaluate_bound);
+    Py_XDECREF(tv->constraints);
+    Py_XDECREF(tv->evaluate_constraints);
+    _PyObject_ClearManagedDict(self);
+
+    Py_TYPE(self)->tp_free(self);
+    Py_DECREF(tp);
+}
+
+static int
+typevar_traverse(PyObject *self, visitproc visit, void *arg)
+{
+    Py_VISIT(Py_TYPE(self));
+    typevarobject *tv = (typevarobject *)self;
+    Py_VISIT(tv->bound);
+    Py_VISIT(tv->evaluate_bound);
+    Py_VISIT(tv->constraints);
+    Py_VISIT(tv->evaluate_constraints);
+    _PyObject_VisitManagedDict(self, visit, arg);
+    return 0;
+}
+
+static int
+typevar_clear(typevarobject *self)
+{
+    Py_CLEAR(self->bound);
+    Py_CLEAR(self->evaluate_bound);
+    Py_CLEAR(self->constraints);
+    Py_CLEAR(self->evaluate_constraints);
+    _PyObject_ClearManagedDict((PyObject *)self);
+    return 0;
+}
+
+static PyObject *
+typevar_repr(PyObject *self)
+{
+    typevarobject *tv = (typevarobject *)self;
+
+    if (tv->infer_variance) {
+        return Py_NewRef(tv->name);
+    }
+
+    char variance = tv->covariant ? '+' : tv->contravariant ? '-' : '~';
+    return PyUnicode_FromFormat("%c%U", variance, tv->name);
+}
+
+static PyMemberDef typevar_members[] = {
+    {"__name__", T_OBJECT, offsetof(typevarobject, name), READONLY},
+    {"__covariant__", T_BOOL, offsetof(typevarobject, covariant), READONLY},
+    {"__contravariant__", T_BOOL, offsetof(typevarobject, contravariant), READONLY},
+    {"__infer_variance__", T_BOOL, offsetof(typevarobject, infer_variance), READONLY},
+    {0}
+};
+
+static PyObject *
+typevar_bound(typevarobject *self, void *Py_UNUSED(ignored))
+{
+    if (self->bound != NULL) {
+        return Py_NewRef(self->bound);
+    }
+    if (self->evaluate_bound == NULL) {
+        Py_RETURN_NONE;
+    }
+    PyObject *bound = PyObject_CallNoArgs(self->evaluate_bound);
+    self->bound = Py_XNewRef(bound);
+    return bound;
+}
+
+static PyObject *
+typevar_constraints(typevarobject *self, void *Py_UNUSED(ignored))
+{
+    if (self->constraints != NULL) {
+        return Py_NewRef(self->constraints);
+    }
+    if (self->evaluate_constraints == NULL) {
+        Py_RETURN_NONE;
+    }
+    PyObject *constraints = PyObject_CallNoArgs(self->evaluate_constraints);
+    self->constraints = Py_XNewRef(constraints);
+    return constraints;
+}
+
+static PyGetSetDef typevar_getset[] = {
+    {"__bound__", (getter)typevar_bound, NULL, NULL, NULL},
+    {"__constraints__", (getter)typevar_constraints, NULL, NULL, NULL},
+    {0}
+};
+
+static typevarobject *
+typevar_alloc(PyObject *name, PyObject *bound, PyObject *evaluate_bound,
+              PyObject *constraints, PyObject *evaluate_constraints,
+              bool covariant, bool contravariant, bool infer_variance,
+              PyObject *module)
+{
+    PyTypeObject *tp = PyInterpreterState_Get()->cached_objects.typevar_type;
+    assert(tp != NULL);
+    typevarobject *tv = PyObject_GC_New(typevarobject, tp);
+    if (tv == NULL) {
+        return NULL;
+    }
+
+    tv->name = Py_NewRef(name);
+
+    tv->bound = Py_XNewRef(bound);
+    tv->evaluate_bound = Py_XNewRef(evaluate_bound);
+    tv->constraints = Py_XNewRef(constraints);
+    tv->evaluate_constraints = Py_XNewRef(evaluate_constraints);
+
+    tv->covariant = covariant;
+    tv->contravariant = contravariant;
+    tv->infer_variance = infer_variance;
+    _PyObject_GC_TRACK(tv);
+
+    if (module != NULL) {
+        if (PyObject_SetAttrString((PyObject *)tv, "__module__", module) < 0) {
+            Py_DECREF(tv);
+            return NULL;
+        }
+    }
+
+    return tv;
+}
+
+/*[clinic input]
+ at classmethod
+typevar.__new__ as typevar_new
+
+    name: object(subclass_of="&PyUnicode_Type")
+    *constraints: object
+    *
+    bound: object = None
+    covariant: bool = False
+    contravariant: bool = False
+    infer_variance: bool = False
+
+Create a TypeVar.
+[clinic start generated code]*/
+
+static PyObject *
+typevar_new_impl(PyTypeObject *type, PyObject *name, PyObject *constraints,
+                 PyObject *bound, int covariant, int contravariant,
+                 int infer_variance)
+/*[clinic end generated code: output=1d200450ee99226d input=2c07ab87c94f462b]*/
+{
+    if (covariant && contravariant) {
+        PyErr_SetString(PyExc_ValueError,
+                        "Bivariant types are not supported.");
+        return NULL;
+    }
+
+    if (infer_variance && (covariant || contravariant)) {
+        PyErr_SetString(PyExc_ValueError,
+                        "Variance cannot be specified with infer_variance.");
+        return NULL;
+    }
+
+    if (Py_IsNone(bound)) {
+        bound = NULL;
+    }
+    if (bound != NULL) {
+        bound = type_check(bound, "Bound must be a type.");
+        if (bound == NULL) {
+            return NULL;
+        }
+    }
+
+    if (!PyTuple_CheckExact(constraints)) {
+        PyErr_SetString(PyExc_TypeError,
+                        "constraints must be a tuple");
+        return NULL;
+    }
+    Py_ssize_t n_constraints = PyTuple_GET_SIZE(constraints);
+    if (n_constraints == 1) {
+        PyErr_SetString(PyExc_TypeError,
+                        "A single constraint is not allowed");
+        Py_XDECREF(bound);
+        return NULL;
+    } else if (n_constraints == 0) {
+        constraints = NULL;
+    } else if (bound != NULL) {
+        PyErr_SetString(PyExc_TypeError,
+                        "Constraints cannot be combined with bound=...");
+        Py_XDECREF(bound);
+        return NULL;
+    }
+    PyObject *module = caller();
+    if (module == NULL) {
+        Py_XDECREF(bound);
+        return NULL;
+    }
+
+    PyObject *tv = (PyObject *)typevar_alloc(name, bound, NULL,
+                                             constraints, NULL,
+                                             covariant, contravariant,
+                                             infer_variance, module);
+    Py_XDECREF(bound);
+    Py_XDECREF(module);
+    return tv;
+}
+
+/*[clinic input]
+typevar.__typing_subst__ as typevar_typing_subst
+
+    arg: object
+
+[clinic start generated code]*/
+
+static PyObject *
+typevar_typing_subst_impl(typevarobject *self, PyObject *arg)
+/*[clinic end generated code: output=c76ced134ed8f4e1 input=6b70a4bb2da838de]*/
+{
+    PyObject *args[2] = {(PyObject *)self, arg};
+    PyObject *result = call_typing_func_object("_typevar_subst", args, 2);
+    return result;
+}
+
+/*[clinic input]
+typevar.__reduce__ as typevar_reduce
+
+[clinic start generated code]*/
+
+static PyObject *
+typevar_reduce_impl(typevarobject *self)
+/*[clinic end generated code: output=02e5c55d7cf8a08f input=de76bc95f04fb9ff]*/
+{
+    return Py_NewRef(self->name);
+}
+
+static PyObject *
+typevar_mro_entries(PyObject *self, PyObject *args)
+{
+    PyErr_SetString(PyExc_TypeError,
+                    "Cannot subclass an instance of TypeVar");
+    return NULL;
+}
+
+static PyMethodDef typevar_methods[] = {
+    TYPEVAR_TYPING_SUBST_METHODDEF
+    TYPEVAR_REDUCE_METHODDEF
+    {"__mro_entries__", typevar_mro_entries, METH_O},
+    {0}
+};
+
+PyDoc_STRVAR(typevar_doc,
+"Type variable.\n\
+\n\
+Usage::\n\
+\n\
+  T = TypeVar('T')  # Can be anything\n\
+  A = TypeVar('A', str, bytes)  # Must be str or bytes\n\
+\n\
+Type variables exist primarily for the benefit of static type\n\
+checkers.  They serve as the parameters for generic types as well\n\
+as for generic function definitions.  See class Generic for more\n\
+information on generic types.  Generic functions work as follows:\n\
+\n\
+  def repeat(x: T, n: int) -> List[T]:\n\
+      '''Return a list containing n references to x.'''\n\
+      return [x]*n\n\
+\n\
+  def longest(x: A, y: A) -> A:\n\
+      '''Return the longest of two strings.'''\n\
+      return x if len(x) >= len(y) else y\n\
+\n\
+The latter example's signature is essentially the overloading\n\
+of (str, str) -> str and (bytes, bytes) -> bytes.  Also note\n\
+that if the arguments are instances of some subclass of str,\n\
+the return type is still plain str.\n\
+\n\
+At runtime, isinstance(x, T) and issubclass(C, T) will raise TypeError.\n\
+\n\
+Type variables defined with covariant=True or contravariant=True\n\
+can be used to declare covariant or contravariant generic types.\n\
+See PEP 484 for more details. By default generic types are invariant\n\
+in all type variables.\n\
+\n\
+Type variables can be introspected. e.g.:\n\
+\n\
+  T.__name__ == 'T'\n\
+  T.__constraints__ == ()\n\
+  T.__covariant__ == False\n\
+  T.__contravariant__ = False\n\
+  A.__constraints__ == (str, bytes)\n\
+\n\
+Note that only type variables defined in global scope can be pickled.\n\
+");
+
+static PyType_Slot typevar_slots[] = {
+    {Py_tp_doc, (void *)typevar_doc},
+    {Py_tp_methods, typevar_methods},
+    {Py_nb_or, make_union},
+    {Py_tp_new, typevar_new},
+    {Py_tp_dealloc, typevar_dealloc},
+    {Py_tp_alloc, PyType_GenericAlloc},
+    {Py_tp_free, PyObject_GC_Del},
+    {Py_tp_traverse, typevar_traverse},
+    {Py_tp_clear, typevar_clear},
+    {Py_tp_repr, typevar_repr},
+    {Py_tp_members, typevar_members},
+    {Py_tp_getset, typevar_getset},
+    {0, NULL},
+};
+
+PyType_Spec typevar_spec = {
+    .name = "typing.TypeVar",
+    .basicsize = sizeof(typevarobject),
+    .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE
+        | Py_TPFLAGS_MANAGED_DICT,
+    .slots = typevar_slots,
+};
+
+typedef struct {
+    PyObject_HEAD
+    PyObject *__origin__;
+} paramspecattrobject;
+
+static void
+paramspecattr_dealloc(PyObject *self)
+{
+    PyTypeObject *tp = Py_TYPE(self);
+    paramspecattrobject *psa = (paramspecattrobject *)self;
+
+    _PyObject_GC_UNTRACK(self);
+
+    Py_XDECREF(psa->__origin__);
+
+    Py_TYPE(self)->tp_free(self);
+    Py_DECREF(tp);
+}
+
+static int
+paramspecattr_traverse(PyObject *self, visitproc visit, void *arg)
+{
+    paramspecattrobject *psa = (paramspecattrobject *)self;
+    Py_VISIT(psa->__origin__);
+    return 0;
+}
+
+static int
+paramspecattr_clear(paramspecattrobject *self)
+{
+    Py_CLEAR(self->__origin__);
+    return 0;
+}
+
+static PyObject *
+paramspecattr_richcompare(PyObject *a, PyObject *b, int op)
+{
+    if (!Py_IS_TYPE(a, Py_TYPE(b))) {
+        Py_RETURN_NOTIMPLEMENTED;
+    }
+    if (op != Py_EQ && op != Py_NE) {
+        Py_RETURN_NOTIMPLEMENTED;
+    }
+    return PyObject_RichCompare(
+        ((paramspecattrobject *)a)->__origin__,
+        ((paramspecattrobject *)b)->__origin__,
+        op
+    );
+}
+
+static PyMemberDef paramspecattr_members[] = {
+    {"__origin__", T_OBJECT, offsetof(paramspecattrobject, __origin__), READONLY},
+    {0}
+};
+
+static paramspecattrobject *
+paramspecattr_new(PyTypeObject *tp, PyObject *origin)
+{
+    paramspecattrobject *psa = PyObject_GC_New(paramspecattrobject, tp);
+    if (psa == NULL) {
+        return NULL;
+    }
+    psa->__origin__ = Py_NewRef(origin);
+    _PyObject_GC_TRACK(psa);
+    return psa;
+}
+
+static PyObject *
+paramspecargs_repr(PyObject *self)
+{
+    paramspecattrobject *psa = (paramspecattrobject *)self;
+
+    PyTypeObject *tp = PyInterpreterState_Get()->cached_objects.paramspec_type;
+    if (Py_IS_TYPE(psa->__origin__, tp)) {
+        return PyUnicode_FromFormat("%U.args",
+            ((paramspecobject *)psa->__origin__)->name);
+    }
+    return PyUnicode_FromFormat("%R.args", psa->__origin__);
+}
+
+
+/*[clinic input]
+ at classmethod
+paramspecargs.__new__ as paramspecargs_new
+
+    origin: object
+
+Create a ParamSpecArgs object.
+[clinic start generated code]*/
+
+static PyObject *
+paramspecargs_new_impl(PyTypeObject *type, PyObject *origin)
+/*[clinic end generated code: output=9a1463dc8942fe4e input=3596a0bb6183c208]*/
+{
+    return (PyObject *)paramspecattr_new(type, origin);
+}
+
+static PyObject *
+paramspecargs_mro_entries(PyObject *self, PyObject *args)
+{
+    PyErr_SetString(PyExc_TypeError,
+                    "Cannot subclass an instance of ParamSpecArgs");
+    return NULL;
+}
+
+static PyMethodDef paramspecargs_methods[] = {
+    {"__mro_entries__", paramspecargs_mro_entries, METH_O},
+    {0}
+};
+
+PyDoc_STRVAR(paramspecargs_doc,
+"The args for a ParamSpec object.\n\
+\n\
+Given a ParamSpec object P, P.args is an instance of ParamSpecArgs.\n\
+\n\
+ParamSpecArgs objects have a reference back to their ParamSpec:\n\
+\n\
+    P.args.__origin__ is P\n\
+\n\
+This type is meant for runtime introspection and has no special meaning to\n\
+static type checkers.\n\
+");
+
+static PyType_Slot paramspecargs_slots[] = {
+    {Py_tp_doc, (void *)paramspecargs_doc},
+    {Py_tp_methods, paramspecargs_methods},
+    {Py_tp_new, paramspecargs_new},
+    {Py_tp_dealloc, paramspecattr_dealloc},
+    {Py_tp_alloc, PyType_GenericAlloc},
+    {Py_tp_free, PyObject_GC_Del},
+    {Py_tp_traverse, paramspecattr_traverse},
+    {Py_tp_clear, (inquiry)paramspecattr_clear},
+    {Py_tp_repr, paramspecargs_repr},
+    {Py_tp_members, paramspecattr_members},
+    {Py_tp_richcompare, paramspecattr_richcompare},
+    {0, NULL},
+};
+
+PyType_Spec paramspecargs_spec = {
+    .name = "typing.ParamSpecArgs",
+    .basicsize = sizeof(paramspecattrobject),
+    .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE,
+    .slots = paramspecargs_slots,
+};
+
+static PyObject *
+paramspeckwargs_repr(PyObject *self)
+{
+    paramspecattrobject *psk = (paramspecattrobject *)self;
+
+    PyTypeObject *tp = PyInterpreterState_Get()->cached_objects.paramspec_type;
+    if (Py_IS_TYPE(psk->__origin__, tp)) {
+        return PyUnicode_FromFormat("%U.kwargs",
+            ((paramspecobject *)psk->__origin__)->name);
+    }
+    return PyUnicode_FromFormat("%R.kwargs", psk->__origin__);
+}
+
+/*[clinic input]
+ at classmethod
+paramspeckwargs.__new__ as paramspeckwargs_new
+
+    origin: object
+
+Create a ParamSpecKwargs object.
+[clinic start generated code]*/
+
+static PyObject *
+paramspeckwargs_new_impl(PyTypeObject *type, PyObject *origin)
+/*[clinic end generated code: output=277b11967ebaf4ab input=981bca9b0cf9e40a]*/
+{
+    return (PyObject *)paramspecattr_new(type, origin);
+}
+
+static PyObject *
+paramspeckwargs_mro_entries(PyObject *self, PyObject *args)
+{
+    PyErr_SetString(PyExc_TypeError,
+                    "Cannot subclass an instance of ParamSpecKwargs");
+    return NULL;
+}
+
+static PyMethodDef paramspeckwargs_methods[] = {
+    {"__mro_entries__", paramspeckwargs_mro_entries, METH_O},
+    {0}
+};
+
+PyDoc_STRVAR(paramspeckwargs_doc,
+"The kwargs for a ParamSpec object.\n\
+\n\
+Given a ParamSpec object P, P.kwargs is an instance of ParamSpecKwargs.\n\
+\n\
+ParamSpecKwargs objects have a reference back to their ParamSpec:\n\
+\n\
+    P.kwargs.__origin__ is P\n\
+\n\
+This type is meant for runtime introspection and has no special meaning to\n\
+static type checkers.\n\
+");
+
+static PyType_Slot paramspeckwargs_slots[] = {
+    {Py_tp_doc, (void *)paramspeckwargs_doc},
+    {Py_tp_methods, paramspeckwargs_methods},
+    {Py_tp_new, paramspeckwargs_new},
+    {Py_tp_dealloc, paramspecattr_dealloc},
+    {Py_tp_alloc, PyType_GenericAlloc},
+    {Py_tp_free, PyObject_GC_Del},
+    {Py_tp_traverse, paramspecattr_traverse},
+    {Py_tp_clear, (inquiry)paramspecattr_clear},
+    {Py_tp_repr, paramspeckwargs_repr},
+    {Py_tp_members, paramspecattr_members},
+    {Py_tp_richcompare, paramspecattr_richcompare},
+    {0, NULL},
+};
+
+PyType_Spec paramspeckwargs_spec = {
+    .name = "typing.ParamSpecKwargs",
+    .basicsize = sizeof(paramspecattrobject),
+    .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE,
+    .slots = paramspeckwargs_slots,
+};
+
+static void
+paramspec_dealloc(PyObject *self)
+{
+    PyTypeObject *tp = Py_TYPE(self);
+    paramspecobject *ps = (paramspecobject *)self;
+
+    _PyObject_GC_UNTRACK(self);
+
+    Py_DECREF(ps->name);
+    Py_XDECREF(ps->bound);
+    _PyObject_ClearManagedDict(self);
+
+    Py_TYPE(self)->tp_free(self);
+    Py_DECREF(tp);
+}
+
+static int
+paramspec_traverse(PyObject *self, visitproc visit, void *arg)
+{
+    Py_VISIT(Py_TYPE(self));
+    paramspecobject *ps = (paramspecobject *)self;
+    Py_VISIT(ps->bound);
+    _PyObject_VisitManagedDict(self, visit, arg);
+    return 0;
+}
+
+static int
+paramspec_clear(paramspecobject *self)
+{
+    Py_CLEAR(self->bound);
+    _PyObject_ClearManagedDict((PyObject *)self);
+    return 0;
+}
+
+static PyObject *
+paramspec_repr(PyObject *self)
+{
+    paramspecobject *ps = (paramspecobject *)self;
+
+    if (ps->infer_variance) {
+        return Py_NewRef(ps->name);
+    }
+
+    char variance = ps->covariant ? '+' : ps->contravariant ? '-' : '~';
+    return PyUnicode_FromFormat("%c%U", variance, ps->name);
+}
+
+static PyMemberDef paramspec_members[] = {
+    {"__name__", T_OBJECT, offsetof(paramspecobject, name), READONLY},
+    {"__bound__", T_OBJECT, offsetof(paramspecobject, bound), READONLY},
+    {"__covariant__", T_BOOL, offsetof(paramspecobject, covariant), READONLY},
+    {"__contravariant__", T_BOOL, offsetof(paramspecobject, contravariant), READONLY},
+    {"__infer_variance__", T_BOOL, offsetof(paramspecobject, infer_variance), READONLY},
+    {0}
+};
+
+static PyObject *
+paramspec_args(PyObject *self, void *unused)
+{
+    PyTypeObject *tp = PyInterpreterState_Get()->cached_objects.paramspecargs_type;
+    return (PyObject *)paramspecattr_new(tp, self);
+}
+
+static PyObject *
+paramspec_kwargs(PyObject *self, void *unused)
+{
+    PyTypeObject *tp = PyInterpreterState_Get()->cached_objects.paramspeckwargs_type;
+    return (PyObject *)paramspecattr_new(tp, self);
+}
+
+static PyGetSetDef paramspec_getset[] = {
+    {"args", (getter)paramspec_args, NULL, "Represents positional arguments.", NULL},
+    {"kwargs", (getter)paramspec_kwargs, NULL, "Represents keyword arguments.", NULL},
+    {0},
+};
+
+static paramspecobject *
+paramspec_alloc(PyObject *name, PyObject *bound, bool covariant,
+                bool contravariant, bool infer_variance, PyObject *module)
+{
+    PyTypeObject *tp = PyInterpreterState_Get()->cached_objects.paramspec_type;
+    paramspecobject *ps = PyObject_GC_New(paramspecobject, tp);
+    if (ps == NULL) {
+        return NULL;
+    }
+    ps->name = Py_NewRef(name);
+    ps->bound = Py_XNewRef(bound);
+    ps->covariant = covariant;
+    ps->contravariant = contravariant;
+    ps->infer_variance = infer_variance;
+    _PyObject_GC_TRACK(ps);
+    if (module != NULL) {
+        if (PyObject_SetAttrString((PyObject *)ps, "__module__", module) < 0) {
+            Py_DECREF(ps);
+            return NULL;
+        }
+    }
+    return ps;
+}
+
+/*[clinic input]
+ at classmethod
+paramspec.__new__ as paramspec_new
+
+    name: object(subclass_of="&PyUnicode_Type")
+    *
+    bound: object = None
+    covariant: bool = False
+    contravariant: bool = False
+    infer_variance: bool = False
+
+Create a ParamSpec object.
+[clinic start generated code]*/
+
+static PyObject *
+paramspec_new_impl(PyTypeObject *type, PyObject *name, PyObject *bound,
+                   int covariant, int contravariant, int infer_variance)
+/*[clinic end generated code: output=fd2daab79cba62da input=57c49c581979b952]*/
+{
+    if (covariant && contravariant) {
+        PyErr_SetString(PyExc_ValueError, "Bivariant types are not supported.");
+        return NULL;
+    }
+    if (infer_variance && (covariant || contravariant)) {
+        PyErr_SetString(PyExc_ValueError, "Variance cannot be specified with infer_variance.");
+        return NULL;
+    }
+    if (bound != NULL) {
+        bound = type_check(bound, "Bound must be a type.");
+        if (bound == NULL) {
+            return NULL;
+        }
+    }
+    PyObject *module = caller();
+    if (module == NULL) {
+        Py_XDECREF(bound);
+        return NULL;
+    }
+    PyObject *ps = (PyObject *)paramspec_alloc(
+        name, bound, covariant, contravariant, infer_variance, module);
+    Py_XDECREF(bound);
+    Py_DECREF(module);
+    return ps;
+}
+
+
+/*[clinic input]
+paramspec.__typing_subst__ as paramspec_typing_subst
+
+    arg: object
+
+[clinic start generated code]*/
+
+static PyObject *
+paramspec_typing_subst_impl(paramspecobject *self, PyObject *arg)
+/*[clinic end generated code: output=803e1ade3f13b57d input=4e0005d24023e896]*/
+{
+    PyObject *args[2] = {(PyObject *)self, arg};
+    PyObject *result = call_typing_func_object("_paramspec_subst", args, 2);
+    return result;
+}
+
+/*[clinic input]
+paramspec.__typing_prepare_subst__ as paramspec_typing_prepare_subst
+
+    alias: object
+    args: object
+
+[clinic start generated code]*/
+
+static PyObject *
+paramspec_typing_prepare_subst_impl(paramspecobject *self, PyObject *alias,
+                                    PyObject *args)
+/*[clinic end generated code: output=95449d630a2adb9a input=4375e2ffcb2ad635]*/
+{
+    PyObject *args_array[3] = {(PyObject *)self, alias, args};
+    PyObject *result = call_typing_func_object(
+        "_paramspec_prepare_subst", args_array, 3);
+    return result;
+}
+
+/*[clinic input]
+paramspec.__reduce__ as paramspec_reduce
+
+[clinic start generated code]*/
+
+static PyObject *
+paramspec_reduce_impl(paramspecobject *self)
+/*[clinic end generated code: output=b83398674416db27 input=5bf349f0d5dd426c]*/
+{
+    return Py_NewRef(self->name);
+}
+
+static PyObject *
+paramspec_mro_entries(PyObject *self, PyObject *args)
+{
+    PyErr_SetString(PyExc_TypeError,
+                    "Cannot subclass an instance of ParamSpec");
+    return NULL;
+}
+
+static PyMethodDef paramspec_methods[] = {
+    PARAMSPEC_TYPING_SUBST_METHODDEF
+    PARAMSPEC_TYPING_PREPARE_SUBST_METHODDEF
+    PARAMSPEC_REDUCE_METHODDEF
+    {"__mro_entries__", paramspec_mro_entries, METH_O},
+    {0}
+};
+
+PyDoc_STRVAR(paramspec_doc,
+"Parameter specification variable.\n\
+\n\
+Usage::\n\
+\n\
+    P = ParamSpec('P')\n\
+\n\
+Parameter specification variables exist primarily for the benefit of static\n\
+type checkers.  They are used to forward the parameter types of one\n\
+callable to another callable, a pattern commonly found in higher order\n\
+functions and decorators.  They are only valid when used in ``Concatenate``,\n\
+or as the first argument to ``Callable``, or as parameters for user-defined\n\
+Generics.  See class Generic for more information on generic types.  An\n\
+example for annotating a decorator::\n\
+\n\
+    T = TypeVar('T')\n\
+    P = ParamSpec('P')\n\
+\n\
+    def add_logging(f: Callable[P, T]) -> Callable[P, T]:\n\
+        '''A type-safe decorator to add logging to a function.'''\n\
+        def inner(*args: P.args, **kwargs: P.kwargs) -> T:\n\
+            logging.info(f'{f.__name__} was called')\n\
+            return f(*args, **kwargs)\n\
+        return inner\n\
+\n\
+    @add_logging\n\
+    def add_two(x: float, y: float) -> float:\n\
+        '''Add two numbers together.'''\n\
+        return x + y\n\
+\n\
+Parameter specification variables defined with covariant=True or\n\
+contravariant=True can be used to declare covariant or contravariant\n\
+generic types.  These keyword arguments are valid, but their actual semantics\n\
+are yet to be decided.  See PEP 612 for details.\n\
+\n\
+Parameter specification variables can be introspected. e.g.:\n\
+\n\
+    P.__name__ == 'P'\n\
+    P.__bound__ == None\n\
+    P.__covariant__ == False\n\
+    P.__contravariant__ == False\n\
+\n\
+Note that only parameter specification variables defined in global scope can\n\
+be pickled.\n\
+");
+
+static PyType_Slot paramspec_slots[] = {
+    {Py_tp_doc, (void *)paramspec_doc},
+    {Py_tp_members, paramspec_members},
+    {Py_tp_methods, paramspec_methods},
+    {Py_tp_getset, paramspec_getset},
+    // Unions of ParamSpecs have no defined meaning, but they were allowed
+    // by the Python implementation, so we allow them here too.
+    {Py_nb_or, make_union},
+    {Py_tp_new, paramspec_new},
+    {Py_tp_dealloc, paramspec_dealloc},
+    {Py_tp_alloc, PyType_GenericAlloc},
+    {Py_tp_free, PyObject_GC_Del},
+    {Py_tp_traverse, paramspec_traverse},
+    {Py_tp_clear, paramspec_clear},
+    {Py_tp_repr, paramspec_repr},
+    {0, 0},
+};
+
+PyType_Spec paramspec_spec = {
+    .name = "typing.ParamSpec",
+    .basicsize = sizeof(paramspecobject),
+    .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE
+        | Py_TPFLAGS_MANAGED_DICT,
+    .slots = paramspec_slots,
+};
+
+static void
+typevartuple_dealloc(PyObject *self)
+{
+    PyTypeObject *tp = Py_TYPE(self);
+    _PyObject_GC_UNTRACK(self);
+    typevartupleobject *tvt = (typevartupleobject *)self;
+
+    Py_DECREF(tvt->name);
+    _PyObject_ClearManagedDict(self);
+
+    Py_TYPE(self)->tp_free(self);
+    Py_DECREF(tp);
+}
+
+static PyObject *
+typevartuple_iter(PyObject *self)
+{
+    PyObject *unpacked = typevartuple_unpack(self);
+    if (unpacked == NULL) {
+        return NULL;
+    }
+    PyObject *tuple = PyTuple_Pack(1, unpacked);
+    if (tuple == NULL) {
+        Py_DECREF(unpacked);
+        return NULL;
+    }
+    PyObject *result = PyObject_GetIter(tuple);
+    Py_DECREF(unpacked);
+    Py_DECREF(tuple);
+    return result;
+}
+
+static PyObject *
+typevartuple_repr(PyObject *self)
+{
+    typevartupleobject *tvt = (typevartupleobject *)self;
+
+    return Py_NewRef(tvt->name);
+}
+
+static PyMemberDef typevartuple_members[] = {
+    {"__name__", T_OBJECT, offsetof(typevartupleobject, name), READONLY},
+    {0}
+};
+
+static typevartupleobject *
+typevartuple_alloc(PyObject *name, PyObject *module)
+{
+    PyTypeObject *tp = PyInterpreterState_Get()->cached_objects.typevartuple_type;
+    typevartupleobject *tvt = PyObject_GC_New(typevartupleobject, tp);
+    if (tvt == NULL) {
+        return NULL;
+    }
+    tvt->name = Py_NewRef(name);
+    _PyObject_GC_TRACK(tvt);
+    if (module != NULL) {
+        if (PyObject_SetAttrString((PyObject *)tvt, "__module__", module) < 0) {
+            Py_DECREF(tvt);
+            return NULL;
+        }
+    }
+    return tvt;
+}
+
+/*[clinic input]
+ at classmethod
+typevartuple.__new__
+
+    name: object(subclass_of="&PyUnicode_Type")
+
+Create a new TypeVarTuple with the given name.
+[clinic start generated code]*/
+
+static PyObject *
+typevartuple_impl(PyTypeObject *type, PyObject *name)
+/*[clinic end generated code: output=09d417a28f976202 input=00d28abcf1fc96bb]*/
+{
+    PyObject *module = caller();
+    if (module == NULL) {
+        return NULL;
+    }
+    PyObject *result = (PyObject *)typevartuple_alloc(name, module);
+    Py_DECREF(module);
+    return result;
+}
+
+/*[clinic input]
+typevartuple.__typing_subst__ as typevartuple_typing_subst
+
+    arg: object
+
+[clinic start generated code]*/
+
+static PyObject *
+typevartuple_typing_subst_impl(typevartupleobject *self, PyObject *arg)
+/*[clinic end generated code: output=814316519441cd76 input=670c4e0a36e5d8c0]*/
+{
+    PyErr_SetString(PyExc_TypeError, "Substitution of bare TypeVarTuple is not supported");
+    return NULL;
+}
+
+/*[clinic input]
+typevartuple.__typing_prepare_subst__ as typevartuple_typing_prepare_subst
+
+    alias: object
+    args: object
+
+[clinic start generated code]*/
+
+static PyObject *
+typevartuple_typing_prepare_subst_impl(typevartupleobject *self,
+                                       PyObject *alias, PyObject *args)
+/*[clinic end generated code: output=ff999bc5b02036c1 input=a211b05f2eeb4306]*/
+{
+    PyObject *args_array[3] = {(PyObject *)self, alias, args};
+    PyObject *result = call_typing_func_object(
+        "_typevartuple_prepare_subst", args_array, 3);
+    return result;
+}
+
+/*[clinic input]
+typevartuple.__reduce__ as typevartuple_reduce
+
+[clinic start generated code]*/
+
+static PyObject *
+typevartuple_reduce_impl(typevartupleobject *self)
+/*[clinic end generated code: output=3215bc0477913d20 input=3018a4d66147e807]*/
+{
+    return Py_NewRef(self->name);
+}
+
+static PyObject *
+typevartuple_mro_entries(PyObject *self, PyObject *args)
+{
+    PyErr_SetString(PyExc_TypeError,
+                    "Cannot subclass an instance of TypeVarTuple");
+    return NULL;
+}
+
+static int
+typevartuple_traverse(PyObject *self, visitproc visit, void *arg)
+{
+    Py_VISIT(Py_TYPE(self));
+    _PyObject_VisitManagedDict(self, visit, arg);
+    return 0;
+}
+
+static int
+typevartuple_clear(PyObject *self)
+{
+    _PyObject_ClearManagedDict(self);
+    return 0;
+}
+
+static PyMethodDef typevartuple_methods[] = {
+    TYPEVARTUPLE_TYPING_SUBST_METHODDEF
+    TYPEVARTUPLE_TYPING_PREPARE_SUBST_METHODDEF
+    TYPEVARTUPLE_REDUCE_METHODDEF
+    {"__mro_entries__", typevartuple_mro_entries, METH_O},
+    {0}
+};
+
+PyDoc_STRVAR(typevartuple_doc,
+"Type variable tuple.\n\
+\n\
+Usage:\n\
+\n\
+  Ts = TypeVarTuple('Ts')  # Can be given any name\n\
+\n\
+Just as a TypeVar (type variable) is a placeholder for a single type,\n\
+a TypeVarTuple is a placeholder for an *arbitrary* number of types. For\n\
+example, if we define a generic class using a TypeVarTuple:\n\
+\n\
+  class C(Generic[*Ts]): ...\n\
+\n\
+Then we can parameterize that class with an arbitrary number of type\n\
+arguments:\n\
+\n\
+  C[int]       # Fine\n\
+  C[int, str]  # Also fine\n\
+  C[()]        # Even this is fine\n\
+\n\
+For more details, see PEP 646.\n\
+\n\
+Note that only TypeVarTuples defined in global scope can be pickled.\n\
+");
+
+PyType_Slot typevartuple_slots[] = {
+    {Py_tp_doc, (void *)typevartuple_doc},
+    {Py_tp_members, typevartuple_members},
+    {Py_tp_methods, typevartuple_methods},
+    {Py_tp_new, typevartuple},
+    {Py_tp_iter, typevartuple_iter},
+    {Py_tp_repr, typevartuple_repr},
+    {Py_tp_dealloc, typevartuple_dealloc},
+    {Py_tp_alloc, PyType_GenericAlloc},
+    {Py_tp_free, PyObject_GC_Del},
+    {Py_tp_traverse, typevartuple_traverse},
+    {Py_tp_clear, typevartuple_clear},
+    {0, 0},
+};
+
+PyType_Spec typevartuple_spec = {
+    .name = "typing.TypeVarTuple",
+    .basicsize = sizeof(typevartupleobject),
+    .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_MANAGED_DICT
+        | Py_TPFLAGS_HAVE_GC,
+    .slots = typevartuple_slots,
+};
+
+PyObject *
+_Py_make_typevar(PyObject *name, PyObject *evaluate_bound, PyObject *evaluate_constraints)
+{
+    return (PyObject *)typevar_alloc(name, NULL, evaluate_bound, NULL, evaluate_constraints,
+                                     false, false, true, NULL);
+}
+
+PyObject *
+_Py_make_paramspec(PyThreadState *Py_UNUSED(ignored), PyObject *v)
+{
+    assert(PyUnicode_Check(v));
+    return (PyObject *)paramspec_alloc(v, NULL, false, false, true, NULL);
+}
+
+PyObject *
+_Py_make_typevartuple(PyThreadState *Py_UNUSED(ignored), PyObject *v)
+{
+    assert(PyUnicode_Check(v));
+    return (PyObject *)typevartuple_alloc(v, NULL);
+}
+
+static void
+typealias_dealloc(PyObject *self)
+{
+    PyTypeObject *tp = Py_TYPE(self);
+    _PyObject_GC_UNTRACK(self);
+    typealiasobject *ta = (typealiasobject *)self;
+    Py_DECREF(ta->name);
+    Py_XDECREF(ta->type_params);
+    Py_XDECREF(ta->compute_value);
+    Py_XDECREF(ta->value);
+    Py_TYPE(self)->tp_free(self);
+    Py_DECREF(tp);
+}
+
+static PyObject *
+typealias_get_value(typealiasobject *ta)
+{
+    if (ta->value != NULL) {
+        return Py_NewRef(ta->value);
+    }
+    PyObject *result = PyObject_CallNoArgs(ta->compute_value);
+    if (result == NULL) {
+        return NULL;
+    }
+    ta->value = Py_NewRef(result);
+    return result;
+}
+
+static PyObject *
+typealias_repr(PyObject *self)
+{
+    typealiasobject *ta = (typealiasobject *)self;
+    return Py_NewRef(ta->name);
+}
+
+static PyMemberDef typealias_members[] = {
+    {"__name__", T_OBJECT, offsetof(typealiasobject, name), READONLY},
+    {0}
+};
+
+static PyObject *
+typealias_value(PyObject *self, void *unused)
+{
+    typealiasobject *ta = (typealiasobject *)self;
+    return typealias_get_value(ta);
+}
+
+static PyObject *
+typealias_parameters(PyObject *self, void *unused)
+{
+    typealiasobject *ta = (typealiasobject *)self;
+    if (ta->type_params == NULL) {
+        return PyTuple_New(0);
+    }
+    return unpack_typevartuples(ta->type_params);
+}
+
+static PyObject *
+typealias_type_params(PyObject *self, void *unused)
+{
+    typealiasobject *ta = (typealiasobject *)self;
+    if (ta->type_params == NULL) {
+        return PyTuple_New(0);
+    }
+    return Py_NewRef(ta->type_params);
+}
+
+static PyGetSetDef typealias_getset[] = {
+    {"__parameters__", typealias_parameters, (setter)NULL, NULL, NULL},
+    {"__type_params__", typealias_type_params, (setter)NULL, NULL, NULL},
+    {"__value__", typealias_value, (setter)NULL, NULL, NULL},
+    {0}
+};
+
+static typealiasobject *
+typealias_alloc(PyObject *name, PyObject *type_params, PyObject *compute_value,
+                PyObject *value)
+{
+    PyTypeObject *tp = PyInterpreterState_Get()->cached_objects.typealias_type;
+    typealiasobject *ta = PyObject_GC_New(typealiasobject, tp);
+    if (ta == NULL) {
+        return NULL;
+    }
+    ta->name = Py_NewRef(name);
+    ta->type_params = Py_IsNone(type_params) ? NULL : Py_XNewRef(type_params);
+    ta->compute_value = Py_XNewRef(compute_value);
+    ta->value = Py_XNewRef(value);
+    _PyObject_GC_TRACK(ta);
+    return ta;
+}
+
+static int
+typealias_traverse(typealiasobject *self, visitproc visit, void *arg)
+{
+    Py_VISIT(self->type_params);
+    Py_VISIT(self->compute_value);
+    Py_VISIT(self->value);
+    return 0;
+}
+
+static int
+typealias_clear(typealiasobject *self)
+{
+    Py_CLEAR(self->type_params);
+    Py_CLEAR(self->compute_value);
+    Py_CLEAR(self->value);
+    return 0;
+}
+
+/*[clinic input]
+typealias.__reduce__ as typealias_reduce
+
+[clinic start generated code]*/
+
+static PyObject *
+typealias_reduce_impl(typealiasobject *self)
+/*[clinic end generated code: output=913724f92ad3b39b input=4f06fbd9472ec0f1]*/
+{
+    return Py_NewRef(self->name);
+}
+
+static PyObject *
+typealias_subscript(PyObject *self, PyObject *args)
+{
+    if (((typealiasobject *)self)->type_params == NULL) {
+        PyErr_SetString(PyExc_TypeError,
+                        "Only generic type aliases are subscriptable");
+        return NULL;
+    }
+    return Py_GenericAlias(self, args);
+}
+
+static PyMethodDef typealias_methods[] = {
+    TYPEALIAS_REDUCE_METHODDEF
+    {0}
+};
+
+
+/*[clinic input]
+ at classmethod
+typealias.__new__ as typealias_new
+
+    name: object(subclass_of="&PyUnicode_Type")
+    value: object
+    *
+    type_params: object = NULL
+
+Create a TypeAliasType.
+[clinic start generated code]*/
+
+static PyObject *
+typealias_new_impl(PyTypeObject *type, PyObject *name, PyObject *value,
+                   PyObject *type_params)
+/*[clinic end generated code: output=8920ce6bdff86f00 input=df163c34e17e1a35]*/
+{
+    if (type_params != NULL && !PyTuple_Check(type_params)) {
+        PyErr_SetString(PyExc_TypeError, "type_params must be a tuple");
+        return NULL;
+    }
+    return (PyObject *)typealias_alloc(name, type_params, NULL, value);
+}
+
+PyDoc_STRVAR(typealias_doc,
+"Type alias.\n\
+\n\
+Type aliases are created through the type statement:\n\
+\n\
+  type Alias = int\n\
+");
+
+static PyType_Slot typealias_slots[] = {
+    {Py_tp_doc, (void *)typealias_doc},
+    {Py_tp_members, typealias_members},
+    {Py_tp_methods, typealias_methods},
+    {Py_tp_getset, typealias_getset},
+    {Py_mp_subscript, typealias_subscript},
+    {Py_tp_dealloc, typealias_dealloc},
+    {Py_tp_alloc, PyType_GenericAlloc},
+    {Py_tp_new, typealias_new},
+    {Py_tp_free, PyObject_GC_Del},
+    {Py_tp_traverse, (traverseproc)typealias_traverse},
+    {Py_tp_clear, (inquiry)typealias_clear},
+    {Py_tp_repr, typealias_repr},
+    {Py_nb_or, _Py_union_type_or},
+    {0, 0},
+};
+
+PyType_Spec typealias_spec = {
+    .name = "typing.TypeAliasType",
+    .basicsize = sizeof(typealiasobject),
+    .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_HAVE_GC,
+    .slots = typealias_slots,
+};
+
+PyObject *
+_Py_make_typealias(PyThreadState* unused, PyObject *args)
+{
+    assert(PyTuple_Check(args));
+    assert(PyTuple_GET_SIZE(args) == 3);
+    PyObject *name = PyTuple_GET_ITEM(args, 0);
+    assert(PyUnicode_Check(name));
+    PyObject *type_params = PyTuple_GET_ITEM(args, 1);
+    PyObject *compute_value = PyTuple_GET_ITEM(args, 2);
+    return (PyObject *)typealias_alloc(name, type_params, compute_value, NULL);
+}
+
+PyDoc_STRVAR(generic_doc,
+"Abstract base class for generic types.\n\
+\n\
+A generic type is typically declared by inheriting from\n\
+this class parameterized with one or more type variables.\n\
+For example, a generic mapping type might be defined as::\n\
+\n\
+    class Mapping(Generic[KT, VT]):\n\
+        def __getitem__(self, key: KT) -> VT:\n\
+            ...\n\
+        # Etc.\n\
+\n\
+This class can then be used as follows::\n\
+\n\
+    def lookup_name(mapping: Mapping[KT, VT], key: KT, default: VT) -> VT:\n\
+        try:\n\
+            return mapping[key]\n\
+        except KeyError:\n\
+            return default\n\
+");
+
+PyDoc_STRVAR(generic_class_getitem_doc,
+"Parameterizes a generic class.\n\
+\n\
+At least, parameterizing a generic class is the *main* thing this method\n\
+does. For example, for some generic class `Foo`, this is called when we\n\
+do `Foo[int]` - there, with `cls=Foo` and `params=int`.\n\
+\n\
+However, note that this method is also called when defining generic\n\
+classes in the first place with `class Foo(Generic[T]): ...`.\n\
+");
+
+static PyObject *
+call_typing_args_kwargs(const char *name, PyTypeObject *cls, PyObject *args, PyObject *kwargs)
+{
+    PyObject *typing = NULL, *func = NULL, *new_args = NULL;
+    typing = PyImport_ImportModule("typing");
+    if (typing == NULL) {
+        goto error;
+    }
+    func = PyObject_GetAttrString(typing, name);
+    if (func == NULL) {
+        goto error;
+    }
+    assert(PyTuple_Check(args));
+    Py_ssize_t nargs = PyTuple_GET_SIZE(args);
+    new_args = PyTuple_New(nargs + 1);
+    if (new_args == NULL) {
+        goto error;
+    }
+    PyTuple_SET_ITEM(new_args, 0, Py_NewRef((PyObject *)cls));
+    for (Py_ssize_t i = 0; i < nargs; i++) {
+        PyObject *arg = PyTuple_GET_ITEM(args, i);
+        PyTuple_SET_ITEM(new_args, i + 1, Py_NewRef(arg));
+    }
+    PyObject *result = PyObject_Call(func, new_args, kwargs);
+    Py_DECREF(typing);
+    Py_DECREF(func);
+    Py_DECREF(new_args);
+    return result;
+error:
+    Py_XDECREF(typing);
+    Py_XDECREF(func);
+    Py_XDECREF(new_args);
+    return NULL;
+}
+
+static PyObject *
+generic_init_subclass(PyTypeObject *cls, PyObject *args, PyObject *kwargs)
+{
+    return call_typing_args_kwargs("_generic_init_subclass", cls, args, kwargs);
+}
+
+static PyObject *
+generic_class_getitem(PyTypeObject *cls, PyObject *args, PyObject *kwargs)
+{
+    return call_typing_args_kwargs("_generic_class_getitem", cls, args, kwargs);
+}
+
+PyObject *
+_Py_subscript_generic(PyThreadState* unused, PyObject *params)
+{
+    params = unpack_typevartuples(params);
+
+    PyInterpreterState *interp = PyInterpreterState_Get();
+    if (interp->cached_objects.generic_type == NULL) {
+        PyErr_SetString(PyExc_SystemError, "Cannot find Generic type");
+        return NULL;
+    }
+    PyObject *args[2] = {(PyObject *)interp->cached_objects.generic_type, params};
+    PyObject *result = call_typing_func_object("_GenericAlias", args, 2);
+    Py_DECREF(params);
+    return result;
+}
+
+static PyMethodDef generic_methods[] = {
+    {"__class_getitem__", (PyCFunction)(void (*)(void))generic_class_getitem,
+     METH_VARARGS | METH_KEYWORDS | METH_CLASS,
+     generic_class_getitem_doc},
+    {"__init_subclass__", (PyCFunction)(void (*)(void))generic_init_subclass,
+     METH_VARARGS | METH_KEYWORDS | METH_CLASS,
+     PyDoc_STR("Function to initialize subclasses.")},
+    {NULL} /* Sentinel */
+};
+
+static void
+generic_dealloc(PyObject *self)
+{
+    PyTypeObject *tp = Py_TYPE(self);
+    _PyObject_GC_UNTRACK(self);
+    Py_TYPE(self)->tp_free(self);
+    Py_DECREF(tp);
+}
+
+static int
+generic_traverse(PyObject *self, visitproc visit, void *arg)
+{
+    Py_VISIT(Py_TYPE(self));
+    return 0;
+}
+
+static PyType_Slot generic_slots[] = {
+    {Py_tp_doc, (void *)generic_doc},
+    {Py_tp_methods, generic_methods},
+    {Py_tp_dealloc, generic_dealloc},
+    {Py_tp_alloc, PyType_GenericAlloc},
+    {Py_tp_free, PyObject_GC_Del},
+    {Py_tp_traverse, generic_traverse},
+    {0, NULL},
+};
+
+PyType_Spec generic_spec = {
+    .name = "typing.Generic",
+    .basicsize = sizeof(PyObject),
+    .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
+    .slots = generic_slots,
+};
+
+int _Py_initialize_generic(PyInterpreterState *interp)
+{
+#define MAKE_TYPE(name) \
+    do { \
+        PyTypeObject *name ## _type = (PyTypeObject *)PyType_FromSpec(&name ## _spec); \
+        if (name ## _type == NULL) { \
+            return -1; \
+        } \
+        interp->cached_objects.name ## _type = name ## _type; \
+    } while(0)
+
+    MAKE_TYPE(generic);
+    MAKE_TYPE(typevar);
+    MAKE_TYPE(typevartuple);
+    MAKE_TYPE(paramspec);
+    MAKE_TYPE(paramspecargs);
+    MAKE_TYPE(paramspeckwargs);
+    MAKE_TYPE(typealias);
+#undef MAKE_TYPE
+    return 0;
+}
+
+void _Py_clear_generic_types(PyInterpreterState *interp)
+{
+    Py_CLEAR(interp->cached_objects.generic_type);
+    Py_CLEAR(interp->cached_objects.typevar_type);
+    Py_CLEAR(interp->cached_objects.typevartuple_type);
+    Py_CLEAR(interp->cached_objects.paramspec_type);
+    Py_CLEAR(interp->cached_objects.paramspecargs_type);
+    Py_CLEAR(interp->cached_objects.paramspeckwargs_type);
+    Py_CLEAR(interp->cached_objects.typealias_type);
+}
diff --git a/Objects/unionobject.c b/Objects/unionobject.c
index f273f7d15ef2..9806678b8048 100644
--- a/Objects/unionobject.c
+++ b/Objects/unionobject.c
@@ -147,10 +147,14 @@ get_types(PyObject **obj, Py_ssize_t *size)
 static int
 is_unionable(PyObject *obj)
 {
-    return (obj == Py_None ||
+    if (obj == Py_None ||
         PyType_Check(obj) ||
         _PyGenericAlias_Check(obj) ||
-        _PyUnion_Check(obj));
+        _PyUnion_Check(obj)) {
+        return 1;
+    }
+    PyInterpreterState *interp = PyInterpreterState_Get();
+    return Py_IS_TYPE(obj, interp->cached_objects.typealias_type);
 }
 
 PyObject *
diff --git a/PCbuild/_freeze_module.vcxproj b/PCbuild/_freeze_module.vcxproj
index d897925f58c0..c9dbe195d932 100644
--- a/PCbuild/_freeze_module.vcxproj
+++ b/PCbuild/_freeze_module.vcxproj
@@ -159,6 +159,7 @@
     <ClCompile Include="..\Objects\structseq.c" />
     <ClCompile Include="..\Objects\tupleobject.c" />
     <ClCompile Include="..\Objects\typeobject.c" />
+    <ClCompile Include="..\Objects\typevarobject.c" />
     <ClCompile Include="..\Objects\unicodectype.c" />
     <ClCompile Include="..\Objects\unicodeobject.c" />
     <ClCompile Include="..\Objects\unionobject.c" />
diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj
index 28b1517c6f6b..ca43404454c4 100644
--- a/PCbuild/pythoncore.vcxproj
+++ b/PCbuild/pythoncore.vcxproj
@@ -269,6 +269,7 @@
     <ClInclude Include="..\Include\internal\pycore_tracemalloc.h" />
     <ClInclude Include="..\Include\internal\pycore_tuple.h" />
     <ClInclude Include="..\Include\internal\pycore_typeobject.h" />
+    <ClInclude Include="..\Include\internal\pycore_typevarobject.h" />
     <ClInclude Include="..\Include\internal\pycore_ucnhash.h" />
     <ClInclude Include="..\Include\internal\pycore_unionobject.h" />
     <ClInclude Include="..\Include\internal\pycore_unicodeobject.h" />
@@ -481,6 +482,7 @@
     <ClCompile Include="..\Objects\structseq.c" />
     <ClCompile Include="..\Objects\tupleobject.c" />
     <ClCompile Include="..\Objects\typeobject.c" />
+    <ClCompile Include="..\Objects\typevarobject.c" />
     <ClCompile Include="..\Objects\unicodectype.c" />
     <ClCompile Include="..\Objects\unicodeobject.c" />
     <ClCompile Include="..\Objects\unionobject.c" />
diff --git a/PCbuild/pythoncore.vcxproj.filters b/PCbuild/pythoncore.vcxproj.filters
index 75e6fbb13f98..a3c2e2476dd6 100644
--- a/PCbuild/pythoncore.vcxproj.filters
+++ b/PCbuild/pythoncore.vcxproj.filters
@@ -705,6 +705,9 @@
     <ClInclude Include="..\Include\internal\pycore_typeobject.h">
       <Filter>Include\internal</Filter>
     </ClInclude>
+    <ClInclude Include="..\Include\internal\pycore_typevarobject.h">
+      <Filter>Include\internal</Filter>
+    </ClInclude>
     <ClInclude Include="..\Include\internal\pycore_ucnhash.h">
       <Filter>Include\internal</Filter>
     </ClInclude>
@@ -1364,6 +1367,9 @@
     <ClCompile Include="..\Objects\genericaliasobject.c">
       <Filter>Objects</Filter>
     </ClCompile>
+    <ClCompile Include="..\Objects\typevarobject.c">
+      <Filter>Objects</Filter>
+    </ClCompile>
     <ClCompile Include="..\Objects\unionobject.c">
       <Filter>Objects</Filter>
     </ClCompile>
diff --git a/Parser/Python.asdl b/Parser/Python.asdl
index e9423a7c984f..cfc41ef45b56 100644
--- a/Parser/Python.asdl
+++ b/Parser/Python.asdl
@@ -8,14 +8,15 @@ module Python
         | Expression(expr body)
         | FunctionType(expr* argtypes, expr returns)
 
-    stmt = FunctionDef(identifier name, arguments args,
+    stmt = FunctionDef(identifier name, typeparam* typeparams, arguments args,
                        stmt* body, expr* decorator_list, expr? returns,
                        string? type_comment)
-          | AsyncFunctionDef(identifier name, arguments args,
+          | AsyncFunctionDef(identifier name, typeparam* typeparams, arguments args,
                              stmt* body, expr* decorator_list, expr? returns,
                              string? type_comment)
 
           | ClassDef(identifier name,
+             typeparam* typeparams,
              expr* bases,
              keyword* keywords,
              stmt* body,
@@ -24,6 +25,7 @@ module Python
 
           | Delete(expr* targets)
           | Assign(expr* targets, expr value, string? type_comment)
+          | TypeAlias(expr name, typeparam* typeparams, expr value)
           | AugAssign(expr target, operator op, expr value)
           -- 'simple' indicates that we annotate simple name without parens
           | AnnAssign(expr target, expr annotation, expr? value, int simple)
@@ -142,4 +144,9 @@ module Python
              attributes (int lineno, int col_offset, int end_lineno, int end_col_offset)
 
     type_ignore = TypeIgnore(int lineno, string tag)
+
+    typeparam = TypeVar(identifier name, expr? bound)
+            | ParamSpec(identifier name)
+            | TypeVarTuple(identifier name)
+             attributes (int lineno, int col_offset, int? end_lineno, int? end_col_offset)
 }
diff --git a/Parser/action_helpers.c b/Parser/action_helpers.c
index 0aaaed64c403..0134e6f16ba8 100644
--- a/Parser/action_helpers.c
+++ b/Parser/action_helpers.c
@@ -752,7 +752,8 @@ _PyPegen_function_def_decorators(Parser *p, asdl_expr_seq *decorators, stmt_ty f
     assert(function_def != NULL);
     if (function_def->kind == AsyncFunctionDef_kind) {
         return _PyAST_AsyncFunctionDef(
-            function_def->v.FunctionDef.name, function_def->v.FunctionDef.args,
+            function_def->v.FunctionDef.name, function_def->v.FunctionDef.typeparams,
+            function_def->v.FunctionDef.args,
             function_def->v.FunctionDef.body, decorators, function_def->v.FunctionDef.returns,
             function_def->v.FunctionDef.type_comment, function_def->lineno,
             function_def->col_offset, function_def->end_lineno, function_def->end_col_offset,
@@ -760,7 +761,8 @@ _PyPegen_function_def_decorators(Parser *p, asdl_expr_seq *decorators, stmt_ty f
     }
 
     return _PyAST_FunctionDef(
-        function_def->v.FunctionDef.name, function_def->v.FunctionDef.args,
+        function_def->v.FunctionDef.name, function_def->v.FunctionDef.typeparams,
+        function_def->v.FunctionDef.args,
         function_def->v.FunctionDef.body, decorators,
         function_def->v.FunctionDef.returns,
         function_def->v.FunctionDef.type_comment, function_def->lineno,
@@ -774,8 +776,9 @@ _PyPegen_class_def_decorators(Parser *p, asdl_expr_seq *decorators, stmt_ty clas
 {
     assert(class_def != NULL);
     return _PyAST_ClassDef(
-        class_def->v.ClassDef.name, class_def->v.ClassDef.bases,
-        class_def->v.ClassDef.keywords, class_def->v.ClassDef.body, decorators,
+        class_def->v.ClassDef.name, class_def->v.ClassDef.typeparams,
+        class_def->v.ClassDef.bases, class_def->v.ClassDef.keywords,
+        class_def->v.ClassDef.body, decorators,
         class_def->lineno, class_def->col_offset, class_def->end_lineno,
         class_def->end_col_offset, p->arena);
 }
diff --git a/Parser/parser.c b/Parser/parser.c
index 6eb985a7d3e1..894846714eff 100644
--- a/Parser/parser.c
+++ b/Parser/parser.c
@@ -75,6 +75,7 @@ static char *soft_keywords[] = {
     "_",
     "case",
     "match",
+    "type",
     NULL,
 };
 #define file_type 1000
@@ -175,419 +176,426 @@ static char *soft_keywords[] = {
 #define positional_patterns_type 1095
 #define keyword_patterns_type 1096
 #define keyword_pattern_type 1097
-#define expressions_type 1098
-#define expression_type 1099
-#define yield_expr_type 1100
-#define star_expressions_type 1101
-#define star_expression_type 1102
-#define star_named_expressions_type 1103
-#define star_named_expression_type 1104
-#define assignment_expression_type 1105
-#define named_expression_type 1106
-#define disjunction_type 1107
-#define conjunction_type 1108
-#define inversion_type 1109
-#define comparison_type 1110
-#define compare_op_bitwise_or_pair_type 1111
-#define eq_bitwise_or_type 1112
-#define noteq_bitwise_or_type 1113
-#define lte_bitwise_or_type 1114
-#define lt_bitwise_or_type 1115
-#define gte_bitwise_or_type 1116
-#define gt_bitwise_or_type 1117
-#define notin_bitwise_or_type 1118
-#define in_bitwise_or_type 1119
-#define isnot_bitwise_or_type 1120
-#define is_bitwise_or_type 1121
-#define bitwise_or_type 1122  // Left-recursive
-#define bitwise_xor_type 1123  // Left-recursive
-#define bitwise_and_type 1124  // Left-recursive
-#define shift_expr_type 1125  // Left-recursive
-#define sum_type 1126  // Left-recursive
-#define term_type 1127  // Left-recursive
-#define factor_type 1128
-#define power_type 1129
-#define await_primary_type 1130
-#define primary_type 1131  // Left-recursive
-#define slices_type 1132
-#define slice_type 1133
-#define atom_type 1134
-#define group_type 1135
-#define lambdef_type 1136
-#define lambda_params_type 1137
-#define lambda_parameters_type 1138
-#define lambda_slash_no_default_type 1139
-#define lambda_slash_with_default_type 1140
-#define lambda_star_etc_type 1141
-#define lambda_kwds_type 1142
-#define lambda_param_no_default_type 1143
-#define lambda_param_with_default_type 1144
-#define lambda_param_maybe_default_type 1145
-#define lambda_param_type 1146
-#define fstring_middle_type 1147
-#define fstring_replacement_field_type 1148
-#define fstring_conversion_type 1149
-#define fstring_full_format_spec_type 1150
-#define fstring_format_spec_type 1151
-#define string_type 1152
-#define strings_type 1153
-#define list_type 1154
-#define tuple_type 1155
-#define set_type 1156
-#define dict_type 1157
-#define double_starred_kvpairs_type 1158
-#define double_starred_kvpair_type 1159
-#define kvpair_type 1160
-#define for_if_clauses_type 1161
-#define for_if_clause_type 1162
-#define listcomp_type 1163
-#define setcomp_type 1164
-#define genexp_type 1165
-#define dictcomp_type 1166
-#define arguments_type 1167
-#define args_type 1168
-#define kwargs_type 1169
-#define starred_expression_type 1170
-#define kwarg_or_starred_type 1171
-#define kwarg_or_double_starred_type 1172
-#define star_targets_type 1173
-#define star_targets_list_seq_type 1174
-#define star_targets_tuple_seq_type 1175
-#define star_target_type 1176
-#define target_with_star_atom_type 1177
-#define star_atom_type 1178
-#define single_target_type 1179
-#define single_subscript_attribute_target_type 1180
-#define t_primary_type 1181  // Left-recursive
-#define t_lookahead_type 1182
-#define del_targets_type 1183
-#define del_target_type 1184
-#define del_t_atom_type 1185
-#define type_expressions_type 1186
-#define func_type_comment_type 1187
-#define invalid_arguments_type 1188
-#define invalid_kwarg_type 1189
-#define expression_without_invalid_type 1190
-#define invalid_legacy_expression_type 1191
-#define invalid_expression_type 1192
-#define invalid_named_expression_type 1193
-#define invalid_assignment_type 1194
-#define invalid_ann_assign_target_type 1195
-#define invalid_del_stmt_type 1196
-#define invalid_block_type 1197
-#define invalid_comprehension_type 1198
-#define invalid_dict_comprehension_type 1199
-#define invalid_parameters_type 1200
-#define invalid_default_type 1201
-#define invalid_star_etc_type 1202
-#define invalid_kwds_type 1203
-#define invalid_parameters_helper_type 1204
-#define invalid_lambda_parameters_type 1205
-#define invalid_lambda_parameters_helper_type 1206
-#define invalid_lambda_star_etc_type 1207
-#define invalid_lambda_kwds_type 1208
-#define invalid_double_type_comments_type 1209
-#define invalid_with_item_type 1210
-#define invalid_for_target_type 1211
-#define invalid_group_type 1212
-#define invalid_import_type 1213
-#define invalid_import_from_targets_type 1214
-#define invalid_with_stmt_type 1215
-#define invalid_with_stmt_indent_type 1216
-#define invalid_try_stmt_type 1217
-#define invalid_except_stmt_type 1218
-#define invalid_finally_stmt_type 1219
-#define invalid_except_stmt_indent_type 1220
-#define invalid_except_star_stmt_indent_type 1221
-#define invalid_match_stmt_type 1222
-#define invalid_case_block_type 1223
-#define invalid_as_pattern_type 1224
-#define invalid_class_pattern_type 1225
-#define invalid_class_argument_pattern_type 1226
-#define invalid_if_stmt_type 1227
-#define invalid_elif_stmt_type 1228
-#define invalid_else_stmt_type 1229
-#define invalid_while_stmt_type 1230
-#define invalid_for_stmt_type 1231
-#define invalid_def_raw_type 1232
-#define invalid_class_def_raw_type 1233
-#define invalid_double_starred_kvpairs_type 1234
-#define invalid_kvpair_type 1235
-#define invalid_starred_expression_type 1236
-#define invalid_replacement_field_type 1237
-#define invalid_conversion_character_type 1238
-#define _loop0_1_type 1239
-#define _loop0_2_type 1240
-#define _loop0_3_type 1241
-#define _loop1_4_type 1242
-#define _loop0_6_type 1243
-#define _gather_5_type 1244
-#define _tmp_7_type 1245
-#define _tmp_8_type 1246
-#define _tmp_9_type 1247
-#define _tmp_10_type 1248
-#define _tmp_11_type 1249
-#define _tmp_12_type 1250
-#define _tmp_13_type 1251
-#define _tmp_14_type 1252
-#define _loop1_15_type 1253
-#define _tmp_16_type 1254
-#define _tmp_17_type 1255
-#define _tmp_18_type 1256
-#define _loop0_20_type 1257
-#define _gather_19_type 1258
-#define _loop0_22_type 1259
-#define _gather_21_type 1260
-#define _tmp_23_type 1261
-#define _tmp_24_type 1262
-#define _loop0_25_type 1263
-#define _loop1_26_type 1264
-#define _loop0_28_type 1265
-#define _gather_27_type 1266
-#define _tmp_29_type 1267
-#define _loop0_31_type 1268
-#define _gather_30_type 1269
-#define _tmp_32_type 1270
-#define _loop1_33_type 1271
-#define _tmp_34_type 1272
-#define _tmp_35_type 1273
-#define _tmp_36_type 1274
-#define _loop0_37_type 1275
-#define _loop0_38_type 1276
-#define _loop0_39_type 1277
-#define _loop1_40_type 1278
-#define _loop0_41_type 1279
-#define _loop1_42_type 1280
-#define _loop1_43_type 1281
-#define _loop1_44_type 1282
-#define _loop0_45_type 1283
-#define _loop1_46_type 1284
-#define _loop0_47_type 1285
-#define _loop1_48_type 1286
-#define _loop0_49_type 1287
-#define _loop0_50_type 1288
-#define _loop1_51_type 1289
-#define _loop0_53_type 1290
-#define _gather_52_type 1291
-#define _loop0_55_type 1292
-#define _gather_54_type 1293
-#define _loop0_57_type 1294
-#define _gather_56_type 1295
-#define _loop0_59_type 1296
-#define _gather_58_type 1297
-#define _tmp_60_type 1298
-#define _loop1_61_type 1299
-#define _loop1_62_type 1300
-#define _tmp_63_type 1301
-#define _tmp_64_type 1302
-#define _loop1_65_type 1303
-#define _loop0_67_type 1304
-#define _gather_66_type 1305
-#define _tmp_68_type 1306
-#define _tmp_69_type 1307
-#define _tmp_70_type 1308
-#define _tmp_71_type 1309
-#define _loop0_73_type 1310
-#define _gather_72_type 1311
-#define _loop0_75_type 1312
-#define _gather_74_type 1313
-#define _tmp_76_type 1314
-#define _loop0_78_type 1315
-#define _gather_77_type 1316
-#define _loop0_80_type 1317
-#define _gather_79_type 1318
-#define _loop1_81_type 1319
-#define _loop1_82_type 1320
-#define _loop0_84_type 1321
-#define _gather_83_type 1322
-#define _loop1_85_type 1323
-#define _loop1_86_type 1324
-#define _loop1_87_type 1325
-#define _tmp_88_type 1326
-#define _loop0_90_type 1327
-#define _gather_89_type 1328
-#define _tmp_91_type 1329
-#define _tmp_92_type 1330
-#define _tmp_93_type 1331
-#define _tmp_94_type 1332
-#define _tmp_95_type 1333
-#define _tmp_96_type 1334
-#define _loop0_97_type 1335
-#define _loop0_98_type 1336
-#define _loop0_99_type 1337
-#define _loop1_100_type 1338
-#define _loop0_101_type 1339
-#define _loop1_102_type 1340
-#define _loop1_103_type 1341
-#define _loop1_104_type 1342
-#define _loop0_105_type 1343
-#define _loop1_106_type 1344
-#define _loop0_107_type 1345
-#define _loop1_108_type 1346
-#define _loop0_109_type 1347
-#define _loop1_110_type 1348
-#define _tmp_111_type 1349
-#define _loop0_112_type 1350
-#define _loop1_113_type 1351
-#define _tmp_114_type 1352
-#define _loop0_116_type 1353
-#define _gather_115_type 1354
-#define _loop1_117_type 1355
-#define _loop0_118_type 1356
-#define _loop0_119_type 1357
-#define _tmp_120_type 1358
-#define _loop0_122_type 1359
-#define _gather_121_type 1360
-#define _tmp_123_type 1361
-#define _loop0_125_type 1362
-#define _gather_124_type 1363
-#define _loop0_127_type 1364
-#define _gather_126_type 1365
-#define _loop0_129_type 1366
-#define _gather_128_type 1367
-#define _loop0_131_type 1368
-#define _gather_130_type 1369
-#define _loop0_132_type 1370
-#define _loop0_134_type 1371
-#define _gather_133_type 1372
-#define _loop1_135_type 1373
-#define _tmp_136_type 1374
-#define _loop0_138_type 1375
-#define _gather_137_type 1376
-#define _loop0_140_type 1377
-#define _gather_139_type 1378
-#define _loop0_142_type 1379
-#define _gather_141_type 1380
-#define _loop0_144_type 1381
-#define _gather_143_type 1382
-#define _loop0_146_type 1383
-#define _gather_145_type 1384
-#define _tmp_147_type 1385
-#define _tmp_148_type 1386
-#define _tmp_149_type 1387
-#define _tmp_150_type 1388
-#define _tmp_151_type 1389
-#define _tmp_152_type 1390
-#define _tmp_153_type 1391
-#define _tmp_154_type 1392
-#define _tmp_155_type 1393
-#define _tmp_156_type 1394
-#define _tmp_157_type 1395
-#define _tmp_158_type 1396
-#define _loop0_159_type 1397
-#define _loop0_160_type 1398
-#define _loop0_161_type 1399
-#define _tmp_162_type 1400
-#define _tmp_163_type 1401
-#define _tmp_164_type 1402
-#define _tmp_165_type 1403
-#define _tmp_166_type 1404
-#define _loop0_167_type 1405
-#define _loop0_168_type 1406
-#define _loop0_169_type 1407
-#define _loop1_170_type 1408
-#define _tmp_171_type 1409
-#define _loop0_172_type 1410
-#define _tmp_173_type 1411
-#define _loop0_174_type 1412
-#define _loop1_175_type 1413
-#define _tmp_176_type 1414
-#define _tmp_177_type 1415
-#define _tmp_178_type 1416
-#define _loop0_179_type 1417
-#define _tmp_180_type 1418
-#define _tmp_181_type 1419
-#define _loop1_182_type 1420
-#define _tmp_183_type 1421
-#define _loop0_184_type 1422
-#define _loop0_185_type 1423
-#define _loop0_186_type 1424
-#define _loop0_188_type 1425
-#define _gather_187_type 1426
-#define _tmp_189_type 1427
-#define _loop0_190_type 1428
-#define _tmp_191_type 1429
-#define _loop0_192_type 1430
-#define _loop1_193_type 1431
-#define _loop1_194_type 1432
-#define _tmp_195_type 1433
-#define _tmp_196_type 1434
-#define _loop0_197_type 1435
-#define _tmp_198_type 1436
-#define _tmp_199_type 1437
-#define _tmp_200_type 1438
-#define _loop0_202_type 1439
-#define _gather_201_type 1440
-#define _loop0_204_type 1441
-#define _gather_203_type 1442
-#define _loop0_206_type 1443
-#define _gather_205_type 1444
-#define _loop0_208_type 1445
-#define _gather_207_type 1446
-#define _tmp_209_type 1447
-#define _loop0_210_type 1448
-#define _loop1_211_type 1449
-#define _tmp_212_type 1450
-#define _loop0_213_type 1451
-#define _loop1_214_type 1452
-#define _tmp_215_type 1453
-#define _tmp_216_type 1454
-#define _tmp_217_type 1455
-#define _tmp_218_type 1456
-#define _tmp_219_type 1457
-#define _tmp_220_type 1458
-#define _tmp_221_type 1459
-#define _tmp_222_type 1460
-#define _tmp_223_type 1461
-#define _tmp_224_type 1462
-#define _loop0_226_type 1463
-#define _gather_225_type 1464
-#define _tmp_227_type 1465
-#define _tmp_228_type 1466
-#define _tmp_229_type 1467
-#define _tmp_230_type 1468
-#define _tmp_231_type 1469
-#define _tmp_232_type 1470
-#define _tmp_233_type 1471
-#define _tmp_234_type 1472
-#define _tmp_235_type 1473
-#define _tmp_236_type 1474
-#define _tmp_237_type 1475
-#define _tmp_238_type 1476
-#define _tmp_239_type 1477
-#define _loop0_240_type 1478
-#define _tmp_241_type 1479
-#define _tmp_242_type 1480
-#define _tmp_243_type 1481
-#define _tmp_244_type 1482
-#define _tmp_245_type 1483
-#define _tmp_246_type 1484
-#define _tmp_247_type 1485
-#define _tmp_248_type 1486
-#define _tmp_249_type 1487
-#define _tmp_250_type 1488
-#define _tmp_251_type 1489
-#define _tmp_252_type 1490
-#define _tmp_253_type 1491
-#define _tmp_254_type 1492
-#define _tmp_255_type 1493
-#define _tmp_256_type 1494
-#define _tmp_257_type 1495
-#define _tmp_258_type 1496
-#define _tmp_259_type 1497
-#define _tmp_260_type 1498
-#define _tmp_261_type 1499
-#define _tmp_262_type 1500
-#define _tmp_263_type 1501
-#define _tmp_264_type 1502
-#define _tmp_265_type 1503
-#define _tmp_266_type 1504
-#define _tmp_267_type 1505
-#define _tmp_268_type 1506
-#define _tmp_269_type 1507
-#define _tmp_270_type 1508
-#define _tmp_271_type 1509
-#define _tmp_272_type 1510
+#define type_alias_type 1098
+#define type_params_type 1099
+#define type_param_seq_type 1100
+#define type_param_type 1101
+#define type_param_bound_type 1102
+#define expressions_type 1103
+#define expression_type 1104
+#define yield_expr_type 1105
+#define star_expressions_type 1106
+#define star_expression_type 1107
+#define star_named_expressions_type 1108
+#define star_named_expression_type 1109
+#define assignment_expression_type 1110
+#define named_expression_type 1111
+#define disjunction_type 1112
+#define conjunction_type 1113
+#define inversion_type 1114
+#define comparison_type 1115
+#define compare_op_bitwise_or_pair_type 1116
+#define eq_bitwise_or_type 1117
+#define noteq_bitwise_or_type 1118
+#define lte_bitwise_or_type 1119
+#define lt_bitwise_or_type 1120
+#define gte_bitwise_or_type 1121
+#define gt_bitwise_or_type 1122
+#define notin_bitwise_or_type 1123
+#define in_bitwise_or_type 1124
+#define isnot_bitwise_or_type 1125
+#define is_bitwise_or_type 1126
+#define bitwise_or_type 1127  // Left-recursive
+#define bitwise_xor_type 1128  // Left-recursive
+#define bitwise_and_type 1129  // Left-recursive
+#define shift_expr_type 1130  // Left-recursive
+#define sum_type 1131  // Left-recursive
+#define term_type 1132  // Left-recursive
+#define factor_type 1133
+#define power_type 1134
+#define await_primary_type 1135
+#define primary_type 1136  // Left-recursive
+#define slices_type 1137
+#define slice_type 1138
+#define atom_type 1139
+#define group_type 1140
+#define lambdef_type 1141
+#define lambda_params_type 1142
+#define lambda_parameters_type 1143
+#define lambda_slash_no_default_type 1144
+#define lambda_slash_with_default_type 1145
+#define lambda_star_etc_type 1146
+#define lambda_kwds_type 1147
+#define lambda_param_no_default_type 1148
+#define lambda_param_with_default_type 1149
+#define lambda_param_maybe_default_type 1150
+#define lambda_param_type 1151
+#define fstring_middle_type 1152
+#define fstring_replacement_field_type 1153
+#define fstring_conversion_type 1154
+#define fstring_full_format_spec_type 1155
+#define fstring_format_spec_type 1156
+#define string_type 1157
+#define strings_type 1158
+#define list_type 1159
+#define tuple_type 1160
+#define set_type 1161
+#define dict_type 1162
+#define double_starred_kvpairs_type 1163
+#define double_starred_kvpair_type 1164
+#define kvpair_type 1165
+#define for_if_clauses_type 1166
+#define for_if_clause_type 1167
+#define listcomp_type 1168
+#define setcomp_type 1169
+#define genexp_type 1170
+#define dictcomp_type 1171
+#define arguments_type 1172
+#define args_type 1173
+#define kwargs_type 1174
+#define starred_expression_type 1175
+#define kwarg_or_starred_type 1176
+#define kwarg_or_double_starred_type 1177
+#define star_targets_type 1178
+#define star_targets_list_seq_type 1179
+#define star_targets_tuple_seq_type 1180
+#define star_target_type 1181
+#define target_with_star_atom_type 1182
+#define star_atom_type 1183
+#define single_target_type 1184
+#define single_subscript_attribute_target_type 1185
+#define t_primary_type 1186  // Left-recursive
+#define t_lookahead_type 1187
+#define del_targets_type 1188
+#define del_target_type 1189
+#define del_t_atom_type 1190
+#define type_expressions_type 1191
+#define func_type_comment_type 1192
+#define invalid_arguments_type 1193
+#define invalid_kwarg_type 1194
+#define expression_without_invalid_type 1195
+#define invalid_legacy_expression_type 1196
+#define invalid_expression_type 1197
+#define invalid_named_expression_type 1198
+#define invalid_assignment_type 1199
+#define invalid_ann_assign_target_type 1200
+#define invalid_del_stmt_type 1201
+#define invalid_block_type 1202
+#define invalid_comprehension_type 1203
+#define invalid_dict_comprehension_type 1204
+#define invalid_parameters_type 1205
+#define invalid_default_type 1206
+#define invalid_star_etc_type 1207
+#define invalid_kwds_type 1208
+#define invalid_parameters_helper_type 1209
+#define invalid_lambda_parameters_type 1210
+#define invalid_lambda_parameters_helper_type 1211
+#define invalid_lambda_star_etc_type 1212
+#define invalid_lambda_kwds_type 1213
+#define invalid_double_type_comments_type 1214
+#define invalid_with_item_type 1215
+#define invalid_for_target_type 1216
+#define invalid_group_type 1217
+#define invalid_import_type 1218
+#define invalid_import_from_targets_type 1219
+#define invalid_with_stmt_type 1220
+#define invalid_with_stmt_indent_type 1221
+#define invalid_try_stmt_type 1222
+#define invalid_except_stmt_type 1223
+#define invalid_finally_stmt_type 1224
+#define invalid_except_stmt_indent_type 1225
+#define invalid_except_star_stmt_indent_type 1226
+#define invalid_match_stmt_type 1227
+#define invalid_case_block_type 1228
+#define invalid_as_pattern_type 1229
+#define invalid_class_pattern_type 1230
+#define invalid_class_argument_pattern_type 1231
+#define invalid_if_stmt_type 1232
+#define invalid_elif_stmt_type 1233
+#define invalid_else_stmt_type 1234
+#define invalid_while_stmt_type 1235
+#define invalid_for_stmt_type 1236
+#define invalid_def_raw_type 1237
+#define invalid_class_def_raw_type 1238
+#define invalid_double_starred_kvpairs_type 1239
+#define invalid_kvpair_type 1240
+#define invalid_starred_expression_type 1241
+#define invalid_replacement_field_type 1242
+#define invalid_conversion_character_type 1243
+#define _loop0_1_type 1244
+#define _loop0_2_type 1245
+#define _loop0_3_type 1246
+#define _loop1_4_type 1247
+#define _loop0_6_type 1248
+#define _gather_5_type 1249
+#define _tmp_7_type 1250
+#define _tmp_8_type 1251
+#define _tmp_9_type 1252
+#define _tmp_10_type 1253
+#define _tmp_11_type 1254
+#define _tmp_12_type 1255
+#define _tmp_13_type 1256
+#define _tmp_14_type 1257
+#define _loop1_15_type 1258
+#define _tmp_16_type 1259
+#define _tmp_17_type 1260
+#define _tmp_18_type 1261
+#define _loop0_20_type 1262
+#define _gather_19_type 1263
+#define _loop0_22_type 1264
+#define _gather_21_type 1265
+#define _tmp_23_type 1266
+#define _tmp_24_type 1267
+#define _loop0_25_type 1268
+#define _loop1_26_type 1269
+#define _loop0_28_type 1270
+#define _gather_27_type 1271
+#define _tmp_29_type 1272
+#define _loop0_31_type 1273
+#define _gather_30_type 1274
+#define _tmp_32_type 1275
+#define _loop1_33_type 1276
+#define _tmp_34_type 1277
+#define _tmp_35_type 1278
+#define _tmp_36_type 1279
+#define _loop0_37_type 1280
+#define _loop0_38_type 1281
+#define _loop0_39_type 1282
+#define _loop1_40_type 1283
+#define _loop0_41_type 1284
+#define _loop1_42_type 1285
+#define _loop1_43_type 1286
+#define _loop1_44_type 1287
+#define _loop0_45_type 1288
+#define _loop1_46_type 1289
+#define _loop0_47_type 1290
+#define _loop1_48_type 1291
+#define _loop0_49_type 1292
+#define _loop0_50_type 1293
+#define _loop1_51_type 1294
+#define _loop0_53_type 1295
+#define _gather_52_type 1296
+#define _loop0_55_type 1297
+#define _gather_54_type 1298
+#define _loop0_57_type 1299
+#define _gather_56_type 1300
+#define _loop0_59_type 1301
+#define _gather_58_type 1302
+#define _tmp_60_type 1303
+#define _loop1_61_type 1304
+#define _loop1_62_type 1305
+#define _tmp_63_type 1306
+#define _tmp_64_type 1307
+#define _loop1_65_type 1308
+#define _loop0_67_type 1309
+#define _gather_66_type 1310
+#define _tmp_68_type 1311
+#define _tmp_69_type 1312
+#define _tmp_70_type 1313
+#define _tmp_71_type 1314
+#define _loop0_73_type 1315
+#define _gather_72_type 1316
+#define _loop0_75_type 1317
+#define _gather_74_type 1318
+#define _tmp_76_type 1319
+#define _loop0_78_type 1320
+#define _gather_77_type 1321
+#define _loop0_80_type 1322
+#define _gather_79_type 1323
+#define _loop0_82_type 1324
+#define _gather_81_type 1325
+#define _loop1_83_type 1326
+#define _loop1_84_type 1327
+#define _loop0_86_type 1328
+#define _gather_85_type 1329
+#define _loop1_87_type 1330
+#define _loop1_88_type 1331
+#define _loop1_89_type 1332
+#define _tmp_90_type 1333
+#define _loop0_92_type 1334
+#define _gather_91_type 1335
+#define _tmp_93_type 1336
+#define _tmp_94_type 1337
+#define _tmp_95_type 1338
+#define _tmp_96_type 1339
+#define _tmp_97_type 1340
+#define _tmp_98_type 1341
+#define _loop0_99_type 1342
+#define _loop0_100_type 1343
+#define _loop0_101_type 1344
+#define _loop1_102_type 1345
+#define _loop0_103_type 1346
+#define _loop1_104_type 1347
+#define _loop1_105_type 1348
+#define _loop1_106_type 1349
+#define _loop0_107_type 1350
+#define _loop1_108_type 1351
+#define _loop0_109_type 1352
+#define _loop1_110_type 1353
+#define _loop0_111_type 1354
+#define _loop1_112_type 1355
+#define _tmp_113_type 1356
+#define _loop0_114_type 1357
+#define _loop1_115_type 1358
+#define _tmp_116_type 1359
+#define _loop0_118_type 1360
+#define _gather_117_type 1361
+#define _loop1_119_type 1362
+#define _loop0_120_type 1363
+#define _loop0_121_type 1364
+#define _tmp_122_type 1365
+#define _loop0_124_type 1366
+#define _gather_123_type 1367
+#define _tmp_125_type 1368
+#define _loop0_127_type 1369
+#define _gather_126_type 1370
+#define _loop0_129_type 1371
+#define _gather_128_type 1372
+#define _loop0_131_type 1373
+#define _gather_130_type 1374
+#define _loop0_133_type 1375
+#define _gather_132_type 1376
+#define _loop0_134_type 1377
+#define _loop0_136_type 1378
+#define _gather_135_type 1379
+#define _loop1_137_type 1380
+#define _tmp_138_type 1381
+#define _loop0_140_type 1382
+#define _gather_139_type 1383
+#define _loop0_142_type 1384
+#define _gather_141_type 1385
+#define _loop0_144_type 1386
+#define _gather_143_type 1387
+#define _loop0_146_type 1388
+#define _gather_145_type 1389
+#define _loop0_148_type 1390
+#define _gather_147_type 1391
+#define _tmp_149_type 1392
+#define _tmp_150_type 1393
+#define _tmp_151_type 1394
+#define _tmp_152_type 1395
+#define _tmp_153_type 1396
+#define _tmp_154_type 1397
+#define _tmp_155_type 1398
+#define _tmp_156_type 1399
+#define _tmp_157_type 1400
+#define _tmp_158_type 1401
+#define _tmp_159_type 1402
+#define _tmp_160_type 1403
+#define _loop0_161_type 1404
+#define _loop0_162_type 1405
+#define _loop0_163_type 1406
+#define _tmp_164_type 1407
+#define _tmp_165_type 1408
+#define _tmp_166_type 1409
+#define _tmp_167_type 1410
+#define _tmp_168_type 1411
+#define _loop0_169_type 1412
+#define _loop0_170_type 1413
+#define _loop0_171_type 1414
+#define _loop1_172_type 1415
+#define _tmp_173_type 1416
+#define _loop0_174_type 1417
+#define _tmp_175_type 1418
+#define _loop0_176_type 1419
+#define _loop1_177_type 1420
+#define _tmp_178_type 1421
+#define _tmp_179_type 1422
+#define _tmp_180_type 1423
+#define _loop0_181_type 1424
+#define _tmp_182_type 1425
+#define _tmp_183_type 1426
+#define _loop1_184_type 1427
+#define _tmp_185_type 1428
+#define _loop0_186_type 1429
+#define _loop0_187_type 1430
+#define _loop0_188_type 1431
+#define _loop0_190_type 1432
+#define _gather_189_type 1433
+#define _tmp_191_type 1434
+#define _loop0_192_type 1435
+#define _tmp_193_type 1436
+#define _loop0_194_type 1437
+#define _loop1_195_type 1438
+#define _loop1_196_type 1439
+#define _tmp_197_type 1440
+#define _tmp_198_type 1441
+#define _loop0_199_type 1442
+#define _tmp_200_type 1443
+#define _tmp_201_type 1444
+#define _tmp_202_type 1445
+#define _loop0_204_type 1446
+#define _gather_203_type 1447
+#define _loop0_206_type 1448
+#define _gather_205_type 1449
+#define _loop0_208_type 1450
+#define _gather_207_type 1451
+#define _loop0_210_type 1452
+#define _gather_209_type 1453
+#define _tmp_211_type 1454
+#define _loop0_212_type 1455
+#define _loop1_213_type 1456
+#define _tmp_214_type 1457
+#define _loop0_215_type 1458
+#define _loop1_216_type 1459
+#define _tmp_217_type 1460
+#define _tmp_218_type 1461
+#define _tmp_219_type 1462
+#define _tmp_220_type 1463
+#define _tmp_221_type 1464
+#define _tmp_222_type 1465
+#define _tmp_223_type 1466
+#define _tmp_224_type 1467
+#define _tmp_225_type 1468
+#define _tmp_226_type 1469
+#define _loop0_228_type 1470
+#define _gather_227_type 1471
+#define _tmp_229_type 1472
+#define _tmp_230_type 1473
+#define _tmp_231_type 1474
+#define _tmp_232_type 1475
+#define _tmp_233_type 1476
+#define _tmp_234_type 1477
+#define _tmp_235_type 1478
+#define _tmp_236_type 1479
+#define _tmp_237_type 1480
+#define _tmp_238_type 1481
+#define _tmp_239_type 1482
+#define _tmp_240_type 1483
+#define _tmp_241_type 1484
+#define _loop0_242_type 1485
+#define _tmp_243_type 1486
+#define _tmp_244_type 1487
+#define _tmp_245_type 1488
+#define _tmp_246_type 1489
+#define _tmp_247_type 1490
+#define _tmp_248_type 1491
+#define _tmp_249_type 1492
+#define _tmp_250_type 1493
+#define _tmp_251_type 1494
+#define _tmp_252_type 1495
+#define _tmp_253_type 1496
+#define _tmp_254_type 1497
+#define _tmp_255_type 1498
+#define _tmp_256_type 1499
+#define _tmp_257_type 1500
+#define _tmp_258_type 1501
+#define _tmp_259_type 1502
+#define _tmp_260_type 1503
+#define _tmp_261_type 1504
+#define _tmp_262_type 1505
+#define _tmp_263_type 1506
+#define _tmp_264_type 1507
+#define _tmp_265_type 1508
+#define _tmp_266_type 1509
+#define _tmp_267_type 1510
+#define _tmp_268_type 1511
+#define _tmp_269_type 1512
+#define _tmp_270_type 1513
+#define _tmp_271_type 1514
+#define _tmp_272_type 1515
+#define _tmp_273_type 1516
+#define _tmp_274_type 1517
 
 static mod_ty file_rule(Parser *p);
 static mod_ty interactive_rule(Parser *p);
@@ -687,6 +695,11 @@ static pattern_ty class_pattern_rule(Parser *p);
 static asdl_pattern_seq* positional_patterns_rule(Parser *p);
 static asdl_seq* keyword_patterns_rule(Parser *p);
 static KeyPatternPair* keyword_pattern_rule(Parser *p);
+static stmt_ty type_alias_rule(Parser *p);
+static asdl_typeparam_seq* type_params_rule(Parser *p);
+static asdl_typeparam_seq* type_param_seq_rule(Parser *p);
+static typeparam_ty type_param_rule(Parser *p);
+static expr_ty type_param_bound_rule(Parser *p);
 static expr_ty expressions_rule(Parser *p);
 static expr_ty expression_rule(Parser *p);
 static expr_ty yield_expr_rule(Parser *p);
@@ -908,64 +921,64 @@ static asdl_seq *_loop0_78_rule(Parser *p);
 static asdl_seq *_gather_77_rule(Parser *p);
 static asdl_seq *_loop0_80_rule(Parser *p);
 static asdl_seq *_gather_79_rule(Parser *p);
-static asdl_seq *_loop1_81_rule(Parser *p);
-static asdl_seq *_loop1_82_rule(Parser *p);
-static asdl_seq *_loop0_84_rule(Parser *p);
-static asdl_seq *_gather_83_rule(Parser *p);
-static asdl_seq *_loop1_85_rule(Parser *p);
-static asdl_seq *_loop1_86_rule(Parser *p);
+static asdl_seq *_loop0_82_rule(Parser *p);
+static asdl_seq *_gather_81_rule(Parser *p);
+static asdl_seq *_loop1_83_rule(Parser *p);
+static asdl_seq *_loop1_84_rule(Parser *p);
+static asdl_seq *_loop0_86_rule(Parser *p);
+static asdl_seq *_gather_85_rule(Parser *p);
 static asdl_seq *_loop1_87_rule(Parser *p);
-static void *_tmp_88_rule(Parser *p);
-static asdl_seq *_loop0_90_rule(Parser *p);
-static asdl_seq *_gather_89_rule(Parser *p);
-static void *_tmp_91_rule(Parser *p);
-static void *_tmp_92_rule(Parser *p);
+static asdl_seq *_loop1_88_rule(Parser *p);
+static asdl_seq *_loop1_89_rule(Parser *p);
+static void *_tmp_90_rule(Parser *p);
+static asdl_seq *_loop0_92_rule(Parser *p);
+static asdl_seq *_gather_91_rule(Parser *p);
 static void *_tmp_93_rule(Parser *p);
 static void *_tmp_94_rule(Parser *p);
 static void *_tmp_95_rule(Parser *p);
 static void *_tmp_96_rule(Parser *p);
-static asdl_seq *_loop0_97_rule(Parser *p);
-static asdl_seq *_loop0_98_rule(Parser *p);
+static void *_tmp_97_rule(Parser *p);
+static void *_tmp_98_rule(Parser *p);
 static asdl_seq *_loop0_99_rule(Parser *p);
-static asdl_seq *_loop1_100_rule(Parser *p);
+static asdl_seq *_loop0_100_rule(Parser *p);
 static asdl_seq *_loop0_101_rule(Parser *p);
 static asdl_seq *_loop1_102_rule(Parser *p);
-static asdl_seq *_loop1_103_rule(Parser *p);
+static asdl_seq *_loop0_103_rule(Parser *p);
 static asdl_seq *_loop1_104_rule(Parser *p);
-static asdl_seq *_loop0_105_rule(Parser *p);
+static asdl_seq *_loop1_105_rule(Parser *p);
 static asdl_seq *_loop1_106_rule(Parser *p);
 static asdl_seq *_loop0_107_rule(Parser *p);
 static asdl_seq *_loop1_108_rule(Parser *p);
 static asdl_seq *_loop0_109_rule(Parser *p);
 static asdl_seq *_loop1_110_rule(Parser *p);
-static void *_tmp_111_rule(Parser *p);
-static asdl_seq *_loop0_112_rule(Parser *p);
-static asdl_seq *_loop1_113_rule(Parser *p);
-static void *_tmp_114_rule(Parser *p);
-static asdl_seq *_loop0_116_rule(Parser *p);
-static asdl_seq *_gather_115_rule(Parser *p);
-static asdl_seq *_loop1_117_rule(Parser *p);
+static asdl_seq *_loop0_111_rule(Parser *p);
+static asdl_seq *_loop1_112_rule(Parser *p);
+static void *_tmp_113_rule(Parser *p);
+static asdl_seq *_loop0_114_rule(Parser *p);
+static asdl_seq *_loop1_115_rule(Parser *p);
+static void *_tmp_116_rule(Parser *p);
 static asdl_seq *_loop0_118_rule(Parser *p);
-static asdl_seq *_loop0_119_rule(Parser *p);
-static void *_tmp_120_rule(Parser *p);
-static asdl_seq *_loop0_122_rule(Parser *p);
-static asdl_seq *_gather_121_rule(Parser *p);
-static void *_tmp_123_rule(Parser *p);
-static asdl_seq *_loop0_125_rule(Parser *p);
-static asdl_seq *_gather_124_rule(Parser *p);
+static asdl_seq *_gather_117_rule(Parser *p);
+static asdl_seq *_loop1_119_rule(Parser *p);
+static asdl_seq *_loop0_120_rule(Parser *p);
+static asdl_seq *_loop0_121_rule(Parser *p);
+static void *_tmp_122_rule(Parser *p);
+static asdl_seq *_loop0_124_rule(Parser *p);
+static asdl_seq *_gather_123_rule(Parser *p);
+static void *_tmp_125_rule(Parser *p);
 static asdl_seq *_loop0_127_rule(Parser *p);
 static asdl_seq *_gather_126_rule(Parser *p);
 static asdl_seq *_loop0_129_rule(Parser *p);
 static asdl_seq *_gather_128_rule(Parser *p);
 static asdl_seq *_loop0_131_rule(Parser *p);
 static asdl_seq *_gather_130_rule(Parser *p);
-static asdl_seq *_loop0_132_rule(Parser *p);
+static asdl_seq *_loop0_133_rule(Parser *p);
+static asdl_seq *_gather_132_rule(Parser *p);
 static asdl_seq *_loop0_134_rule(Parser *p);
-static asdl_seq *_gather_133_rule(Parser *p);
-static asdl_seq *_loop1_135_rule(Parser *p);
-static void *_tmp_136_rule(Parser *p);
-static asdl_seq *_loop0_138_rule(Parser *p);
-static asdl_seq *_gather_137_rule(Parser *p);
+static asdl_seq *_loop0_136_rule(Parser *p);
+static asdl_seq *_gather_135_rule(Parser *p);
+static asdl_seq *_loop1_137_rule(Parser *p);
+static void *_tmp_138_rule(Parser *p);
 static asdl_seq *_loop0_140_rule(Parser *p);
 static asdl_seq *_gather_139_rule(Parser *p);
 static asdl_seq *_loop0_142_rule(Parser *p);
@@ -974,8 +987,8 @@ static asdl_seq *_loop0_144_rule(Parser *p);
 static asdl_seq *_gather_143_rule(Parser *p);
 static asdl_seq *_loop0_146_rule(Parser *p);
 static asdl_seq *_gather_145_rule(Parser *p);
-static void *_tmp_147_rule(Parser *p);
-static void *_tmp_148_rule(Parser *p);
+static asdl_seq *_loop0_148_rule(Parser *p);
+static asdl_seq *_gather_147_rule(Parser *p);
 static void *_tmp_149_rule(Parser *p);
 static void *_tmp_150_rule(Parser *p);
 static void *_tmp_151_rule(Parser *p);
@@ -986,64 +999,64 @@ static void *_tmp_155_rule(Parser *p);
 static void *_tmp_156_rule(Parser *p);
 static void *_tmp_157_rule(Parser *p);
 static void *_tmp_158_rule(Parser *p);
-static asdl_seq *_loop0_159_rule(Parser *p);
-static asdl_seq *_loop0_160_rule(Parser *p);
+static void *_tmp_159_rule(Parser *p);
+static void *_tmp_160_rule(Parser *p);
 static asdl_seq *_loop0_161_rule(Parser *p);
-static void *_tmp_162_rule(Parser *p);
-static void *_tmp_163_rule(Parser *p);
+static asdl_seq *_loop0_162_rule(Parser *p);
+static asdl_seq *_loop0_163_rule(Parser *p);
 static void *_tmp_164_rule(Parser *p);
 static void *_tmp_165_rule(Parser *p);
 static void *_tmp_166_rule(Parser *p);
-static asdl_seq *_loop0_167_rule(Parser *p);
-static asdl_seq *_loop0_168_rule(Parser *p);
+static void *_tmp_167_rule(Parser *p);
+static void *_tmp_168_rule(Parser *p);
 static asdl_seq *_loop0_169_rule(Parser *p);
-static asdl_seq *_loop1_170_rule(Parser *p);
-static void *_tmp_171_rule(Parser *p);
-static asdl_seq *_loop0_172_rule(Parser *p);
+static asdl_seq *_loop0_170_rule(Parser *p);
+static asdl_seq *_loop0_171_rule(Parser *p);
+static asdl_seq *_loop1_172_rule(Parser *p);
 static void *_tmp_173_rule(Parser *p);
 static asdl_seq *_loop0_174_rule(Parser *p);
-static asdl_seq *_loop1_175_rule(Parser *p);
-static void *_tmp_176_rule(Parser *p);
-static void *_tmp_177_rule(Parser *p);
+static void *_tmp_175_rule(Parser *p);
+static asdl_seq *_loop0_176_rule(Parser *p);
+static asdl_seq *_loop1_177_rule(Parser *p);
 static void *_tmp_178_rule(Parser *p);
-static asdl_seq *_loop0_179_rule(Parser *p);
+static void *_tmp_179_rule(Parser *p);
 static void *_tmp_180_rule(Parser *p);
-static void *_tmp_181_rule(Parser *p);
-static asdl_seq *_loop1_182_rule(Parser *p);
+static asdl_seq *_loop0_181_rule(Parser *p);
+static void *_tmp_182_rule(Parser *p);
 static void *_tmp_183_rule(Parser *p);
-static asdl_seq *_loop0_184_rule(Parser *p);
-static asdl_seq *_loop0_185_rule(Parser *p);
+static asdl_seq *_loop1_184_rule(Parser *p);
+static void *_tmp_185_rule(Parser *p);
 static asdl_seq *_loop0_186_rule(Parser *p);
+static asdl_seq *_loop0_187_rule(Parser *p);
 static asdl_seq *_loop0_188_rule(Parser *p);
-static asdl_seq *_gather_187_rule(Parser *p);
-static void *_tmp_189_rule(Parser *p);
 static asdl_seq *_loop0_190_rule(Parser *p);
+static asdl_seq *_gather_189_rule(Parser *p);
 static void *_tmp_191_rule(Parser *p);
 static asdl_seq *_loop0_192_rule(Parser *p);
-static asdl_seq *_loop1_193_rule(Parser *p);
-static asdl_seq *_loop1_194_rule(Parser *p);
-static void *_tmp_195_rule(Parser *p);
-static void *_tmp_196_rule(Parser *p);
-static asdl_seq *_loop0_197_rule(Parser *p);
+static void *_tmp_193_rule(Parser *p);
+static asdl_seq *_loop0_194_rule(Parser *p);
+static asdl_seq *_loop1_195_rule(Parser *p);
+static asdl_seq *_loop1_196_rule(Parser *p);
+static void *_tmp_197_rule(Parser *p);
 static void *_tmp_198_rule(Parser *p);
-static void *_tmp_199_rule(Parser *p);
+static asdl_seq *_loop0_199_rule(Parser *p);
 static void *_tmp_200_rule(Parser *p);
-static asdl_seq *_loop0_202_rule(Parser *p);
-static asdl_seq *_gather_201_rule(Parser *p);
+static void *_tmp_201_rule(Parser *p);
+static void *_tmp_202_rule(Parser *p);
 static asdl_seq *_loop0_204_rule(Parser *p);
 static asdl_seq *_gather_203_rule(Parser *p);
 static asdl_seq *_loop0_206_rule(Parser *p);
 static asdl_seq *_gather_205_rule(Parser *p);
 static asdl_seq *_loop0_208_rule(Parser *p);
 static asdl_seq *_gather_207_rule(Parser *p);
-static void *_tmp_209_rule(Parser *p);
 static asdl_seq *_loop0_210_rule(Parser *p);
-static asdl_seq *_loop1_211_rule(Parser *p);
-static void *_tmp_212_rule(Parser *p);
-static asdl_seq *_loop0_213_rule(Parser *p);
-static asdl_seq *_loop1_214_rule(Parser *p);
-static void *_tmp_215_rule(Parser *p);
-static void *_tmp_216_rule(Parser *p);
+static asdl_seq *_gather_209_rule(Parser *p);
+static void *_tmp_211_rule(Parser *p);
+static asdl_seq *_loop0_212_rule(Parser *p);
+static asdl_seq *_loop1_213_rule(Parser *p);
+static void *_tmp_214_rule(Parser *p);
+static asdl_seq *_loop0_215_rule(Parser *p);
+static asdl_seq *_loop1_216_rule(Parser *p);
 static void *_tmp_217_rule(Parser *p);
 static void *_tmp_218_rule(Parser *p);
 static void *_tmp_219_rule(Parser *p);
@@ -1052,10 +1065,10 @@ static void *_tmp_221_rule(Parser *p);
 static void *_tmp_222_rule(Parser *p);
 static void *_tmp_223_rule(Parser *p);
 static void *_tmp_224_rule(Parser *p);
-static asdl_seq *_loop0_226_rule(Parser *p);
-static asdl_seq *_gather_225_rule(Parser *p);
-static void *_tmp_227_rule(Parser *p);
-static void *_tmp_228_rule(Parser *p);
+static void *_tmp_225_rule(Parser *p);
+static void *_tmp_226_rule(Parser *p);
+static asdl_seq *_loop0_228_rule(Parser *p);
+static asdl_seq *_gather_227_rule(Parser *p);
 static void *_tmp_229_rule(Parser *p);
 static void *_tmp_230_rule(Parser *p);
 static void *_tmp_231_rule(Parser *p);
@@ -1067,9 +1080,9 @@ static void *_tmp_236_rule(Parser *p);
 static void *_tmp_237_rule(Parser *p);
 static void *_tmp_238_rule(Parser *p);
 static void *_tmp_239_rule(Parser *p);
-static asdl_seq *_loop0_240_rule(Parser *p);
+static void *_tmp_240_rule(Parser *p);
 static void *_tmp_241_rule(Parser *p);
-static void *_tmp_242_rule(Parser *p);
+static asdl_seq *_loop0_242_rule(Parser *p);
 static void *_tmp_243_rule(Parser *p);
 static void *_tmp_244_rule(Parser *p);
 static void *_tmp_245_rule(Parser *p);
@@ -1100,6 +1113,8 @@ static void *_tmp_269_rule(Parser *p);
 static void *_tmp_270_rule(Parser *p);
 static void *_tmp_271_rule(Parser *p);
 static void *_tmp_272_rule(Parser *p);
+static void *_tmp_273_rule(Parser *p);
+static void *_tmp_274_rule(Parser *p);
 
 
 // file: statements? $
@@ -1681,6 +1696,7 @@ simple_stmts_rule(Parser *p)
 
 // simple_stmt:
 //     | assignment
+//     | &"type" type_alias
 //     | star_expressions
 //     | &'return' return_stmt
 //     | &('import' | 'from') import_stmt
@@ -1738,6 +1754,27 @@ simple_stmt_rule(Parser *p)
         D(fprintf(stderr, "%*c%s simple_stmt[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "assignment"));
     }
+    { // &"type" type_alias
+        if (p->error_indicator) {
+            p->level--;
+            return NULL;
+        }
+        D(fprintf(stderr, "%*c> simple_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&\"type\" type_alias"));
+        stmt_ty type_alias_var;
+        if (
+            _PyPegen_lookahead_with_string(1, _PyPegen_expect_soft_keyword, p, "type")
+            &&
+            (type_alias_var = type_alias_rule(p))  // type_alias
+        )
+        {
+            D(fprintf(stderr, "%*c+ simple_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&\"type\" type_alias"));
+            _res = type_alias_var;
+            goto done;
+        }
+        p->mark = _mark;
+        D(fprintf(stderr, "%*c%s simple_stmt[%d-%d]: %s failed!\n", p->level, ' ',
+                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "&\"type\" type_alias"));
+    }
     { // star_expressions
         if (p->error_indicator) {
             p->level--;
@@ -4308,7 +4345,9 @@ class_def_rule(Parser *p)
     return _res;
 }
 
-// class_def_raw: invalid_class_def_raw | 'class' NAME ['(' arguments? ')'] ':' block
+// class_def_raw:
+//     | invalid_class_def_raw
+//     | 'class' NAME type_params? ['(' arguments? ')'] ':' block
 static stmt_ty
 class_def_raw_rule(Parser *p)
 {
@@ -4350,22 +4389,25 @@ class_def_raw_rule(Parser *p)
         D(fprintf(stderr, "%*c%s class_def_raw[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_class_def_raw"));
     }
-    { // 'class' NAME ['(' arguments? ')'] ':' block
+    { // 'class' NAME type_params? ['(' arguments? ')'] ':' block
         if (p->error_indicator) {
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> class_def_raw[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'class' NAME ['(' arguments? ')'] ':' block"));
+        D(fprintf(stderr, "%*c> class_def_raw[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'class' NAME type_params? ['(' arguments? ')'] ':' block"));
         Token * _keyword;
         Token * _literal;
         expr_ty a;
         void *b;
         asdl_stmt_seq* c;
+        void *t;
         if (
             (_keyword = _PyPegen_expect_token(p, 654))  // token='class'
             &&
             (a = _PyPegen_name_token(p))  // NAME
             &&
+            (t = type_params_rule(p), !p->error_indicator)  // type_params?
+            &&
             (b = _tmp_34_rule(p), !p->error_indicator)  // ['(' arguments? ')']
             &&
             (_literal = _PyPegen_expect_token(p, 11))  // token=':'
@@ -4373,7 +4415,7 @@ class_def_raw_rule(Parser *p)
             (c = block_rule(p))  // block
         )
         {
-            D(fprintf(stderr, "%*c+ class_def_raw[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'class' NAME ['(' arguments? ')'] ':' block"));
+            D(fprintf(stderr, "%*c+ class_def_raw[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'class' NAME type_params? ['(' arguments? ')'] ':' block"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
                 p->level--;
@@ -4383,7 +4425,7 @@ class_def_raw_rule(Parser *p)
             UNUSED(_end_lineno); // Only used by EXTRA macro
             int _end_col_offset = _token->end_col_offset;
             UNUSED(_end_col_offset); // Only used by EXTRA macro
-            _res = _PyAST_ClassDef ( a -> v . Name . id , ( b ) ? ( ( expr_ty ) b ) -> v . Call . args : NULL , ( b ) ? ( ( expr_ty ) b ) -> v . Call . keywords : NULL , c , NULL , EXTRA );
+            _res = _PyAST_ClassDef ( a -> v . Name . id , t , ( b ) ? ( ( expr_ty ) b ) -> v . Call . args : NULL , ( b ) ? ( ( expr_ty ) b ) -> v . Call . keywords : NULL , c , NULL , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
                 p->level--;
@@ -4393,7 +4435,7 @@ class_def_raw_rule(Parser *p)
         }
         p->mark = _mark;
         D(fprintf(stderr, "%*c%s class_def_raw[%d-%d]: %s failed!\n", p->level, ' ',
-                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'class' NAME ['(' arguments? ')'] ':' block"));
+                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'class' NAME type_params? ['(' arguments? ')'] ':' block"));
     }
     _res = NULL;
   done:
@@ -4469,8 +4511,8 @@ function_def_rule(Parser *p)
 
 // function_def_raw:
 //     | invalid_def_raw
-//     | 'def' NAME &&'(' params? ')' ['->' expression] &&':' func_type_comment? block
-//     | ASYNC 'def' NAME &&'(' params? ')' ['->' expression] &&':' func_type_comment? block
+//     | 'def' NAME type_params? &&'(' params? ')' ['->' expression] &&':' func_type_comment? block
+//     | ASYNC 'def' NAME type_params? &&'(' params? ')' ['->' expression] &&':' func_type_comment? block
 static stmt_ty
 function_def_raw_rule(Parser *p)
 {
@@ -4512,12 +4554,12 @@ function_def_raw_rule(Parser *p)
         D(fprintf(stderr, "%*c%s function_def_raw[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "invalid_def_raw"));
     }
-    { // 'def' NAME &&'(' params? ')' ['->' expression] &&':' func_type_comment? block
+    { // 'def' NAME type_params? &&'(' params? ')' ['->' expression] &&':' func_type_comment? block
         if (p->error_indicator) {
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> function_def_raw[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'def' NAME &&'(' params? ')' ['->' expression] &&':' func_type_comment? block"));
+        D(fprintf(stderr, "%*c> function_def_raw[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'def' NAME type_params? &&'(' params? ')' ['->' expression] &&':' func_type_comment? block"));
         Token * _keyword;
         Token * _literal;
         Token * _literal_1;
@@ -4526,12 +4568,15 @@ function_def_raw_rule(Parser *p)
         asdl_stmt_seq* b;
         expr_ty n;
         void *params;
+        void *t;
         void *tc;
         if (
             (_keyword = _PyPegen_expect_token(p, 652))  // token='def'
             &&
             (n = _PyPegen_name_token(p))  // NAME
             &&
+            (t = type_params_rule(p), !p->error_indicator)  // type_params?
+            &&
             (_literal = _PyPegen_expect_forced_token(p, 7, "("))  // forced_token='('
             &&
             (params = params_rule(p), !p->error_indicator)  // params?
@@ -4547,7 +4592,7 @@ function_def_raw_rule(Parser *p)
             (b = block_rule(p))  // block
         )
         {
-            D(fprintf(stderr, "%*c+ function_def_raw[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'def' NAME &&'(' params? ')' ['->' expression] &&':' func_type_comment? block"));
+            D(fprintf(stderr, "%*c+ function_def_raw[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'def' NAME type_params? &&'(' params? ')' ['->' expression] &&':' func_type_comment? block"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
                 p->level--;
@@ -4557,7 +4602,7 @@ function_def_raw_rule(Parser *p)
             UNUSED(_end_lineno); // Only used by EXTRA macro
             int _end_col_offset = _token->end_col_offset;
             UNUSED(_end_col_offset); // Only used by EXTRA macro
-            _res = _PyAST_FunctionDef ( n -> v . Name . id , ( params ) ? params : CHECK ( arguments_ty , _PyPegen_empty_arguments ( p ) ) , b , NULL , a , NEW_TYPE_COMMENT ( p , tc ) , EXTRA );
+            _res = _PyAST_FunctionDef ( n -> v . Name . id , t , ( params ) ? params : CHECK ( arguments_ty , _PyPegen_empty_arguments ( p ) ) , b , NULL , a , NEW_TYPE_COMMENT ( p , tc ) , EXTRA );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
                 p->level--;
@@ -4567,14 +4612,14 @@ function_def_raw_rule(Parser *p)
         }
         p->mark = _mark;
         D(fprintf(stderr, "%*c%s function_def_raw[%d-%d]: %s failed!\n", p->level, ' ',
-                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'def' NAME &&'(' params? ')' ['->' expression] &&':' func_type_comment? block"));
+                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'def' NAME type_params? &&'(' params? ')' ['->' expression] &&':' func_type_comment? block"));
     }
-    { // ASYNC 'def' NAME &&'(' params? ')' ['->' expression] &&':' func_type_comment? block
+    { // ASYNC 'def' NAME type_params? &&'(' params? ')' ['->' expression] &&':' func_type_comment? block
         if (p->error_indicator) {
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> function_def_raw[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC 'def' NAME &&'(' params? ')' ['->' expression] &&':' func_type_comment? block"));
+        D(fprintf(stderr, "%*c> function_def_raw[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC 'def' NAME type_params? &&'(' params? ')' ['->' expression] &&':' func_type_comment? block"));
         Token * _keyword;
         Token * _literal;
         Token * _literal_1;
@@ -4584,6 +4629,7 @@ function_def_raw_rule(Parser *p)
         asdl_stmt_seq* b;
         expr_ty n;
         void *params;
+        void *t;
         void *tc;
         if (
             (async_var = _PyPegen_expect_token(p, ASYNC))  // token='ASYNC'
@@ -4592,6 +4638,8 @@ function_def_raw_rule(Parser *p)
             &&
             (n = _PyPegen_name_token(p))  // NAME
             &&
+            (t = type_params_rule(p), !p->error_indicator)  // type_params?
+            &&
             (_literal = _PyPegen_expect_forced_token(p, 7, "("))  // forced_token='('
             &&
             (params = params_rule(p), !p->error_indicator)  // params?
@@ -4607,7 +4655,7 @@ function_def_raw_rule(Parser *p)
             (b = block_rule(p))  // block
         )
         {
-            D(fprintf(stderr, "%*c+ function_def_raw[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC 'def' NAME &&'(' params? ')' ['->' expression] &&':' func_type_comment? block"));
+            D(fprintf(stderr, "%*c+ function_def_raw[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC 'def' NAME type_params? &&'(' params? ')' ['->' expression] &&':' func_type_comment? block"));
             Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
             if (_token == NULL) {
                 p->level--;
@@ -4617,7 +4665,7 @@ function_def_raw_rule(Parser *p)
             UNUSED(_end_lineno); // Only used by EXTRA macro
             int _end_col_offset = _token->end_col_offset;
             UNUSED(_end_col_offset); // Only used by EXTRA macro
-            _res = CHECK_VERSION ( stmt_ty , 5 , "Async functions are" , _PyAST_AsyncFunctionDef ( n -> v . Name . id , ( params ) ? params : CHECK ( arguments_ty , _PyPegen_empty_arguments ( p ) ) , b , NULL , a , NEW_TYPE_COMMENT ( p , tc ) , EXTRA ) );
+            _res = CHECK_VERSION ( stmt_ty , 5 , "Async functions are" , _PyAST_AsyncFunctionDef ( n -> v . Name . id , t , ( params ) ? params : CHECK ( arguments_ty , _PyPegen_empty_arguments ( p ) ) , b , NULL , a , NEW_TYPE_COMMENT ( p , tc ) , EXTRA ) );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
                 p->level--;
@@ -4627,7 +4675,7 @@ function_def_raw_rule(Parser *p)
         }
         p->mark = _mark;
         D(fprintf(stderr, "%*c%s function_def_raw[%d-%d]: %s failed!\n", p->level, ' ',
-                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC 'def' NAME &&'(' params? ')' ['->' expression] &&':' func_type_comment? block"));
+                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "ASYNC 'def' NAME type_params? &&'(' params? ')' ['->' expression] &&':' func_type_comment? block"));
     }
     _res = NULL;
   done:
@@ -10530,6 +10578,438 @@ keyword_pattern_rule(Parser *p)
     return _res;
 }
 
+// type_alias: "type" NAME type_params? '=' expression
+static stmt_ty
+type_alias_rule(Parser *p)
+{
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
+    if (p->error_indicator) {
+        p->level--;
+        return NULL;
+    }
+    stmt_ty _res = NULL;
+    int _mark = p->mark;
+    if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
+        p->error_indicator = 1;
+        p->level--;
+        return NULL;
+    }
+    int _start_lineno = p->tokens[_mark]->lineno;
+    UNUSED(_start_lineno); // Only used by EXTRA macro
+    int _start_col_offset = p->tokens[_mark]->col_offset;
+    UNUSED(_start_col_offset); // Only used by EXTRA macro
+    { // "type" NAME type_params? '=' expression
+        if (p->error_indicator) {
+            p->level--;
+            return NULL;
+        }
+        D(fprintf(stderr, "%*c> type_alias[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "\"type\" NAME type_params? '=' expression"));
+        expr_ty _keyword;
+        Token * _literal;
+        expr_ty b;
+        expr_ty n;
+        void *t;
+        if (
+            (_keyword = _PyPegen_expect_soft_keyword(p, "type"))  // soft_keyword='"type"'
+            &&
+            (n = _PyPegen_name_token(p))  // NAME
+            &&
+            (t = type_params_rule(p), !p->error_indicator)  // type_params?
+            &&
+            (_literal = _PyPegen_expect_token(p, 22))  // token='='
+            &&
+            (b = expression_rule(p))  // expression
+        )
+        {
+            D(fprintf(stderr, "%*c+ type_alias[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "\"type\" NAME type_params? '=' expression"));
+            Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
+            if (_token == NULL) {
+                p->level--;
+                return NULL;
+            }
+            int _end_lineno = _token->end_lineno;
+            UNUSED(_end_lineno); // Only used by EXTRA macro
+            int _end_col_offset = _token->end_col_offset;
+            UNUSED(_end_col_offset); // Only used by EXTRA macro
+            _res = CHECK_VERSION ( stmt_ty , 12 , "Type statement is" , _PyAST_TypeAlias ( CHECK ( expr_ty , _PyPegen_set_expr_context ( p , n , Store ) ) , t , b , EXTRA ) );
+            if (_res == NULL && PyErr_Occurred()) {
+                p->error_indicator = 1;
+                p->level--;
+                return NULL;
+            }
+            goto done;
+        }
+        p->mark = _mark;
+        D(fprintf(stderr, "%*c%s type_alias[%d-%d]: %s failed!\n", p->level, ' ',
+                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "\"type\" NAME type_params? '=' expression"));
+    }
+    _res = NULL;
+  done:
+    p->level--;
+    return _res;
+}
+
+// type_params: '[' type_param_seq ']'
+static asdl_typeparam_seq*
+type_params_rule(Parser *p)
+{
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
+    if (p->error_indicator) {
+        p->level--;
+        return NULL;
+    }
+    asdl_typeparam_seq* _res = NULL;
+    int _mark = p->mark;
+    { // '[' type_param_seq ']'
+        if (p->error_indicator) {
+            p->level--;
+            return NULL;
+        }
+        D(fprintf(stderr, "%*c> type_params[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'[' type_param_seq ']'"));
+        Token * _literal;
+        Token * _literal_1;
+        asdl_typeparam_seq* t;
+        if (
+            (_literal = _PyPegen_expect_token(p, 9))  // token='['
+            &&
+            (t = type_param_seq_rule(p))  // type_param_seq
+            &&
+            (_literal_1 = _PyPegen_expect_token(p, 10))  // token=']'
+        )
+        {
+            D(fprintf(stderr, "%*c+ type_params[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'[' type_param_seq ']'"));
+            _res = CHECK_VERSION ( asdl_typeparam_seq* , 12 , "Type parameter lists are" , t );
+            if (_res == NULL && PyErr_Occurred()) {
+                p->error_indicator = 1;
+                p->level--;
+                return NULL;
+            }
+            goto done;
+        }
+        p->mark = _mark;
+        D(fprintf(stderr, "%*c%s type_params[%d-%d]: %s failed!\n", p->level, ' ',
+                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'[' type_param_seq ']'"));
+    }
+    _res = NULL;
+  done:
+    p->level--;
+    return _res;
+}
+
+// type_param_seq: ','.type_param+ ','?
+static asdl_typeparam_seq*
+type_param_seq_rule(Parser *p)
+{
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
+    if (p->error_indicator) {
+        p->level--;
+        return NULL;
+    }
+    asdl_typeparam_seq* _res = NULL;
+    int _mark = p->mark;
+    { // ','.type_param+ ','?
+        if (p->error_indicator) {
+            p->level--;
+            return NULL;
+        }
+        D(fprintf(stderr, "%*c> type_param_seq[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.type_param+ ','?"));
+        void *_opt_var;
+        UNUSED(_opt_var); // Silence compiler warnings
+        asdl_typeparam_seq* a;
+        if (
+            (a = (asdl_typeparam_seq*)_gather_81_rule(p))  // ','.type_param+
+            &&
+            (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator)  // ','?
+        )
+        {
+            D(fprintf(stderr, "%*c+ type_param_seq[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.type_param+ ','?"));
+            _res = a;
+            if (_res == NULL && PyErr_Occurred()) {
+                p->error_indicator = 1;
+                p->level--;
+                return NULL;
+            }
+            goto done;
+        }
+        p->mark = _mark;
+        D(fprintf(stderr, "%*c%s type_param_seq[%d-%d]: %s failed!\n", p->level, ' ',
+                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','.type_param+ ','?"));
+    }
+    _res = NULL;
+  done:
+    p->level--;
+    return _res;
+}
+
+// type_param:
+//     | NAME type_param_bound?
+//     | '*' NAME ":" expression
+//     | '*' NAME
+//     | '**' NAME ":" expression
+//     | '**' NAME
+static typeparam_ty
+type_param_rule(Parser *p)
+{
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
+    if (p->error_indicator) {
+        p->level--;
+        return NULL;
+    }
+    typeparam_ty _res = NULL;
+    if (_PyPegen_is_memoized(p, type_param_type, &_res)) {
+        p->level--;
+        return _res;
+    }
+    int _mark = p->mark;
+    if (p->mark == p->fill && _PyPegen_fill_token(p) < 0) {
+        p->error_indicator = 1;
+        p->level--;
+        return NULL;
+    }
+    int _start_lineno = p->tokens[_mark]->lineno;
+    UNUSED(_start_lineno); // Only used by EXTRA macro
+    int _start_col_offset = p->tokens[_mark]->col_offset;
+    UNUSED(_start_col_offset); // Only used by EXTRA macro
+    { // NAME type_param_bound?
+        if (p->error_indicator) {
+            p->level--;
+            return NULL;
+        }
+        D(fprintf(stderr, "%*c> type_param[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME type_param_bound?"));
+        expr_ty a;
+        void *b;
+        if (
+            (a = _PyPegen_name_token(p))  // NAME
+            &&
+            (b = type_param_bound_rule(p), !p->error_indicator)  // type_param_bound?
+        )
+        {
+            D(fprintf(stderr, "%*c+ type_param[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME type_param_bound?"));
+            Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
+            if (_token == NULL) {
+                p->level--;
+                return NULL;
+            }
+            int _end_lineno = _token->end_lineno;
+            UNUSED(_end_lineno); // Only used by EXTRA macro
+            int _end_col_offset = _token->end_col_offset;
+            UNUSED(_end_col_offset); // Only used by EXTRA macro
+            _res = _PyAST_TypeVar ( a -> v . Name . id , b , EXTRA );
+            if (_res == NULL && PyErr_Occurred()) {
+                p->error_indicator = 1;
+                p->level--;
+                return NULL;
+            }
+            goto done;
+        }
+        p->mark = _mark;
+        D(fprintf(stderr, "%*c%s type_param[%d-%d]: %s failed!\n", p->level, ' ',
+                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME type_param_bound?"));
+    }
+    { // '*' NAME ":" expression
+        if (p->error_indicator) {
+            p->level--;
+            return NULL;
+        }
+        D(fprintf(stderr, "%*c> type_param[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' NAME \":\" expression"));
+        Token * _literal;
+        expr_ty a;
+        Token * colon;
+        expr_ty e;
+        if (
+            (_literal = _PyPegen_expect_token(p, 16))  // token='*'
+            &&
+            (a = _PyPegen_name_token(p))  // NAME
+            &&
+            (colon = _PyPegen_expect_token(p, 11))  // token=':'
+            &&
+            (e = expression_rule(p))  // expression
+        )
+        {
+            D(fprintf(stderr, "%*c+ type_param[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' NAME \":\" expression"));
+            _res = RAISE_SYNTAX_ERROR_STARTING_FROM ( colon , e -> kind == Tuple_kind ? "cannot use constraints with TypeVarTuple" : "cannot use bound with TypeVarTuple" );
+            if (_res == NULL && PyErr_Occurred()) {
+                p->error_indicator = 1;
+                p->level--;
+                return NULL;
+            }
+            goto done;
+        }
+        p->mark = _mark;
+        D(fprintf(stderr, "%*c%s type_param[%d-%d]: %s failed!\n", p->level, ' ',
+                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' NAME \":\" expression"));
+    }
+    { // '*' NAME
+        if (p->error_indicator) {
+            p->level--;
+            return NULL;
+        }
+        D(fprintf(stderr, "%*c> type_param[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' NAME"));
+        Token * _literal;
+        expr_ty a;
+        if (
+            (_literal = _PyPegen_expect_token(p, 16))  // token='*'
+            &&
+            (a = _PyPegen_name_token(p))  // NAME
+        )
+        {
+            D(fprintf(stderr, "%*c+ type_param[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' NAME"));
+            Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
+            if (_token == NULL) {
+                p->level--;
+                return NULL;
+            }
+            int _end_lineno = _token->end_lineno;
+            UNUSED(_end_lineno); // Only used by EXTRA macro
+            int _end_col_offset = _token->end_col_offset;
+            UNUSED(_end_col_offset); // Only used by EXTRA macro
+            _res = _PyAST_TypeVarTuple ( a -> v . Name . id , EXTRA );
+            if (_res == NULL && PyErr_Occurred()) {
+                p->error_indicator = 1;
+                p->level--;
+                return NULL;
+            }
+            goto done;
+        }
+        p->mark = _mark;
+        D(fprintf(stderr, "%*c%s type_param[%d-%d]: %s failed!\n", p->level, ' ',
+                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*' NAME"));
+    }
+    { // '**' NAME ":" expression
+        if (p->error_indicator) {
+            p->level--;
+            return NULL;
+        }
+        D(fprintf(stderr, "%*c> type_param[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**' NAME \":\" expression"));
+        Token * _literal;
+        expr_ty a;
+        Token * colon;
+        expr_ty e;
+        if (
+            (_literal = _PyPegen_expect_token(p, 35))  // token='**'
+            &&
+            (a = _PyPegen_name_token(p))  // NAME
+            &&
+            (colon = _PyPegen_expect_token(p, 11))  // token=':'
+            &&
+            (e = expression_rule(p))  // expression
+        )
+        {
+            D(fprintf(stderr, "%*c+ type_param[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' NAME \":\" expression"));
+            _res = RAISE_SYNTAX_ERROR_STARTING_FROM ( colon , e -> kind == Tuple_kind ? "cannot use constraints with ParamSpec" : "cannot use bound with ParamSpec" );
+            if (_res == NULL && PyErr_Occurred()) {
+                p->error_indicator = 1;
+                p->level--;
+                return NULL;
+            }
+            goto done;
+        }
+        p->mark = _mark;
+        D(fprintf(stderr, "%*c%s type_param[%d-%d]: %s failed!\n", p->level, ' ',
+                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**' NAME \":\" expression"));
+    }
+    { // '**' NAME
+        if (p->error_indicator) {
+            p->level--;
+            return NULL;
+        }
+        D(fprintf(stderr, "%*c> type_param[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**' NAME"));
+        Token * _literal;
+        expr_ty a;
+        if (
+            (_literal = _PyPegen_expect_token(p, 35))  // token='**'
+            &&
+            (a = _PyPegen_name_token(p))  // NAME
+        )
+        {
+            D(fprintf(stderr, "%*c+ type_param[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' NAME"));
+            Token *_token = _PyPegen_get_last_nonnwhitespace_token(p);
+            if (_token == NULL) {
+                p->level--;
+                return NULL;
+            }
+            int _end_lineno = _token->end_lineno;
+            UNUSED(_end_lineno); // Only used by EXTRA macro
+            int _end_col_offset = _token->end_col_offset;
+            UNUSED(_end_col_offset); // Only used by EXTRA macro
+            _res = _PyAST_ParamSpec ( a -> v . Name . id , EXTRA );
+            if (_res == NULL && PyErr_Occurred()) {
+                p->error_indicator = 1;
+                p->level--;
+                return NULL;
+            }
+            goto done;
+        }
+        p->mark = _mark;
+        D(fprintf(stderr, "%*c%s type_param[%d-%d]: %s failed!\n", p->level, ' ',
+                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**' NAME"));
+    }
+    _res = NULL;
+  done:
+    _PyPegen_insert_memo(p, _mark, type_param_type, _res);
+    p->level--;
+    return _res;
+}
+
+// type_param_bound: ":" expression
+static expr_ty
+type_param_bound_rule(Parser *p)
+{
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
+    if (p->error_indicator) {
+        p->level--;
+        return NULL;
+    }
+    expr_ty _res = NULL;
+    int _mark = p->mark;
+    { // ":" expression
+        if (p->error_indicator) {
+            p->level--;
+            return NULL;
+        }
+        D(fprintf(stderr, "%*c> type_param_bound[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "\":\" expression"));
+        Token * _literal;
+        expr_ty e;
+        if (
+            (_literal = _PyPegen_expect_token(p, 11))  // token=':'
+            &&
+            (e = expression_rule(p))  // expression
+        )
+        {
+            D(fprintf(stderr, "%*c+ type_param_bound[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "\":\" expression"));
+            _res = e;
+            if (_res == NULL && PyErr_Occurred()) {
+                p->error_indicator = 1;
+                p->level--;
+                return NULL;
+            }
+            goto done;
+        }
+        p->mark = _mark;
+        D(fprintf(stderr, "%*c%s type_param_bound[%d-%d]: %s failed!\n", p->level, ' ',
+                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "\":\" expression"));
+    }
+    _res = NULL;
+  done:
+    p->level--;
+    return _res;
+}
+
 // expressions: expression ((',' expression))+ ','? | expression ',' | expression
 static expr_ty
 expressions_rule(Parser *p)
@@ -10566,7 +11046,7 @@ expressions_rule(Parser *p)
         if (
             (a = expression_rule(p))  // expression
             &&
-            (b = _loop1_81_rule(p))  // ((',' expression))+
+            (b = _loop1_83_rule(p))  // ((',' expression))+
             &&
             (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator)  // ','?
         )
@@ -10957,7 +11437,7 @@ star_expressions_rule(Parser *p)
         if (
             (a = star_expression_rule(p))  // star_expression
             &&
-            (b = _loop1_82_rule(p))  // ((',' star_expression))+
+            (b = _loop1_84_rule(p))  // ((',' star_expression))+
             &&
             (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator)  // ','?
         )
@@ -11158,7 +11638,7 @@ star_named_expressions_rule(Parser *p)
         UNUSED(_opt_var); // Silence compiler warnings
         asdl_expr_seq* a;
         if (
-            (a = (asdl_expr_seq*)_gather_83_rule(p))  // ','.star_named_expression+
+            (a = (asdl_expr_seq*)_gather_85_rule(p))  // ','.star_named_expression+
             &&
             (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator)  // ','?
         )
@@ -11458,7 +11938,7 @@ disjunction_rule(Parser *p)
         if (
             (a = conjunction_rule(p))  // conjunction
             &&
-            (b = _loop1_85_rule(p))  // (('or' conjunction))+
+            (b = _loop1_87_rule(p))  // (('or' conjunction))+
         )
         {
             D(fprintf(stderr, "%*c+ disjunction[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "conjunction (('or' conjunction))+"));
@@ -11547,7 +12027,7 @@ conjunction_rule(Parser *p)
         if (
             (a = inversion_rule(p))  // inversion
             &&
-            (b = _loop1_86_rule(p))  // (('and' inversion))+
+            (b = _loop1_88_rule(p))  // (('and' inversion))+
         )
         {
             D(fprintf(stderr, "%*c+ conjunction[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "inversion (('and' inversion))+"));
@@ -11721,7 +12201,7 @@ comparison_rule(Parser *p)
         if (
             (a = bitwise_or_rule(p))  // bitwise_or
             &&
-            (b = _loop1_87_rule(p))  // compare_op_bitwise_or_pair+
+            (b = _loop1_89_rule(p))  // compare_op_bitwise_or_pair+
         )
         {
             D(fprintf(stderr, "%*c+ comparison[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "bitwise_or compare_op_bitwise_or_pair+"));
@@ -12058,10 +12538,10 @@ noteq_bitwise_or_rule(Parser *p)
             return NULL;
         }
         D(fprintf(stderr, "%*c> noteq_bitwise_or[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('!=') bitwise_or"));
-        void *_tmp_88_var;
+        void *_tmp_90_var;
         expr_ty a;
         if (
-            (_tmp_88_var = _tmp_88_rule(p))  // '!='
+            (_tmp_90_var = _tmp_90_rule(p))  // '!='
             &&
             (a = bitwise_or_rule(p))  // bitwise_or
         )
@@ -14096,7 +14576,7 @@ slices_rule(Parser *p)
         UNUSED(_opt_var); // Silence compiler warnings
         asdl_expr_seq* a;
         if (
-            (a = (asdl_expr_seq*)_gather_89_rule(p))  // ','.(slice | starred_expression)+
+            (a = (asdl_expr_seq*)_gather_91_rule(p))  // ','.(slice | starred_expression)+
             &&
             (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator)  // ','?
         )
@@ -14169,7 +14649,7 @@ slice_rule(Parser *p)
             &&
             (b = expression_rule(p), !p->error_indicator)  // expression?
             &&
-            (c = _tmp_91_rule(p), !p->error_indicator)  // [':' expression?]
+            (c = _tmp_93_rule(p), !p->error_indicator)  // [':' expression?]
         )
         {
             D(fprintf(stderr, "%*c+ slice[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression? ':' expression? [':' expression?]"));
@@ -14383,7 +14863,7 @@ atom_rule(Parser *p)
         D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&(STRING | FSTRING_START) strings"));
         expr_ty strings_var;
         if (
-            _PyPegen_lookahead(1, _tmp_92_rule, p)
+            _PyPegen_lookahead(1, _tmp_94_rule, p)
             &&
             (strings_var = strings_rule(p))  // strings
         )
@@ -14421,15 +14901,15 @@ atom_rule(Parser *p)
             return NULL;
         }
         D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'(' (tuple | group | genexp)"));
-        void *_tmp_93_var;
+        void *_tmp_95_var;
         if (
             _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 7)  // token='('
             &&
-            (_tmp_93_var = _tmp_93_rule(p))  // tuple | group | genexp
+            (_tmp_95_var = _tmp_95_rule(p))  // tuple | group | genexp
         )
         {
             D(fprintf(stderr, "%*c+ atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&'(' (tuple | group | genexp)"));
-            _res = _tmp_93_var;
+            _res = _tmp_95_var;
             goto done;
         }
         p->mark = _mark;
@@ -14442,15 +14922,15 @@ atom_rule(Parser *p)
             return NULL;
         }
         D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'[' (list | listcomp)"));
-        void *_tmp_94_var;
+        void *_tmp_96_var;
         if (
             _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 9)  // token='['
             &&
-            (_tmp_94_var = _tmp_94_rule(p))  // list | listcomp
+            (_tmp_96_var = _tmp_96_rule(p))  // list | listcomp
         )
         {
             D(fprintf(stderr, "%*c+ atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&'[' (list | listcomp)"));
-            _res = _tmp_94_var;
+            _res = _tmp_96_var;
             goto done;
         }
         p->mark = _mark;
@@ -14463,15 +14943,15 @@ atom_rule(Parser *p)
             return NULL;
         }
         D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "&'{' (dict | set | dictcomp | setcomp)"));
-        void *_tmp_95_var;
+        void *_tmp_97_var;
         if (
             _PyPegen_lookahead_with_int(1, _PyPegen_expect_token, p, 25)  // token='{'
             &&
-            (_tmp_95_var = _tmp_95_rule(p))  // dict | set | dictcomp | setcomp
+            (_tmp_97_var = _tmp_97_rule(p))  // dict | set | dictcomp | setcomp
         )
         {
             D(fprintf(stderr, "%*c+ atom[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "&'{' (dict | set | dictcomp | setcomp)"));
-            _res = _tmp_95_var;
+            _res = _tmp_97_var;
             goto done;
         }
         p->mark = _mark;
@@ -14543,7 +15023,7 @@ group_rule(Parser *p)
         if (
             (_literal = _PyPegen_expect_token(p, 7))  // token='('
             &&
-            (a = _tmp_96_rule(p))  // yield_expr | named_expression
+            (a = _tmp_98_rule(p))  // yield_expr | named_expression
             &&
             (_literal_1 = _PyPegen_expect_token(p, 8))  // token=')'
         )
@@ -14747,9 +15227,9 @@ lambda_parameters_rule(Parser *p)
         if (
             (a = lambda_slash_no_default_rule(p))  // lambda_slash_no_default
             &&
-            (b = (asdl_arg_seq*)_loop0_97_rule(p))  // lambda_param_no_default*
+            (b = (asdl_arg_seq*)_loop0_99_rule(p))  // lambda_param_no_default*
             &&
-            (c = _loop0_98_rule(p))  // lambda_param_with_default*
+            (c = _loop0_100_rule(p))  // lambda_param_with_default*
             &&
             (d = lambda_star_etc_rule(p), !p->error_indicator)  // lambda_star_etc?
         )
@@ -14779,7 +15259,7 @@ lambda_parameters_rule(Parser *p)
         if (
             (a = lambda_slash_with_default_rule(p))  // lambda_slash_with_default
             &&
-            (b = _loop0_99_rule(p))  // lambda_param_with_default*
+            (b = _loop0_101_rule(p))  // lambda_param_with_default*
             &&
             (c = lambda_star_etc_rule(p), !p->error_indicator)  // lambda_star_etc?
         )
@@ -14807,9 +15287,9 @@ lambda_parameters_rule(Parser *p)
         asdl_seq * b;
         void *c;
         if (
-            (a = (asdl_arg_seq*)_loop1_100_rule(p))  // lambda_param_no_default+
+            (a = (asdl_arg_seq*)_loop1_102_rule(p))  // lambda_param_no_default+
             &&
-            (b = _loop0_101_rule(p))  // lambda_param_with_default*
+            (b = _loop0_103_rule(p))  // lambda_param_with_default*
             &&
             (c = lambda_star_etc_rule(p), !p->error_indicator)  // lambda_star_etc?
         )
@@ -14836,7 +15316,7 @@ lambda_parameters_rule(Parser *p)
         asdl_seq * a;
         void *b;
         if (
-            (a = _loop1_102_rule(p))  // lambda_param_with_default+
+            (a = _loop1_104_rule(p))  // lambda_param_with_default+
             &&
             (b = lambda_star_etc_rule(p), !p->error_indicator)  // lambda_star_etc?
         )
@@ -14910,7 +15390,7 @@ lambda_slash_no_default_rule(Parser *p)
         Token * _literal_1;
         asdl_arg_seq* a;
         if (
-            (a = (asdl_arg_seq*)_loop1_103_rule(p))  // lambda_param_no_default+
+            (a = (asdl_arg_seq*)_loop1_105_rule(p))  // lambda_param_no_default+
             &&
             (_literal = _PyPegen_expect_token(p, 17))  // token='/'
             &&
@@ -14939,7 +15419,7 @@ lambda_slash_no_default_rule(Parser *p)
         Token * _literal;
         asdl_arg_seq* a;
         if (
-            (a = (asdl_arg_seq*)_loop1_104_rule(p))  // lambda_param_no_default+
+            (a = (asdl_arg_seq*)_loop1_106_rule(p))  // lambda_param_no_default+
             &&
             (_literal = _PyPegen_expect_token(p, 17))  // token='/'
             &&
@@ -14992,9 +15472,9 @@ lambda_slash_with_default_rule(Parser *p)
         asdl_seq * a;
         asdl_seq * b;
         if (
-            (a = _loop0_105_rule(p))  // lambda_param_no_default*
+            (a = _loop0_107_rule(p))  // lambda_param_no_default*
             &&
-            (b = _loop1_106_rule(p))  // lambda_param_with_default+
+            (b = _loop1_108_rule(p))  // lambda_param_with_default+
             &&
             (_literal = _PyPegen_expect_token(p, 17))  // token='/'
             &&
@@ -15024,9 +15504,9 @@ lambda_slash_with_default_rule(Parser *p)
         asdl_seq * a;
         asdl_seq * b;
         if (
-            (a = _loop0_107_rule(p))  // lambda_param_no_default*
+            (a = _loop0_109_rule(p))  // lambda_param_no_default*
             &&
-            (b = _loop1_108_rule(p))  // lambda_param_with_default+
+            (b = _loop1_110_rule(p))  // lambda_param_with_default+
             &&
             (_literal = _PyPegen_expect_token(p, 17))  // token='/'
             &&
@@ -15104,7 +15584,7 @@ lambda_star_etc_rule(Parser *p)
             &&
             (a = lambda_param_no_default_rule(p))  // lambda_param_no_default
             &&
-            (b = _loop0_109_rule(p))  // lambda_param_maybe_default*
+            (b = _loop0_111_rule(p))  // lambda_param_maybe_default*
             &&
             (c = lambda_kwds_rule(p), !p->error_indicator)  // lambda_kwds?
         )
@@ -15137,7 +15617,7 @@ lambda_star_etc_rule(Parser *p)
             &&
             (_literal_1 = _PyPegen_expect_token(p, 12))  // token=','
             &&
-            (b = _loop1_110_rule(p))  // lambda_param_maybe_default+
+            (b = _loop1_112_rule(p))  // lambda_param_maybe_default+
             &&
             (c = lambda_kwds_rule(p), !p->error_indicator)  // lambda_kwds?
         )
@@ -15647,7 +16127,7 @@ fstring_replacement_field_rule(Parser *p)
         if (
             (_literal = _PyPegen_expect_token(p, 25))  // token='{'
             &&
-            (a = _tmp_111_rule(p))  // yield_expr | star_expressions
+            (a = _tmp_113_rule(p))  // yield_expr | star_expressions
             &&
             (debug_expr = _PyPegen_expect_token(p, 22), !p->error_indicator)  // "="?
             &&
@@ -15786,7 +16266,7 @@ fstring_full_format_spec_rule(Parser *p)
         if (
             (colon = _PyPegen_expect_token(p, 11))  // token=':'
             &&
-            (spec = _loop0_112_rule(p))  // fstring_format_spec*
+            (spec = _loop0_114_rule(p))  // fstring_format_spec*
         )
         {
             D(fprintf(stderr, "%*c+ fstring_full_format_spec[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':' fstring_format_spec*"));
@@ -15959,7 +16439,7 @@ strings_rule(Parser *p)
         D(fprintf(stderr, "%*c> strings[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "((fstring | string))+"));
         asdl_expr_seq* a;
         if (
-            (a = (asdl_expr_seq*)_loop1_113_rule(p))  // ((fstring | string))+
+            (a = (asdl_expr_seq*)_loop1_115_rule(p))  // ((fstring | string))+
         )
         {
             D(fprintf(stderr, "%*c+ strings[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "((fstring | string))+"));
@@ -16094,7 +16574,7 @@ tuple_rule(Parser *p)
         if (
             (_literal = _PyPegen_expect_token(p, 7))  // token='('
             &&
-            (a = _tmp_114_rule(p), !p->error_indicator)  // [star_named_expression ',' star_named_expressions?]
+            (a = _tmp_116_rule(p), !p->error_indicator)  // [star_named_expression ',' star_named_expressions?]
             &&
             (_literal_1 = _PyPegen_expect_token(p, 8))  // token=')'
         )
@@ -16312,7 +16792,7 @@ double_starred_kvpairs_rule(Parser *p)
         UNUSED(_opt_var); // Silence compiler warnings
         asdl_seq * a;
         if (
-            (a = _gather_115_rule(p))  // ','.double_starred_kvpair+
+            (a = _gather_117_rule(p))  // ','.double_starred_kvpair+
             &&
             (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator)  // ','?
         )
@@ -16474,7 +16954,7 @@ for_if_clauses_rule(Parser *p)
         D(fprintf(stderr, "%*c> for_if_clauses[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "for_if_clause+"));
         asdl_comprehension_seq* a;
         if (
-            (a = (asdl_comprehension_seq*)_loop1_117_rule(p))  // for_if_clause+
+            (a = (asdl_comprehension_seq*)_loop1_119_rule(p))  // for_if_clause+
         )
         {
             D(fprintf(stderr, "%*c+ for_if_clauses[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "for_if_clause+"));
@@ -16539,7 +17019,7 @@ for_if_clause_rule(Parser *p)
             &&
             (b = disjunction_rule(p))  // disjunction
             &&
-            (c = (asdl_expr_seq*)_loop0_118_rule(p))  // (('if' disjunction))*
+            (c = (asdl_expr_seq*)_loop0_120_rule(p))  // (('if' disjunction))*
         )
         {
             D(fprintf(stderr, "%*c+ for_if_clause[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "ASYNC 'for' star_targets 'in' ~ disjunction (('if' disjunction))*"));
@@ -16582,7 +17062,7 @@ for_if_clause_rule(Parser *p)
             &&
             (b = disjunction_rule(p))  // disjunction
             &&
-            (c = (asdl_expr_seq*)_loop0_119_rule(p))  // (('if' disjunction))*
+            (c = (asdl_expr_seq*)_loop0_121_rule(p))  // (('if' disjunction))*
         )
         {
             D(fprintf(stderr, "%*c+ for_if_clause[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'for' star_targets 'in' ~ disjunction (('if' disjunction))*"));
@@ -16845,7 +17325,7 @@ genexp_rule(Parser *p)
         if (
             (_literal = _PyPegen_expect_token(p, 7))  // token='('
             &&
-            (a = _tmp_120_rule(p))  // assignment_expression | expression !':='
+            (a = _tmp_122_rule(p))  // assignment_expression | expression !':='
             &&
             (b = for_if_clauses_rule(p))  // for_if_clauses
             &&
@@ -17097,9 +17577,9 @@ args_rule(Parser *p)
         asdl_expr_seq* a;
         void *b;
         if (
-            (a = (asdl_expr_seq*)_gather_121_rule(p))  // ','.(starred_expression | (assignment_expression | expression !':=') !'=')+
+            (a = (asdl_expr_seq*)_gather_123_rule(p))  // ','.(starred_expression | (assignment_expression | expression !':=') !'=')+
             &&
-            (b = _tmp_123_rule(p), !p->error_indicator)  // [',' kwargs]
+            (b = _tmp_125_rule(p), !p->error_indicator)  // [',' kwargs]
         )
         {
             D(fprintf(stderr, "%*c+ args[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.(starred_expression | (assignment_expression | expression !':=') !'=')+ [',' kwargs]"));
@@ -17190,11 +17670,11 @@ kwargs_rule(Parser *p)
         asdl_seq * a;
         asdl_seq * b;
         if (
-            (a = _gather_124_rule(p))  // ','.kwarg_or_starred+
+            (a = _gather_126_rule(p))  // ','.kwarg_or_starred+
             &&
             (_literal = _PyPegen_expect_token(p, 12))  // token=','
             &&
-            (b = _gather_126_rule(p))  // ','.kwarg_or_double_starred+
+            (b = _gather_128_rule(p))  // ','.kwarg_or_double_starred+
         )
         {
             D(fprintf(stderr, "%*c+ kwargs[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.kwarg_or_starred+ ',' ','.kwarg_or_double_starred+"));
@@ -17216,13 +17696,13 @@ kwargs_rule(Parser *p)
             return NULL;
         }
         D(fprintf(stderr, "%*c> kwargs[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.kwarg_or_starred+"));
-        asdl_seq * _gather_128_var;
+        asdl_seq * _gather_130_var;
         if (
-            (_gather_128_var = _gather_128_rule(p))  // ','.kwarg_or_starred+
+            (_gather_130_var = _gather_130_rule(p))  // ','.kwarg_or_starred+
         )
         {
             D(fprintf(stderr, "%*c+ kwargs[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.kwarg_or_starred+"));
-            _res = _gather_128_var;
+            _res = _gather_130_var;
             goto done;
         }
         p->mark = _mark;
@@ -17235,13 +17715,13 @@ kwargs_rule(Parser *p)
             return NULL;
         }
         D(fprintf(stderr, "%*c> kwargs[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.kwarg_or_double_starred+"));
-        asdl_seq * _gather_130_var;
+        asdl_seq * _gather_132_var;
         if (
-            (_gather_130_var = _gather_130_rule(p))  // ','.kwarg_or_double_starred+
+            (_gather_132_var = _gather_132_rule(p))  // ','.kwarg_or_double_starred+
         )
         {
             D(fprintf(stderr, "%*c+ kwargs[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.kwarg_or_double_starred+"));
-            _res = _gather_130_var;
+            _res = _gather_132_var;
             goto done;
         }
         p->mark = _mark;
@@ -17634,7 +18114,7 @@ star_targets_rule(Parser *p)
         if (
             (a = star_target_rule(p))  // star_target
             &&
-            (b = _loop0_132_rule(p))  // ((',' star_target))*
+            (b = _loop0_134_rule(p))  // ((',' star_target))*
             &&
             (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator)  // ','?
         )
@@ -17691,7 +18171,7 @@ star_targets_list_seq_rule(Parser *p)
         UNUSED(_opt_var); // Silence compiler warnings
         asdl_expr_seq* a;
         if (
-            (a = (asdl_expr_seq*)_gather_133_rule(p))  // ','.star_target+
+            (a = (asdl_expr_seq*)_gather_135_rule(p))  // ','.star_target+
             &&
             (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator)  // ','?
         )
@@ -17742,7 +18222,7 @@ star_targets_tuple_seq_rule(Parser *p)
         if (
             (a = star_target_rule(p))  // star_target
             &&
-            (b = _loop1_135_rule(p))  // ((',' star_target))+
+            (b = _loop1_137_rule(p))  // ((',' star_target))+
             &&
             (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator)  // ','?
         )
@@ -17831,7 +18311,7 @@ star_target_rule(Parser *p)
         if (
             (_literal = _PyPegen_expect_token(p, 16))  // token='*'
             &&
-            (a = _tmp_136_rule(p))  // !'*' star_target
+            (a = _tmp_138_rule(p))  // !'*' star_target
         )
         {
             D(fprintf(stderr, "%*c+ star_target[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' (!'*' star_target)"));
@@ -18762,7 +19242,7 @@ del_targets_rule(Parser *p)
         UNUSED(_opt_var); // Silence compiler warnings
         asdl_expr_seq* a;
         if (
-            (a = (asdl_expr_seq*)_gather_137_rule(p))  // ','.del_target+
+            (a = (asdl_expr_seq*)_gather_139_rule(p))  // ','.del_target+
             &&
             (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator)  // ','?
         )
@@ -19123,7 +19603,7 @@ type_expressions_rule(Parser *p)
         expr_ty b;
         expr_ty c;
         if (
-            (a = _gather_139_rule(p))  // ','.expression+
+            (a = _gather_141_rule(p))  // ','.expression+
             &&
             (_literal = _PyPegen_expect_token(p, 12))  // token=','
             &&
@@ -19162,7 +19642,7 @@ type_expressions_rule(Parser *p)
         asdl_seq * a;
         expr_ty b;
         if (
-            (a = _gather_141_rule(p))  // ','.expression+
+            (a = _gather_143_rule(p))  // ','.expression+
             &&
             (_literal = _PyPegen_expect_token(p, 12))  // token=','
             &&
@@ -19195,7 +19675,7 @@ type_expressions_rule(Parser *p)
         asdl_seq * a;
         expr_ty b;
         if (
-            (a = _gather_143_rule(p))  // ','.expression+
+            (a = _gather_145_rule(p))  // ','.expression+
             &&
             (_literal = _PyPegen_expect_token(p, 12))  // token=','
             &&
@@ -19315,7 +19795,7 @@ type_expressions_rule(Parser *p)
         D(fprintf(stderr, "%*c> type_expressions[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.expression+"));
         asdl_expr_seq* a;
         if (
-            (a = (asdl_expr_seq*)_gather_145_rule(p))  // ','.expression+
+            (a = (asdl_expr_seq*)_gather_147_rule(p))  // ','.expression+
         )
         {
             D(fprintf(stderr, "%*c+ type_expressions[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.expression+"));
@@ -19367,7 +19847,7 @@ func_type_comment_rule(Parser *p)
             &&
             (t = _PyPegen_expect_token(p, TYPE_COMMENT))  // token='TYPE_COMMENT'
             &&
-            _PyPegen_lookahead(1, _tmp_147_rule, p)
+            _PyPegen_lookahead(1, _tmp_149_rule, p)
         )
         {
             D(fprintf(stderr, "%*c+ func_type_comment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NEWLINE TYPE_COMMENT &(NEWLINE INDENT)"));
@@ -19496,7 +19976,7 @@ invalid_arguments_rule(Parser *p)
             &&
             (_literal = _PyPegen_expect_token(p, 12))  // token=','
             &&
-            (_opt_var = _tmp_148_rule(p), !p->error_indicator)  // [args | expression for_if_clauses]
+            (_opt_var = _tmp_150_rule(p), !p->error_indicator)  // [args | expression for_if_clauses]
         )
         {
             D(fprintf(stderr, "%*c+ invalid_arguments[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression for_if_clauses ',' [args | expression for_if_clauses]"));
@@ -19556,13 +20036,13 @@ invalid_arguments_rule(Parser *p)
         expr_ty a;
         Token * b;
         if (
-            (_opt_var = _tmp_149_rule(p), !p->error_indicator)  // [(args ',')]
+            (_opt_var = _tmp_151_rule(p), !p->error_indicator)  // [(args ',')]
             &&
             (a = _PyPegen_name_token(p))  // NAME
             &&
             (b = _PyPegen_expect_token(p, 22))  // token='='
             &&
-            _PyPegen_lookahead(1, _tmp_150_rule, p)
+            _PyPegen_lookahead(1, _tmp_152_rule, p)
         )
         {
             D(fprintf(stderr, "%*c+ invalid_arguments[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "[(args ',')] NAME '=' &(',' | ')')"));
@@ -19701,7 +20181,7 @@ invalid_kwarg_rule(Parser *p)
         Token* a;
         Token * b;
         if (
-            (a = (Token*)_tmp_151_rule(p))  // 'True' | 'False' | 'None'
+            (a = (Token*)_tmp_153_rule(p))  // 'True' | 'False' | 'None'
             &&
             (b = _PyPegen_expect_token(p, 22))  // token='='
         )
@@ -19761,7 +20241,7 @@ invalid_kwarg_rule(Parser *p)
         expr_ty a;
         Token * b;
         if (
-            _PyPegen_lookahead(0, _tmp_152_rule, p)
+            _PyPegen_lookahead(0, _tmp_154_rule, p)
             &&
             (a = expression_rule(p))  // expression
             &&
@@ -20020,7 +20500,7 @@ invalid_expression_rule(Parser *p)
         expr_ty a;
         expr_ty b;
         if (
-            _PyPegen_lookahead(0, _tmp_153_rule, p)
+            _PyPegen_lookahead(0, _tmp_155_rule, p)
             &&
             (a = disjunction_rule(p))  // disjunction
             &&
@@ -20056,7 +20536,7 @@ invalid_expression_rule(Parser *p)
             &&
             (b = disjunction_rule(p))  // disjunction
             &&
-            _PyPegen_lookahead(0, _tmp_154_rule, p)
+            _PyPegen_lookahead(0, _tmp_156_rule, p)
         )
         {
             D(fprintf(stderr, "%*c+ invalid_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "disjunction 'if' disjunction !('else' | ':')"));
@@ -20089,7 +20569,7 @@ invalid_expression_rule(Parser *p)
             &&
             (b = _PyPegen_expect_token(p, 11))  // token=':'
             &&
-            _PyPegen_lookahead(1, _tmp_155_rule, p)
+            _PyPegen_lookahead(1, _tmp_157_rule, p)
         )
         {
             D(fprintf(stderr, "%*c+ invalid_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'lambda' lambda_params? ':' &(FSTRING_MIDDLE | fstring_replacement_field)"));
@@ -20178,7 +20658,7 @@ invalid_named_expression_rule(Parser *p)
             &&
             (b = bitwise_or_rule(p))  // bitwise_or
             &&
-            _PyPegen_lookahead(0, _tmp_156_rule, p)
+            _PyPegen_lookahead(0, _tmp_158_rule, p)
         )
         {
             D(fprintf(stderr, "%*c+ invalid_named_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME '=' bitwise_or !('=' | ':=')"));
@@ -20204,7 +20684,7 @@ invalid_named_expression_rule(Parser *p)
         Token * b;
         expr_ty bitwise_or_var;
         if (
-            _PyPegen_lookahead(0, _tmp_157_rule, p)
+            _PyPegen_lookahead(0, _tmp_159_rule, p)
             &&
             (a = bitwise_or_rule(p))  // bitwise_or
             &&
@@ -20212,7 +20692,7 @@ invalid_named_expression_rule(Parser *p)
             &&
             (bitwise_or_var = bitwise_or_rule(p))  // bitwise_or
             &&
-            _PyPegen_lookahead(0, _tmp_158_rule, p)
+            _PyPegen_lookahead(0, _tmp_160_rule, p)
         )
         {
             D(fprintf(stderr, "%*c+ invalid_named_expression[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "!(list | tuple | genexp | 'True' | 'None' | 'False') bitwise_or '=' bitwise_or !('=' | ':=')"));
@@ -20293,7 +20773,7 @@ invalid_assignment_rule(Parser *p)
         D(fprintf(stderr, "%*c> invalid_assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expression ',' star_named_expressions* ':' expression"));
         Token * _literal;
         Token * _literal_1;
-        asdl_seq * _loop0_159_var;
+        asdl_seq * _loop0_161_var;
         expr_ty a;
         expr_ty expression_var;
         if (
@@ -20301,7 +20781,7 @@ invalid_assignment_rule(Parser *p)
             &&
             (_literal = _PyPegen_expect_token(p, 12))  // token=','
             &&
-            (_loop0_159_var = _loop0_159_rule(p))  // star_named_expressions*
+            (_loop0_161_var = _loop0_161_rule(p))  // star_named_expressions*
             &&
             (_literal_1 = _PyPegen_expect_token(p, 11))  // token=':'
             &&
@@ -20358,10 +20838,10 @@ invalid_assignment_rule(Parser *p)
         }
         D(fprintf(stderr, "%*c> invalid_assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "((star_targets '='))* star_expressions '='"));
         Token * _literal;
-        asdl_seq * _loop0_160_var;
+        asdl_seq * _loop0_162_var;
         expr_ty a;
         if (
-            (_loop0_160_var = _loop0_160_rule(p))  // ((star_targets '='))*
+            (_loop0_162_var = _loop0_162_rule(p))  // ((star_targets '='))*
             &&
             (a = star_expressions_rule(p))  // star_expressions
             &&
@@ -20388,10 +20868,10 @@ invalid_assignment_rule(Parser *p)
         }
         D(fprintf(stderr, "%*c> invalid_assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "((star_targets '='))* yield_expr '='"));
         Token * _literal;
-        asdl_seq * _loop0_161_var;
+        asdl_seq * _loop0_163_var;
         expr_ty a;
         if (
-            (_loop0_161_var = _loop0_161_rule(p))  // ((star_targets '='))*
+            (_loop0_163_var = _loop0_163_rule(p))  // ((star_targets '='))*
             &&
             (a = yield_expr_rule(p))  // yield_expr
             &&
@@ -20417,7 +20897,7 @@ invalid_assignment_rule(Parser *p)
             return NULL;
         }
         D(fprintf(stderr, "%*c> invalid_assignment[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions augassign (yield_expr | star_expressions)"));
-        void *_tmp_162_var;
+        void *_tmp_164_var;
         expr_ty a;
         AugOperator* augassign_var;
         if (
@@ -20425,7 +20905,7 @@ invalid_assignment_rule(Parser *p)
             &&
             (augassign_var = augassign_rule(p))  // augassign
             &&
-            (_tmp_162_var = _tmp_162_rule(p))  // yield_expr | star_expressions
+            (_tmp_164_var = _tmp_164_rule(p))  // yield_expr | star_expressions
         )
         {
             D(fprintf(stderr, "%*c+ invalid_assignment[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions augassign (yield_expr | star_expressions)"));
@@ -20651,11 +21131,11 @@ invalid_comprehension_rule(Parser *p)
             return NULL;
         }
         D(fprintf(stderr, "%*c> invalid_comprehension[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('[' | '(' | '{') starred_expression for_if_clauses"));
-        void *_tmp_163_var;
+        void *_tmp_165_var;
         expr_ty a;
         asdl_comprehension_seq* for_if_clauses_var;
         if (
-            (_tmp_163_var = _tmp_163_rule(p))  // '[' | '(' | '{'
+            (_tmp_165_var = _tmp_165_rule(p))  // '[' | '(' | '{'
             &&
             (a = starred_expression_rule(p))  // starred_expression
             &&
@@ -20682,12 +21162,12 @@ invalid_comprehension_rule(Parser *p)
         }
         D(fprintf(stderr, "%*c> invalid_comprehension[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('[' | '{') star_named_expression ',' star_named_expressions for_if_clauses"));
         Token * _literal;
-        void *_tmp_164_var;
+        void *_tmp_166_var;
         expr_ty a;
         asdl_expr_seq* b;
         asdl_comprehension_seq* for_if_clauses_var;
         if (
-            (_tmp_164_var = _tmp_164_rule(p))  // '[' | '{'
+            (_tmp_166_var = _tmp_166_rule(p))  // '[' | '{'
             &&
             (a = star_named_expression_rule(p))  // star_named_expression
             &&
@@ -20717,12 +21197,12 @@ invalid_comprehension_rule(Parser *p)
             return NULL;
         }
         D(fprintf(stderr, "%*c> invalid_comprehension[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('[' | '{') star_named_expression ',' for_if_clauses"));
-        void *_tmp_165_var;
+        void *_tmp_167_var;
         expr_ty a;
         Token * b;
         asdl_comprehension_seq* for_if_clauses_var;
         if (
-            (_tmp_165_var = _tmp_165_rule(p))  // '[' | '{'
+            (_tmp_167_var = _tmp_167_rule(p))  // '[' | '{'
             &&
             (a = star_named_expression_rule(p))  // star_named_expression
             &&
@@ -20859,13 +21339,13 @@ invalid_parameters_rule(Parser *p)
             return NULL;
         }
         D(fprintf(stderr, "%*c> invalid_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(slash_no_default | slash_with_default) param_maybe_default* '/'"));
-        asdl_seq * _loop0_167_var;
-        void *_tmp_166_var;
+        asdl_seq * _loop0_169_var;
+        void *_tmp_168_var;
         Token * a;
         if (
-            (_tmp_166_var = _tmp_166_rule(p))  // slash_no_default | slash_with_default
+            (_tmp_168_var = _tmp_168_rule(p))  // slash_no_default | slash_with_default
             &&
-            (_loop0_167_var = _loop0_167_rule(p))  // param_maybe_default*
+            (_loop0_169_var = _loop0_169_rule(p))  // param_maybe_default*
             &&
             (a = _PyPegen_expect_token(p, 17))  // token='/'
         )
@@ -20889,7 +21369,7 @@ invalid_parameters_rule(Parser *p)
             return NULL;
         }
         D(fprintf(stderr, "%*c> invalid_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_no_default? param_no_default* invalid_parameters_helper param_no_default"));
-        asdl_seq * _loop0_168_var;
+        asdl_seq * _loop0_170_var;
         void *_opt_var;
         UNUSED(_opt_var); // Silence compiler warnings
         arg_ty a;
@@ -20897,7 +21377,7 @@ invalid_parameters_rule(Parser *p)
         if (
             (_opt_var = slash_no_default_rule(p), !p->error_indicator)  // slash_no_default?
             &&
-            (_loop0_168_var = _loop0_168_rule(p))  // param_no_default*
+            (_loop0_170_var = _loop0_170_rule(p))  // param_no_default*
             &&
             (invalid_parameters_helper_var = invalid_parameters_helper_rule(p))  // invalid_parameters_helper
             &&
@@ -20923,18 +21403,18 @@ invalid_parameters_rule(Parser *p)
             return NULL;
         }
         D(fprintf(stderr, "%*c> invalid_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default* '(' param_no_default+ ','? ')'"));
-        asdl_seq * _loop0_169_var;
-        asdl_seq * _loop1_170_var;
+        asdl_seq * _loop0_171_var;
+        asdl_seq * _loop1_172_var;
         void *_opt_var;
         UNUSED(_opt_var); // Silence compiler warnings
         Token * a;
         Token * b;
         if (
-            (_loop0_169_var = _loop0_169_rule(p))  // param_no_default*
+            (_loop0_171_var = _loop0_171_rule(p))  // param_no_default*
             &&
             (a = _PyPegen_expect_token(p, 7))  // token='('
             &&
-            (_loop1_170_var = _loop1_170_rule(p))  // param_no_default+
+            (_loop1_172_var = _loop1_172_rule(p))  // param_no_default+
             &&
             (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator)  // ','?
             &&
@@ -20961,22 +21441,22 @@ invalid_parameters_rule(Parser *p)
         }
         D(fprintf(stderr, "%*c> invalid_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "[(slash_no_default | slash_with_default)] param_maybe_default* '*' (',' | param_no_default) param_maybe_default* '/'"));
         Token * _literal;
-        asdl_seq * _loop0_172_var;
         asdl_seq * _loop0_174_var;
+        asdl_seq * _loop0_176_var;
         void *_opt_var;
         UNUSED(_opt_var); // Silence compiler warnings
-        void *_tmp_173_var;
+        void *_tmp_175_var;
         Token * a;
         if (
-            (_opt_var = _tmp_171_rule(p), !p->error_indicator)  // [(slash_no_default | slash_with_default)]
+            (_opt_var = _tmp_173_rule(p), !p->error_indicator)  // [(slash_no_default | slash_with_default)]
             &&
-            (_loop0_172_var = _loop0_172_rule(p))  // param_maybe_default*
+            (_loop0_174_var = _loop0_174_rule(p))  // param_maybe_default*
             &&
             (_literal = _PyPegen_expect_token(p, 16))  // token='*'
             &&
-            (_tmp_173_var = _tmp_173_rule(p))  // ',' | param_no_default
+            (_tmp_175_var = _tmp_175_rule(p))  // ',' | param_no_default
             &&
-            (_loop0_174_var = _loop0_174_rule(p))  // param_maybe_default*
+            (_loop0_176_var = _loop0_176_rule(p))  // param_maybe_default*
             &&
             (a = _PyPegen_expect_token(p, 17))  // token='/'
         )
@@ -21001,10 +21481,10 @@ invalid_parameters_rule(Parser *p)
         }
         D(fprintf(stderr, "%*c> invalid_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default+ '/' '*'"));
         Token * _literal;
-        asdl_seq * _loop1_175_var;
+        asdl_seq * _loop1_177_var;
         Token * a;
         if (
-            (_loop1_175_var = _loop1_175_rule(p))  // param_maybe_default+
+            (_loop1_177_var = _loop1_177_rule(p))  // param_maybe_default+
             &&
             (_literal = _PyPegen_expect_token(p, 17))  // token='/'
             &&
@@ -21054,7 +21534,7 @@ invalid_default_rule(Parser *p)
         if (
             (a = _PyPegen_expect_token(p, 22))  // token='='
             &&
-            _PyPegen_lookahead(1, _tmp_176_rule, p)
+            _PyPegen_lookahead(1, _tmp_178_rule, p)
         )
         {
             D(fprintf(stderr, "%*c+ invalid_default[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'=' &(')' | ',')"));
@@ -21100,12 +21580,12 @@ invalid_star_etc_rule(Parser *p)
             return NULL;
         }
         D(fprintf(stderr, "%*c> invalid_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' (')' | ',' (')' | '**'))"));
-        void *_tmp_177_var;
+        void *_tmp_179_var;
         Token * a;
         if (
             (a = _PyPegen_expect_token(p, 16))  // token='*'
             &&
-            (_tmp_177_var = _tmp_177_rule(p))  // ')' | ',' (')' | '**')
+            (_tmp_179_var = _tmp_179_rule(p))  // ')' | ',' (')' | '**')
         )
         {
             D(fprintf(stderr, "%*c+ invalid_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' (')' | ',' (')' | '**'))"));
@@ -21188,20 +21668,20 @@ invalid_star_etc_rule(Parser *p)
         }
         D(fprintf(stderr, "%*c> invalid_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' (param_no_default | ',') param_maybe_default* '*' (param_no_default | ',')"));
         Token * _literal;
-        asdl_seq * _loop0_179_var;
-        void *_tmp_178_var;
+        asdl_seq * _loop0_181_var;
         void *_tmp_180_var;
+        void *_tmp_182_var;
         Token * a;
         if (
             (_literal = _PyPegen_expect_token(p, 16))  // token='*'
             &&
-            (_tmp_178_var = _tmp_178_rule(p))  // param_no_default | ','
+            (_tmp_180_var = _tmp_180_rule(p))  // param_no_default | ','
             &&
-            (_loop0_179_var = _loop0_179_rule(p))  // param_maybe_default*
+            (_loop0_181_var = _loop0_181_rule(p))  // param_maybe_default*
             &&
             (a = _PyPegen_expect_token(p, 16))  // token='*'
             &&
-            (_tmp_180_var = _tmp_180_rule(p))  // param_no_default | ','
+            (_tmp_182_var = _tmp_182_rule(p))  // param_no_default | ','
         )
         {
             D(fprintf(stderr, "%*c+ invalid_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' (param_no_default | ',') param_maybe_default* '*' (param_no_default | ',')"));
@@ -21317,7 +21797,7 @@ invalid_kwds_rule(Parser *p)
             &&
             (_literal_1 = _PyPegen_expect_token(p, 12))  // token=','
             &&
-            (a = (Token*)_tmp_181_rule(p))  // '*' | '**' | '/'
+            (a = (Token*)_tmp_183_rule(p))  // '*' | '**' | '/'
         )
         {
             D(fprintf(stderr, "%*c+ invalid_kwds[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' param ',' ('*' | '**' | '/')"));
@@ -21383,13 +21863,13 @@ invalid_parameters_helper_rule(Parser *p)
             return NULL;
         }
         D(fprintf(stderr, "%*c> invalid_parameters_helper[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default+"));
-        asdl_seq * _loop1_182_var;
+        asdl_seq * _loop1_184_var;
         if (
-            (_loop1_182_var = _loop1_182_rule(p))  // param_with_default+
+            (_loop1_184_var = _loop1_184_rule(p))  // param_with_default+
         )
         {
             D(fprintf(stderr, "%*c+ invalid_parameters_helper[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_with_default+"));
-            _res = _loop1_182_var;
+            _res = _loop1_184_var;
             goto done;
         }
         p->mark = _mark;
@@ -21455,13 +21935,13 @@ invalid_lambda_parameters_rule(Parser *p)
             return NULL;
         }
         D(fprintf(stderr, "%*c> invalid_lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(lambda_slash_no_default | lambda_slash_with_default) lambda_param_maybe_default* '/'"));
-        asdl_seq * _loop0_184_var;
-        void *_tmp_183_var;
+        asdl_seq * _loop0_186_var;
+        void *_tmp_185_var;
         Token * a;
         if (
-            (_tmp_183_var = _tmp_183_rule(p))  // lambda_slash_no_default | lambda_slash_with_default
+            (_tmp_185_var = _tmp_185_rule(p))  // lambda_slash_no_default | lambda_slash_with_default
             &&
-            (_loop0_184_var = _loop0_184_rule(p))  // lambda_param_maybe_default*
+            (_loop0_186_var = _loop0_186_rule(p))  // lambda_param_maybe_default*
             &&
             (a = _PyPegen_expect_token(p, 17))  // token='/'
         )
@@ -21485,7 +21965,7 @@ invalid_lambda_parameters_rule(Parser *p)
             return NULL;
         }
         D(fprintf(stderr, "%*c> invalid_lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default? lambda_param_no_default* invalid_lambda_parameters_helper lambda_param_no_default"));
-        asdl_seq * _loop0_185_var;
+        asdl_seq * _loop0_187_var;
         void *_opt_var;
         UNUSED(_opt_var); // Silence compiler warnings
         arg_ty a;
@@ -21493,7 +21973,7 @@ invalid_lambda_parameters_rule(Parser *p)
         if (
             (_opt_var = lambda_slash_no_default_rule(p), !p->error_indicator)  // lambda_slash_no_default?
             &&
-            (_loop0_185_var = _loop0_185_rule(p))  // lambda_param_no_default*
+            (_loop0_187_var = _loop0_187_rule(p))  // lambda_param_no_default*
             &&
             (invalid_lambda_parameters_helper_var = invalid_lambda_parameters_helper_rule(p))  // invalid_lambda_parameters_helper
             &&
@@ -21519,18 +21999,18 @@ invalid_lambda_parameters_rule(Parser *p)
             return NULL;
         }
         D(fprintf(stderr, "%*c> invalid_lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default* '(' ','.lambda_param+ ','? ')'"));
-        asdl_seq * _gather_187_var;
-        asdl_seq * _loop0_186_var;
+        asdl_seq * _gather_189_var;
+        asdl_seq * _loop0_188_var;
         void *_opt_var;
         UNUSED(_opt_var); // Silence compiler warnings
         Token * a;
         Token * b;
         if (
-            (_loop0_186_var = _loop0_186_rule(p))  // lambda_param_no_default*
+            (_loop0_188_var = _loop0_188_rule(p))  // lambda_param_no_default*
             &&
             (a = _PyPegen_expect_token(p, 7))  // token='('
             &&
-            (_gather_187_var = _gather_187_rule(p))  // ','.lambda_param+
+            (_gather_189_var = _gather_189_rule(p))  // ','.lambda_param+
             &&
             (_opt_var = _PyPegen_expect_token(p, 12), !p->error_indicator)  // ','?
             &&
@@ -21557,22 +22037,22 @@ invalid_lambda_parameters_rule(Parser *p)
         }
         D(fprintf(stderr, "%*c> invalid_lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "[(lambda_slash_no_default | lambda_slash_with_default)] lambda_param_maybe_default* '*' (',' | lambda_param_no_default) lambda_param_maybe_default* '/'"));
         Token * _literal;
-        asdl_seq * _loop0_190_var;
         asdl_seq * _loop0_192_var;
+        asdl_seq * _loop0_194_var;
         void *_opt_var;
         UNUSED(_opt_var); // Silence compiler warnings
-        void *_tmp_191_var;
+        void *_tmp_193_var;
         Token * a;
         if (
-            (_opt_var = _tmp_189_rule(p), !p->error_indicator)  // [(lambda_slash_no_default | lambda_slash_with_default)]
+            (_opt_var = _tmp_191_rule(p), !p->error_indicator)  // [(lambda_slash_no_default | lambda_slash_with_default)]
             &&
-            (_loop0_190_var = _loop0_190_rule(p))  // lambda_param_maybe_default*
+            (_loop0_192_var = _loop0_192_rule(p))  // lambda_param_maybe_default*
             &&
             (_literal = _PyPegen_expect_token(p, 16))  // token='*'
             &&
-            (_tmp_191_var = _tmp_191_rule(p))  // ',' | lambda_param_no_default
+            (_tmp_193_var = _tmp_193_rule(p))  // ',' | lambda_param_no_default
             &&
-            (_loop0_192_var = _loop0_192_rule(p))  // lambda_param_maybe_default*
+            (_loop0_194_var = _loop0_194_rule(p))  // lambda_param_maybe_default*
             &&
             (a = _PyPegen_expect_token(p, 17))  // token='/'
         )
@@ -21597,10 +22077,10 @@ invalid_lambda_parameters_rule(Parser *p)
         }
         D(fprintf(stderr, "%*c> invalid_lambda_parameters[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default+ '/' '*'"));
         Token * _literal;
-        asdl_seq * _loop1_193_var;
+        asdl_seq * _loop1_195_var;
         Token * a;
         if (
-            (_loop1_193_var = _loop1_193_rule(p))  // lambda_param_maybe_default+
+            (_loop1_195_var = _loop1_195_rule(p))  // lambda_param_maybe_default+
             &&
             (_literal = _PyPegen_expect_token(p, 17))  // token='/'
             &&
@@ -21672,13 +22152,13 @@ invalid_lambda_parameters_helper_rule(Parser *p)
             return NULL;
         }
         D(fprintf(stderr, "%*c> invalid_lambda_parameters_helper[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default+"));
-        asdl_seq * _loop1_194_var;
+        asdl_seq * _loop1_196_var;
         if (
-            (_loop1_194_var = _loop1_194_rule(p))  // lambda_param_with_default+
+            (_loop1_196_var = _loop1_196_rule(p))  // lambda_param_with_default+
         )
         {
             D(fprintf(stderr, "%*c+ invalid_lambda_parameters_helper[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default+"));
-            _res = _loop1_194_var;
+            _res = _loop1_196_var;
             goto done;
         }
         p->mark = _mark;
@@ -21715,11 +22195,11 @@ invalid_lambda_star_etc_rule(Parser *p)
         }
         D(fprintf(stderr, "%*c> invalid_lambda_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' (':' | ',' (':' | '**'))"));
         Token * _literal;
-        void *_tmp_195_var;
+        void *_tmp_197_var;
         if (
             (_literal = _PyPegen_expect_token(p, 16))  // token='*'
             &&
-            (_tmp_195_var = _tmp_195_rule(p))  // ':' | ',' (':' | '**')
+            (_tmp_197_var = _tmp_197_rule(p))  // ':' | ',' (':' | '**')
         )
         {
             D(fprintf(stderr, "%*c+ invalid_lambda_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' (':' | ',' (':' | '**'))"));
@@ -21772,20 +22252,20 @@ invalid_lambda_star_etc_rule(Parser *p)
         }
         D(fprintf(stderr, "%*c> invalid_lambda_star_etc[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*' (lambda_param_no_default | ',') lambda_param_maybe_default* '*' (lambda_param_no_default | ',')"));
         Token * _literal;
-        asdl_seq * _loop0_197_var;
-        void *_tmp_196_var;
+        asdl_seq * _loop0_199_var;
         void *_tmp_198_var;
+        void *_tmp_200_var;
         Token * a;
         if (
             (_literal = _PyPegen_expect_token(p, 16))  // token='*'
             &&
-            (_tmp_196_var = _tmp_196_rule(p))  // lambda_param_no_default | ','
+            (_tmp_198_var = _tmp_198_rule(p))  // lambda_param_no_default | ','
             &&
-            (_loop0_197_var = _loop0_197_rule(p))  // lambda_param_maybe_default*
+            (_loop0_199_var = _loop0_199_rule(p))  // lambda_param_maybe_default*
             &&
             (a = _PyPegen_expect_token(p, 16))  // token='*'
             &&
-            (_tmp_198_var = _tmp_198_rule(p))  // lambda_param_no_default | ','
+            (_tmp_200_var = _tmp_200_rule(p))  // lambda_param_no_default | ','
         )
         {
             D(fprintf(stderr, "%*c+ invalid_lambda_star_etc[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*' (lambda_param_no_default | ',') lambda_param_maybe_default* '*' (lambda_param_no_default | ',')"));
@@ -21904,7 +22384,7 @@ invalid_lambda_kwds_rule(Parser *p)
             &&
             (_literal_1 = _PyPegen_expect_token(p, 12))  // token=','
             &&
-            (a = (Token*)_tmp_199_rule(p))  // '*' | '**' | '/'
+            (a = (Token*)_tmp_201_rule(p))  // '*' | '**' | '/'
         )
         {
             D(fprintf(stderr, "%*c+ invalid_lambda_kwds[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**' lambda_param ',' ('*' | '**' | '/')"));
@@ -22012,7 +22492,7 @@ invalid_with_item_rule(Parser *p)
             &&
             (a = expression_rule(p))  // expression
             &&
-            _PyPegen_lookahead(1, _tmp_200_rule, p)
+            _PyPegen_lookahead(1, _tmp_202_rule, p)
         )
         {
             D(fprintf(stderr, "%*c+ invalid_with_item[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression 'as' expression &(',' | ')' | ':')"));
@@ -22293,7 +22773,7 @@ invalid_with_stmt_rule(Parser *p)
             return NULL;
         }
         D(fprintf(stderr, "%*c> invalid_with_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC? 'with' ','.(expression ['as' star_target])+ NEWLINE"));
-        asdl_seq * _gather_201_var;
+        asdl_seq * _gather_203_var;
         Token * _keyword;
         void *_opt_var;
         UNUSED(_opt_var); // Silence compiler warnings
@@ -22303,7 +22783,7 @@ invalid_with_stmt_rule(Parser *p)
             &&
             (_keyword = _PyPegen_expect_token(p, 615))  // token='with'
             &&
-            (_gather_201_var = _gather_201_rule(p))  // ','.(expression ['as' star_target])+
+            (_gather_203_var = _gather_203_rule(p))  // ','.(expression ['as' star_target])+
             &&
             (newline_var = _PyPegen_expect_token(p, NEWLINE))  // token='NEWLINE'
         )
@@ -22327,7 +22807,7 @@ invalid_with_stmt_rule(Parser *p)
             return NULL;
         }
         D(fprintf(stderr, "%*c> invalid_with_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' NEWLINE"));
-        asdl_seq * _gather_203_var;
+        asdl_seq * _gather_205_var;
         Token * _keyword;
         Token * _literal;
         Token * _literal_1;
@@ -22343,7 +22823,7 @@ invalid_with_stmt_rule(Parser *p)
             &&
             (_literal = _PyPegen_expect_token(p, 7))  // token='('
             &&
-            (_gather_203_var = _gather_203_rule(p))  // ','.(expressions ['as' star_target])+
+            (_gather_205_var = _gather_205_rule(p))  // ','.(expressions ['as' star_target])+
             &&
             (_opt_var_1 = _PyPegen_expect_token(p, 12), !p->error_indicator)  // ','?
             &&
@@ -22393,7 +22873,7 @@ invalid_with_stmt_indent_rule(Parser *p)
             return NULL;
         }
         D(fprintf(stderr, "%*c> invalid_with_stmt_indent[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC? 'with' ','.(expression ['as' star_target])+ ':' NEWLINE !INDENT"));
-        asdl_seq * _gather_205_var;
+        asdl_seq * _gather_207_var;
         Token * _literal;
         void *_opt_var;
         UNUSED(_opt_var); // Silence compiler warnings
@@ -22404,7 +22884,7 @@ invalid_with_stmt_indent_rule(Parser *p)
             &&
             (a = _PyPegen_expect_token(p, 615))  // token='with'
             &&
-            (_gather_205_var = _gather_205_rule(p))  // ','.(expression ['as' star_target])+
+            (_gather_207_var = _gather_207_rule(p))  // ','.(expression ['as' star_target])+
             &&
             (_literal = _PyPegen_expect_token(p, 11))  // token=':'
             &&
@@ -22432,7 +22912,7 @@ invalid_with_stmt_indent_rule(Parser *p)
             return NULL;
         }
         D(fprintf(stderr, "%*c> invalid_with_stmt_indent[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "ASYNC? 'with' '(' ','.(expressions ['as' star_target])+ ','? ')' ':' NEWLINE !INDENT"));
-        asdl_seq * _gather_207_var;
+        asdl_seq * _gather_209_var;
         Token * _literal;
         Token * _literal_1;
         Token * _literal_2;
@@ -22449,7 +22929,7 @@ invalid_with_stmt_indent_rule(Parser *p)
             &&
             (_literal = _PyPegen_expect_token(p, 7))  // token='('
             &&
-            (_gather_207_var = _gather_207_rule(p))  // ','.(expressions ['as' star_target])+
+            (_gather_209_var = _gather_209_rule(p))  // ','.(expressions ['as' star_target])+
             &&
             (_opt_var_1 = _PyPegen_expect_token(p, 12), !p->error_indicator)  // ','?
             &&
@@ -22547,7 +23027,7 @@ invalid_try_stmt_rule(Parser *p)
             &&
             (block_var = block_rule(p))  // block
             &&
-            _PyPegen_lookahead(0, _tmp_209_rule, p)
+            _PyPegen_lookahead(0, _tmp_211_rule, p)
         )
         {
             D(fprintf(stderr, "%*c+ invalid_try_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'try' ':' block !('except' | 'finally')"));
@@ -22572,8 +23052,8 @@ invalid_try_stmt_rule(Parser *p)
         Token * _keyword;
         Token * _literal;
         Token * _literal_1;
-        asdl_seq * _loop0_210_var;
-        asdl_seq * _loop1_211_var;
+        asdl_seq * _loop0_212_var;
+        asdl_seq * _loop1_213_var;
         void *_opt_var;
         UNUSED(_opt_var); // Silence compiler warnings
         Token * a;
@@ -22584,9 +23064,9 @@ invalid_try_stmt_rule(Parser *p)
             &&
             (_literal = _PyPegen_expect_token(p, 11))  // token=':'
             &&
-            (_loop0_210_var = _loop0_210_rule(p))  // block*
+            (_loop0_212_var = _loop0_212_rule(p))  // block*
             &&
-            (_loop1_211_var = _loop1_211_rule(p))  // except_block+
+            (_loop1_213_var = _loop1_213_rule(p))  // except_block+
             &&
             (a = _PyPegen_expect_token(p, 637))  // token='except'
             &&
@@ -22594,7 +23074,7 @@ invalid_try_stmt_rule(Parser *p)
             &&
             (expression_var = expression_rule(p))  // expression
             &&
-            (_opt_var = _tmp_212_rule(p), !p->error_indicator)  // ['as' NAME]
+            (_opt_var = _tmp_214_rule(p), !p->error_indicator)  // ['as' NAME]
             &&
             (_literal_1 = _PyPegen_expect_token(p, 11))  // token=':'
         )
@@ -22621,8 +23101,8 @@ invalid_try_stmt_rule(Parser *p)
         Token * _keyword;
         Token * _literal;
         Token * _literal_1;
-        asdl_seq * _loop0_213_var;
-        asdl_seq * _loop1_214_var;
+        asdl_seq * _loop0_215_var;
+        asdl_seq * _loop1_216_var;
         void *_opt_var;
         UNUSED(_opt_var); // Silence compiler warnings
         Token * a;
@@ -22631,13 +23111,13 @@ invalid_try_stmt_rule(Parser *p)
             &&
             (_literal = _PyPegen_expect_token(p, 11))  // token=':'
             &&
-            (_loop0_213_var = _loop0_213_rule(p))  // block*
+            (_loop0_215_var = _loop0_215_rule(p))  // block*
             &&
-            (_loop1_214_var = _loop1_214_rule(p))  // except_star_block+
+            (_loop1_216_var = _loop1_216_rule(p))  // except_star_block+
             &&
             (a = _PyPegen_expect_token(p, 637))  // token='except'
             &&
-            (_opt_var = _tmp_215_rule(p), !p->error_indicator)  // [expression ['as' NAME]]
+            (_opt_var = _tmp_217_rule(p), !p->error_indicator)  // [expression ['as' NAME]]
             &&
             (_literal_1 = _PyPegen_expect_token(p, 11))  // token=':'
         )
@@ -22705,7 +23185,7 @@ invalid_except_stmt_rule(Parser *p)
             &&
             (expressions_var = expressions_rule(p))  // expressions
             &&
-            (_opt_var_1 = _tmp_216_rule(p), !p->error_indicator)  // ['as' NAME]
+            (_opt_var_1 = _tmp_218_rule(p), !p->error_indicator)  // ['as' NAME]
             &&
             (_literal_1 = _PyPegen_expect_token(p, 11))  // token=':'
         )
@@ -22743,7 +23223,7 @@ invalid_except_stmt_rule(Parser *p)
             &&
             (expression_var = expression_rule(p))  // expression
             &&
-            (_opt_var_1 = _tmp_217_rule(p), !p->error_indicator)  // ['as' NAME]
+            (_opt_var_1 = _tmp_219_rule(p), !p->error_indicator)  // ['as' NAME]
             &&
             (newline_var = _PyPegen_expect_token(p, NEWLINE))  // token='NEWLINE'
         )
@@ -22795,14 +23275,14 @@ invalid_except_stmt_rule(Parser *p)
         }
         D(fprintf(stderr, "%*c> invalid_except_stmt[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'except' '*' (NEWLINE | ':')"));
         Token * _literal;
-        void *_tmp_218_var;
+        void *_tmp_220_var;
         Token * a;
         if (
             (a = _PyPegen_expect_token(p, 637))  // token='except'
             &&
             (_literal = _PyPegen_expect_token(p, 16))  // token='*'
             &&
-            (_tmp_218_var = _tmp_218_rule(p))  // NEWLINE | ':'
+            (_tmp_220_var = _tmp_220_rule(p))  // NEWLINE | ':'
         )
         {
             D(fprintf(stderr, "%*c+ invalid_except_stmt[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except' '*' (NEWLINE | ':')"));
@@ -22909,7 +23389,7 @@ invalid_except_stmt_indent_rule(Parser *p)
             &&
             (expression_var = expression_rule(p))  // expression
             &&
-            (_opt_var = _tmp_219_rule(p), !p->error_indicator)  // ['as' NAME]
+            (_opt_var = _tmp_221_rule(p), !p->error_indicator)  // ['as' NAME]
             &&
             (_literal = _PyPegen_expect_token(p, 11))  // token=':'
             &&
@@ -23004,7 +23484,7 @@ invalid_except_star_stmt_indent_rule(Parser *p)
             &&
             (expression_var = expression_rule(p))  // expression
             &&
-            (_opt_var = _tmp_220_rule(p), !p->error_indicator)  // ['as' NAME]
+            (_opt_var = _tmp_222_rule(p), !p->error_indicator)  // ['as' NAME]
             &&
             (_literal_1 = _PyPegen_expect_token(p, 11))  // token=':'
             &&
@@ -23373,7 +23853,7 @@ invalid_class_argument_pattern_rule(Parser *p)
         asdl_pattern_seq* a;
         asdl_seq* keyword_patterns_var;
         if (
-            (_opt_var = _tmp_221_rule(p), !p->error_indicator)  // [positional_patterns ',']
+            (_opt_var = _tmp_223_rule(p), !p->error_indicator)  // [positional_patterns ',']
             &&
             (keyword_patterns_var = keyword_patterns_rule(p))  // keyword_patterns
             &&
@@ -23867,7 +24347,7 @@ invalid_def_raw_rule(Parser *p)
             &&
             (_literal_1 = _PyPegen_expect_token(p, 8))  // token=')'
             &&
-            (_opt_var_2 = _tmp_222_rule(p), !p->error_indicator)  // ['->' expression]
+            (_opt_var_2 = _tmp_224_rule(p), !p->error_indicator)  // ['->' expression]
             &&
             (_literal_2 = _PyPegen_expect_token(p, 11))  // token=':'
             &&
@@ -23927,7 +24407,7 @@ invalid_class_def_raw_rule(Parser *p)
             &&
             (name_var = _PyPegen_name_token(p))  // NAME
             &&
-            (_opt_var = _tmp_223_rule(p), !p->error_indicator)  // ['(' arguments? ')']
+            (_opt_var = _tmp_225_rule(p), !p->error_indicator)  // ['(' arguments? ')']
             &&
             (newline_var = _PyPegen_expect_token(p, NEWLINE))  // token='NEWLINE'
         )
@@ -23962,7 +24442,7 @@ invalid_class_def_raw_rule(Parser *p)
             &&
             (name_var = _PyPegen_name_token(p))  // NAME
             &&
-            (_opt_var = _tmp_224_rule(p), !p->error_indicator)  // ['(' arguments? ')']
+            (_opt_var = _tmp_226_rule(p), !p->error_indicator)  // ['(' arguments? ')']
             &&
             (_literal = _PyPegen_expect_token(p, 11))  // token=':'
             &&
@@ -24013,11 +24493,11 @@ invalid_double_starred_kvpairs_rule(Parser *p)
             return NULL;
         }
         D(fprintf(stderr, "%*c> invalid_double_starred_kvpairs[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','.double_starred_kvpair+ ',' invalid_kvpair"));
-        asdl_seq * _gather_225_var;
+        asdl_seq * _gather_227_var;
         Token * _literal;
         void *invalid_kvpair_var;
         if (
-            (_gather_225_var = _gather_225_rule(p))  // ','.double_starred_kvpair+
+            (_gather_227_var = _gather_227_rule(p))  // ','.double_starred_kvpair+
             &&
             (_literal = _PyPegen_expect_token(p, 12))  // token=','
             &&
@@ -24025,7 +24505,7 @@ invalid_double_starred_kvpairs_rule(Parser *p)
         )
         {
             D(fprintf(stderr, "%*c+ invalid_double_starred_kvpairs[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','.double_starred_kvpair+ ',' invalid_kvpair"));
-            _res = _PyPegen_dummy_name(p, _gather_225_var, _literal, invalid_kvpair_var);
+            _res = _PyPegen_dummy_name(p, _gather_227_var, _literal, invalid_kvpair_var);
             goto done;
         }
         p->mark = _mark;
@@ -24078,7 +24558,7 @@ invalid_double_starred_kvpairs_rule(Parser *p)
             &&
             (a = _PyPegen_expect_token(p, 11))  // token=':'
             &&
-            _PyPegen_lookahead(1, _tmp_227_rule, p)
+            _PyPegen_lookahead(1, _tmp_229_rule, p)
         )
         {
             D(fprintf(stderr, "%*c+ invalid_double_starred_kvpairs[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ':' &('}' | ',')"));
@@ -24189,7 +24669,7 @@ invalid_kvpair_rule(Parser *p)
             &&
             (a = _PyPegen_expect_token(p, 11))  // token=':'
             &&
-            _PyPegen_lookahead(1, _tmp_228_rule, p)
+            _PyPegen_lookahead(1, _tmp_230_rule, p)
         )
         {
             D(fprintf(stderr, "%*c+ invalid_kvpair[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ':' &('}' | ',')"));
@@ -24407,7 +24887,7 @@ invalid_replacement_field_rule(Parser *p)
         if (
             (_literal = _PyPegen_expect_token(p, 25))  // token='{'
             &&
-            _PyPegen_lookahead(0, _tmp_229_rule, p)
+            _PyPegen_lookahead(0, _tmp_231_rule, p)
         )
         {
             D(fprintf(stderr, "%*c+ invalid_replacement_field[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' !(yield_expr | star_expressions)"));
@@ -24430,13 +24910,13 @@ invalid_replacement_field_rule(Parser *p)
         }
         D(fprintf(stderr, "%*c> invalid_replacement_field[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{' (yield_expr | star_expressions) !('=' | '!' | ':' | '}')"));
         Token * _literal;
-        void *_tmp_230_var;
+        void *_tmp_232_var;
         if (
             (_literal = _PyPegen_expect_token(p, 25))  // token='{'
             &&
-            (_tmp_230_var = _tmp_230_rule(p))  // yield_expr | star_expressions
+            (_tmp_232_var = _tmp_232_rule(p))  // yield_expr | star_expressions
             &&
-            _PyPegen_lookahead(0, _tmp_231_rule, p)
+            _PyPegen_lookahead(0, _tmp_233_rule, p)
         )
         {
             D(fprintf(stderr, "%*c+ invalid_replacement_field[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' (yield_expr | star_expressions) !('=' | '!' | ':' | '}')"));
@@ -24460,15 +24940,15 @@ invalid_replacement_field_rule(Parser *p)
         D(fprintf(stderr, "%*c> invalid_replacement_field[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{' (yield_expr | star_expressions) '=' !('!' | ':' | '}')"));
         Token * _literal;
         Token * _literal_1;
-        void *_tmp_232_var;
+        void *_tmp_234_var;
         if (
             (_literal = _PyPegen_expect_token(p, 25))  // token='{'
             &&
-            (_tmp_232_var = _tmp_232_rule(p))  // yield_expr | star_expressions
+            (_tmp_234_var = _tmp_234_rule(p))  // yield_expr | star_expressions
             &&
             (_literal_1 = _PyPegen_expect_token(p, 22))  // token='='
             &&
-            _PyPegen_lookahead(0, _tmp_233_rule, p)
+            _PyPegen_lookahead(0, _tmp_235_rule, p)
         )
         {
             D(fprintf(stderr, "%*c+ invalid_replacement_field[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' (yield_expr | star_expressions) '=' !('!' | ':' | '}')"));
@@ -24493,12 +24973,12 @@ invalid_replacement_field_rule(Parser *p)
         Token * _literal;
         void *_opt_var;
         UNUSED(_opt_var); // Silence compiler warnings
-        void *_tmp_234_var;
+        void *_tmp_236_var;
         void *invalid_conversion_character_var;
         if (
             (_literal = _PyPegen_expect_token(p, 25))  // token='{'
             &&
-            (_tmp_234_var = _tmp_234_rule(p))  // yield_expr | star_expressions
+            (_tmp_236_var = _tmp_236_rule(p))  // yield_expr | star_expressions
             &&
             (_opt_var = _PyPegen_expect_token(p, 22), !p->error_indicator)  // '='?
             &&
@@ -24506,7 +24986,7 @@ invalid_replacement_field_rule(Parser *p)
         )
         {
             D(fprintf(stderr, "%*c+ invalid_replacement_field[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' (yield_expr | star_expressions) '='? invalid_conversion_character"));
-            _res = _PyPegen_dummy_name(p, _literal, _tmp_234_var, _opt_var, invalid_conversion_character_var);
+            _res = _PyPegen_dummy_name(p, _literal, _tmp_236_var, _opt_var, invalid_conversion_character_var);
             goto done;
         }
         p->mark = _mark;
@@ -24524,17 +25004,17 @@ invalid_replacement_field_rule(Parser *p)
         UNUSED(_opt_var); // Silence compiler warnings
         void *_opt_var_1;
         UNUSED(_opt_var_1); // Silence compiler warnings
-        void *_tmp_235_var;
+        void *_tmp_237_var;
         if (
             (_literal = _PyPegen_expect_token(p, 25))  // token='{'
             &&
-            (_tmp_235_var = _tmp_235_rule(p))  // yield_expr | star_expressions
+            (_tmp_237_var = _tmp_237_rule(p))  // yield_expr | star_expressions
             &&
             (_opt_var = _PyPegen_expect_token(p, 22), !p->error_indicator)  // '='?
             &&
-            (_opt_var_1 = _tmp_236_rule(p), !p->error_indicator)  // ['!' NAME]
+            (_opt_var_1 = _tmp_238_rule(p), !p->error_indicator)  // ['!' NAME]
             &&
-            _PyPegen_lookahead(0, _tmp_237_rule, p)
+            _PyPegen_lookahead(0, _tmp_239_rule, p)
         )
         {
             D(fprintf(stderr, "%*c+ invalid_replacement_field[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' (yield_expr | star_expressions) '='? ['!' NAME] !(':' | '}')"));
@@ -24558,24 +25038,24 @@ invalid_replacement_field_rule(Parser *p)
         D(fprintf(stderr, "%*c> invalid_replacement_field[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{' (yield_expr | star_expressions) '='? ['!' NAME] ':' fstring_format_spec* !'}'"));
         Token * _literal;
         Token * _literal_1;
-        asdl_seq * _loop0_240_var;
+        asdl_seq * _loop0_242_var;
         void *_opt_var;
         UNUSED(_opt_var); // Silence compiler warnings
         void *_opt_var_1;
         UNUSED(_opt_var_1); // Silence compiler warnings
-        void *_tmp_238_var;
+        void *_tmp_240_var;
         if (
             (_literal = _PyPegen_expect_token(p, 25))  // token='{'
             &&
-            (_tmp_238_var = _tmp_238_rule(p))  // yield_expr | star_expressions
+            (_tmp_240_var = _tmp_240_rule(p))  // yield_expr | star_expressions
             &&
             (_opt_var = _PyPegen_expect_token(p, 22), !p->error_indicator)  // '='?
             &&
-            (_opt_var_1 = _tmp_239_rule(p), !p->error_indicator)  // ['!' NAME]
+            (_opt_var_1 = _tmp_241_rule(p), !p->error_indicator)  // ['!' NAME]
             &&
             (_literal_1 = _PyPegen_expect_token(p, 11))  // token=':'
             &&
-            (_loop0_240_var = _loop0_240_rule(p))  // fstring_format_spec*
+            (_loop0_242_var = _loop0_242_rule(p))  // fstring_format_spec*
             &&
             _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 26)  // token='}'
         )
@@ -24604,15 +25084,15 @@ invalid_replacement_field_rule(Parser *p)
         UNUSED(_opt_var); // Silence compiler warnings
         void *_opt_var_1;
         UNUSED(_opt_var_1); // Silence compiler warnings
-        void *_tmp_241_var;
+        void *_tmp_243_var;
         if (
             (_literal = _PyPegen_expect_token(p, 25))  // token='{'
             &&
-            (_tmp_241_var = _tmp_241_rule(p))  // yield_expr | star_expressions
+            (_tmp_243_var = _tmp_243_rule(p))  // yield_expr | star_expressions
             &&
             (_opt_var = _PyPegen_expect_token(p, 22), !p->error_indicator)  // '='?
             &&
-            (_opt_var_1 = _tmp_242_rule(p), !p->error_indicator)  // ['!' NAME]
+            (_opt_var_1 = _tmp_244_rule(p), !p->error_indicator)  // ['!' NAME]
             &&
             _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 26)  // token='}'
         )
@@ -24660,7 +25140,7 @@ invalid_conversion_character_rule(Parser *p)
         if (
             (_literal = _PyPegen_expect_token(p, 54))  // token='!'
             &&
-            _PyPegen_lookahead(1, _tmp_243_rule, p)
+            _PyPegen_lookahead(1, _tmp_245_rule, p)
         )
         {
             D(fprintf(stderr, "%*c+ invalid_conversion_character[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!' &(':' | '}')"));
@@ -25605,12 +26085,12 @@ _loop1_15_rule(Parser *p)
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop1_15[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')"));
-        void *_tmp_244_var;
+        void *_tmp_246_var;
         while (
-            (_tmp_244_var = _tmp_244_rule(p))  // star_targets '='
+            (_tmp_246_var = _tmp_246_rule(p))  // star_targets '='
         )
         {
-            _res = _tmp_244_var;
+            _res = _tmp_246_var;
             if (_n == _children_capacity) {
                 _children_capacity *= 2;
                 void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *));
@@ -26184,12 +26664,12 @@ _loop0_25_rule(Parser *p)
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop0_25[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('.' | '...')"));
-        void *_tmp_245_var;
+        void *_tmp_247_var;
         while (
-            (_tmp_245_var = _tmp_245_rule(p))  // '.' | '...'
+            (_tmp_247_var = _tmp_247_rule(p))  // '.' | '...'
         )
         {
-            _res = _tmp_245_var;
+            _res = _tmp_247_var;
             if (_n == _children_capacity) {
                 _children_capacity *= 2;
                 void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *));
@@ -26252,12 +26732,12 @@ _loop1_26_rule(Parser *p)
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop1_26[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('.' | '...')"));
-        void *_tmp_246_var;
+        void *_tmp_248_var;
         while (
-            (_tmp_246_var = _tmp_246_rule(p))  // '.' | '...'
+            (_tmp_248_var = _tmp_248_rule(p))  // '.' | '...'
         )
         {
-            _res = _tmp_246_var;
+            _res = _tmp_248_var;
             if (_n == _children_capacity) {
                 _children_capacity *= 2;
                 void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *));
@@ -26657,12 +27137,12 @@ _loop1_33_rule(Parser *p)
             return NULL;
         }
         D(fprintf(stderr, "%*c> _loop1_33[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('@' named_expression NEWLINE)"));
-        void *_tmp_247_var;
+        void *_tmp_249_var;
         while (
-            (_tmp_247_var = _tmp_247_rule(p))  // '@' named_expression NEWLINE
+            (_tmp_249_var = _tmp_249_rule(p))  // '@' named_expression NEWLINE
         )
         {
-            _res = _tmp_247_var;
+            _res = _tmp_249_var;
             if (_n == _children_capacity) {
                 _children_capacity *= 2;
                 void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *));
@@ -29511,8 +29991,127 @@ _loop0_78_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop0_78[%d-%d]: %s failed!\n", p->level, ' ',
-                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' pattern"));
+        D(fprintf(stderr, "%*c%s _loop0_78[%d-%d]: %s failed!\n", p->level, ' ',
+                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' pattern"));
+    }
+    asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena);
+    if (!_seq) {
+        PyMem_Free(_children);
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+        p->level--;
+        return NULL;
+    }
+    for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]);
+    PyMem_Free(_children);
+    p->level--;
+    return _seq;
+}
+
+// _gather_77: pattern _loop0_78
+static asdl_seq *
+_gather_77_rule(Parser *p)
+{
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
+    if (p->error_indicator) {
+        p->level--;
+        return NULL;
+    }
+    asdl_seq * _res = NULL;
+    int _mark = p->mark;
+    { // pattern _loop0_78
+        if (p->error_indicator) {
+            p->level--;
+            return NULL;
+        }
+        D(fprintf(stderr, "%*c> _gather_77[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "pattern _loop0_78"));
+        pattern_ty elem;
+        asdl_seq * seq;
+        if (
+            (elem = pattern_rule(p))  // pattern
+            &&
+            (seq = _loop0_78_rule(p))  // _loop0_78
+        )
+        {
+            D(fprintf(stderr, "%*c+ _gather_77[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "pattern _loop0_78"));
+            _res = _PyPegen_seq_insert_in_front(p, elem, seq);
+            goto done;
+        }
+        p->mark = _mark;
+        D(fprintf(stderr, "%*c%s _gather_77[%d-%d]: %s failed!\n", p->level, ' ',
+                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "pattern _loop0_78"));
+    }
+    _res = NULL;
+  done:
+    p->level--;
+    return _res;
+}
+
+// _loop0_80: ',' keyword_pattern
+static asdl_seq *
+_loop0_80_rule(Parser *p)
+{
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
+    if (p->error_indicator) {
+        p->level--;
+        return NULL;
+    }
+    void *_res = NULL;
+    int _mark = p->mark;
+    void **_children = PyMem_Malloc(sizeof(void *));
+    if (!_children) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+        p->level--;
+        return NULL;
+    }
+    Py_ssize_t _children_capacity = 1;
+    Py_ssize_t _n = 0;
+    { // ',' keyword_pattern
+        if (p->error_indicator) {
+            p->level--;
+            return NULL;
+        }
+        D(fprintf(stderr, "%*c> _loop0_80[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' keyword_pattern"));
+        Token * _literal;
+        KeyPatternPair* elem;
+        while (
+            (_literal = _PyPegen_expect_token(p, 12))  // token=','
+            &&
+            (elem = keyword_pattern_rule(p))  // keyword_pattern
+        )
+        {
+            _res = elem;
+            if (_res == NULL && PyErr_Occurred()) {
+                p->error_indicator = 1;
+                PyMem_Free(_children);
+                p->level--;
+                return NULL;
+            }
+            if (_n == _children_capacity) {
+                _children_capacity *= 2;
+                void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *));
+                if (!_new_children) {
+                    PyMem_Free(_children);
+                    p->error_indicator = 1;
+                    PyErr_NoMemory();
+                    p->level--;
+                    return NULL;
+                }
+                _children = _new_children;
+            }
+            _children[_n++] = _res;
+            _mark = p->mark;
+        }
+        p->mark = _mark;
+        D(fprintf(stderr, "%*c%s _loop0_80[%d-%d]: %s failed!\n", p->level, ' ',
+                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' keyword_pattern"));
     }
     asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena);
     if (!_seq) {
@@ -29528,9 +30127,9 @@ _loop0_78_rule(Parser *p)
     return _seq;
 }
 
-// _gather_77: pattern _loop0_78
+// _gather_79: keyword_pattern _loop0_80
 static asdl_seq *
-_gather_77_rule(Parser *p)
+_gather_79_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -29542,27 +30141,27 @@ _gather_77_rule(Parser *p)
     }
     asdl_seq * _res = NULL;
     int _mark = p->mark;
-    { // pattern _loop0_78
+    { // keyword_pattern _loop0_80
         if (p->error_indicator) {
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _gather_77[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "pattern _loop0_78"));
-        pattern_ty elem;
+        D(fprintf(stderr, "%*c> _gather_79[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "keyword_pattern _loop0_80"));
+        KeyPatternPair* elem;
         asdl_seq * seq;
         if (
-            (elem = pattern_rule(p))  // pattern
+            (elem = keyword_pattern_rule(p))  // keyword_pattern
             &&
-            (seq = _loop0_78_rule(p))  // _loop0_78
+            (seq = _loop0_80_rule(p))  // _loop0_80
         )
         {
-            D(fprintf(stderr, "%*c+ _gather_77[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "pattern _loop0_78"));
+            D(fprintf(stderr, "%*c+ _gather_79[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "keyword_pattern _loop0_80"));
             _res = _PyPegen_seq_insert_in_front(p, elem, seq);
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _gather_77[%d-%d]: %s failed!\n", p->level, ' ',
-                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "pattern _loop0_78"));
+        D(fprintf(stderr, "%*c%s _gather_79[%d-%d]: %s failed!\n", p->level, ' ',
+                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "keyword_pattern _loop0_80"));
     }
     _res = NULL;
   done:
@@ -29570,9 +30169,9 @@ _gather_77_rule(Parser *p)
     return _res;
 }
 
-// _loop0_80: ',' keyword_pattern
+// _loop0_82: ',' type_param
 static asdl_seq *
-_loop0_80_rule(Parser *p)
+_loop0_82_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -29593,18 +30192,18 @@ _loop0_80_rule(Parser *p)
     }
     Py_ssize_t _children_capacity = 1;
     Py_ssize_t _n = 0;
-    { // ',' keyword_pattern
+    { // ',' type_param
         if (p->error_indicator) {
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop0_80[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' keyword_pattern"));
+        D(fprintf(stderr, "%*c> _loop0_82[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' type_param"));
         Token * _literal;
-        KeyPatternPair* elem;
+        typeparam_ty elem;
         while (
             (_literal = _PyPegen_expect_token(p, 12))  // token=','
             &&
-            (elem = keyword_pattern_rule(p))  // keyword_pattern
+            (elem = type_param_rule(p))  // type_param
         )
         {
             _res = elem;
@@ -29630,8 +30229,8 @@ _loop0_80_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop0_80[%d-%d]: %s failed!\n", p->level, ' ',
-                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' keyword_pattern"));
+        D(fprintf(stderr, "%*c%s _loop0_82[%d-%d]: %s failed!\n", p->level, ' ',
+                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' type_param"));
     }
     asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena);
     if (!_seq) {
@@ -29647,9 +30246,9 @@ _loop0_80_rule(Parser *p)
     return _seq;
 }
 
-// _gather_79: keyword_pattern _loop0_80
+// _gather_81: type_param _loop0_82
 static asdl_seq *
-_gather_79_rule(Parser *p)
+_gather_81_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -29661,27 +30260,27 @@ _gather_79_rule(Parser *p)
     }
     asdl_seq * _res = NULL;
     int _mark = p->mark;
-    { // keyword_pattern _loop0_80
+    { // type_param _loop0_82
         if (p->error_indicator) {
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _gather_79[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "keyword_pattern _loop0_80"));
-        KeyPatternPair* elem;
+        D(fprintf(stderr, "%*c> _gather_81[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "type_param _loop0_82"));
+        typeparam_ty elem;
         asdl_seq * seq;
         if (
-            (elem = keyword_pattern_rule(p))  // keyword_pattern
+            (elem = type_param_rule(p))  // type_param
             &&
-            (seq = _loop0_80_rule(p))  // _loop0_80
+            (seq = _loop0_82_rule(p))  // _loop0_82
         )
         {
-            D(fprintf(stderr, "%*c+ _gather_79[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "keyword_pattern _loop0_80"));
+            D(fprintf(stderr, "%*c+ _gather_81[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "type_param _loop0_82"));
             _res = _PyPegen_seq_insert_in_front(p, elem, seq);
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _gather_79[%d-%d]: %s failed!\n", p->level, ' ',
-                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "keyword_pattern _loop0_80"));
+        D(fprintf(stderr, "%*c%s _gather_81[%d-%d]: %s failed!\n", p->level, ' ',
+                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "type_param _loop0_82"));
     }
     _res = NULL;
   done:
@@ -29689,9 +30288,9 @@ _gather_79_rule(Parser *p)
     return _res;
 }
 
-// _loop1_81: (',' expression)
+// _loop1_83: (',' expression)
 static asdl_seq *
-_loop1_81_rule(Parser *p)
+_loop1_83_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -29717,13 +30316,13 @@ _loop1_81_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop1_81[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' expression)"));
-        void *_tmp_248_var;
+        D(fprintf(stderr, "%*c> _loop1_83[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' expression)"));
+        void *_tmp_250_var;
         while (
-            (_tmp_248_var = _tmp_248_rule(p))  // ',' expression
+            (_tmp_250_var = _tmp_250_rule(p))  // ',' expression
         )
         {
-            _res = _tmp_248_var;
+            _res = _tmp_250_var;
             if (_n == _children_capacity) {
                 _children_capacity *= 2;
                 void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *));
@@ -29740,7 +30339,7 @@ _loop1_81_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop1_81[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop1_83[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(',' expression)"));
     }
     if (_n == 0 || p->error_indicator) {
@@ -29762,9 +30361,9 @@ _loop1_81_rule(Parser *p)
     return _seq;
 }
 
-// _loop1_82: (',' star_expression)
+// _loop1_84: (',' star_expression)
 static asdl_seq *
-_loop1_82_rule(Parser *p)
+_loop1_84_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -29790,13 +30389,13 @@ _loop1_82_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop1_82[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_expression)"));
-        void *_tmp_249_var;
+        D(fprintf(stderr, "%*c> _loop1_84[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_expression)"));
+        void *_tmp_251_var;
         while (
-            (_tmp_249_var = _tmp_249_rule(p))  // ',' star_expression
+            (_tmp_251_var = _tmp_251_rule(p))  // ',' star_expression
         )
         {
-            _res = _tmp_249_var;
+            _res = _tmp_251_var;
             if (_n == _children_capacity) {
                 _children_capacity *= 2;
                 void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *));
@@ -29813,7 +30412,7 @@ _loop1_82_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop1_82[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop1_84[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(',' star_expression)"));
     }
     if (_n == 0 || p->error_indicator) {
@@ -29835,9 +30434,9 @@ _loop1_82_rule(Parser *p)
     return _seq;
 }
 
-// _loop0_84: ',' star_named_expression
+// _loop0_86: ',' star_named_expression
 static asdl_seq *
-_loop0_84_rule(Parser *p)
+_loop0_86_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -29863,7 +30462,7 @@ _loop0_84_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop0_84[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_named_expression"));
+        D(fprintf(stderr, "%*c> _loop0_86[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_named_expression"));
         Token * _literal;
         expr_ty elem;
         while (
@@ -29895,7 +30494,7 @@ _loop0_84_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop0_84[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop0_86[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' star_named_expression"));
     }
     asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena);
@@ -29912,9 +30511,9 @@ _loop0_84_rule(Parser *p)
     return _seq;
 }
 
-// _gather_83: star_named_expression _loop0_84
+// _gather_85: star_named_expression _loop0_86
 static asdl_seq *
-_gather_83_rule(Parser *p)
+_gather_85_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -29926,27 +30525,27 @@ _gather_83_rule(Parser *p)
     }
     asdl_seq * _res = NULL;
     int _mark = p->mark;
-    { // star_named_expression _loop0_84
+    { // star_named_expression _loop0_86
         if (p->error_indicator) {
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _gather_83[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expression _loop0_84"));
+        D(fprintf(stderr, "%*c> _gather_85[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expression _loop0_86"));
         expr_ty elem;
         asdl_seq * seq;
         if (
             (elem = star_named_expression_rule(p))  // star_named_expression
             &&
-            (seq = _loop0_84_rule(p))  // _loop0_84
+            (seq = _loop0_86_rule(p))  // _loop0_86
         )
         {
-            D(fprintf(stderr, "%*c+ _gather_83[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_named_expression _loop0_84"));
+            D(fprintf(stderr, "%*c+ _gather_85[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_named_expression _loop0_86"));
             _res = _PyPegen_seq_insert_in_front(p, elem, seq);
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _gather_83[%d-%d]: %s failed!\n", p->level, ' ',
-                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_named_expression _loop0_84"));
+        D(fprintf(stderr, "%*c%s _gather_85[%d-%d]: %s failed!\n", p->level, ' ',
+                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_named_expression _loop0_86"));
     }
     _res = NULL;
   done:
@@ -29954,9 +30553,9 @@ _gather_83_rule(Parser *p)
     return _res;
 }
 
-// _loop1_85: ('or' conjunction)
+// _loop1_87: ('or' conjunction)
 static asdl_seq *
-_loop1_85_rule(Parser *p)
+_loop1_87_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -29982,13 +30581,13 @@ _loop1_85_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop1_85[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('or' conjunction)"));
-        void *_tmp_250_var;
+        D(fprintf(stderr, "%*c> _loop1_87[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('or' conjunction)"));
+        void *_tmp_252_var;
         while (
-            (_tmp_250_var = _tmp_250_rule(p))  // 'or' conjunction
+            (_tmp_252_var = _tmp_252_rule(p))  // 'or' conjunction
         )
         {
-            _res = _tmp_250_var;
+            _res = _tmp_252_var;
             if (_n == _children_capacity) {
                 _children_capacity *= 2;
                 void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *));
@@ -30005,7 +30604,7 @@ _loop1_85_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop1_85[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop1_87[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "('or' conjunction)"));
     }
     if (_n == 0 || p->error_indicator) {
@@ -30027,9 +30626,9 @@ _loop1_85_rule(Parser *p)
     return _seq;
 }
 
-// _loop1_86: ('and' inversion)
+// _loop1_88: ('and' inversion)
 static asdl_seq *
-_loop1_86_rule(Parser *p)
+_loop1_88_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -30055,13 +30654,13 @@ _loop1_86_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop1_86[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('and' inversion)"));
-        void *_tmp_251_var;
+        D(fprintf(stderr, "%*c> _loop1_88[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('and' inversion)"));
+        void *_tmp_253_var;
         while (
-            (_tmp_251_var = _tmp_251_rule(p))  // 'and' inversion
+            (_tmp_253_var = _tmp_253_rule(p))  // 'and' inversion
         )
         {
-            _res = _tmp_251_var;
+            _res = _tmp_253_var;
             if (_n == _children_capacity) {
                 _children_capacity *= 2;
                 void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *));
@@ -30078,7 +30677,7 @@ _loop1_86_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop1_86[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop1_88[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "('and' inversion)"));
     }
     if (_n == 0 || p->error_indicator) {
@@ -30100,9 +30699,9 @@ _loop1_86_rule(Parser *p)
     return _seq;
 }
 
-// _loop1_87: compare_op_bitwise_or_pair
+// _loop1_89: compare_op_bitwise_or_pair
 static asdl_seq *
-_loop1_87_rule(Parser *p)
+_loop1_89_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -30128,7 +30727,7 @@ _loop1_87_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop1_87[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "compare_op_bitwise_or_pair"));
+        D(fprintf(stderr, "%*c> _loop1_89[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "compare_op_bitwise_or_pair"));
         CmpopExprPair* compare_op_bitwise_or_pair_var;
         while (
             (compare_op_bitwise_or_pair_var = compare_op_bitwise_or_pair_rule(p))  // compare_op_bitwise_or_pair
@@ -30151,7 +30750,7 @@ _loop1_87_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop1_87[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop1_89[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "compare_op_bitwise_or_pair"));
     }
     if (_n == 0 || p->error_indicator) {
@@ -30173,9 +30772,9 @@ _loop1_87_rule(Parser *p)
     return _seq;
 }
 
-// _tmp_88: '!='
+// _tmp_90: '!='
 static void *
-_tmp_88_rule(Parser *p)
+_tmp_90_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -30192,13 +30791,13 @@ _tmp_88_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_88[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!='"));
+        D(fprintf(stderr, "%*c> _tmp_90[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!='"));
         Token * tok;
         if (
             (tok = _PyPegen_expect_token(p, 28))  // token='!='
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_88[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!='"));
+            D(fprintf(stderr, "%*c+ _tmp_90[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!='"));
             _res = _PyPegen_check_barry_as_flufl ( p , tok ) ? NULL : tok;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
@@ -30208,7 +30807,7 @@ _tmp_88_rule(Parser *p)
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_88[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_90[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'!='"));
     }
     _res = NULL;
@@ -30217,9 +30816,9 @@ _tmp_88_rule(Parser *p)
     return _res;
 }
 
-// _loop0_90: ',' (slice | starred_expression)
+// _loop0_92: ',' (slice | starred_expression)
 static asdl_seq *
-_loop0_90_rule(Parser *p)
+_loop0_92_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -30245,13 +30844,13 @@ _loop0_90_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop0_90[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (slice | starred_expression)"));
+        D(fprintf(stderr, "%*c> _loop0_92[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (slice | starred_expression)"));
         Token * _literal;
         void *elem;
         while (
             (_literal = _PyPegen_expect_token(p, 12))  // token=','
             &&
-            (elem = _tmp_252_rule(p))  // slice | starred_expression
+            (elem = _tmp_254_rule(p))  // slice | starred_expression
         )
         {
             _res = elem;
@@ -30277,7 +30876,7 @@ _loop0_90_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop0_90[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop0_92[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (slice | starred_expression)"));
     }
     asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena);
@@ -30294,9 +30893,9 @@ _loop0_90_rule(Parser *p)
     return _seq;
 }
 
-// _gather_89: (slice | starred_expression) _loop0_90
+// _gather_91: (slice | starred_expression) _loop0_92
 static asdl_seq *
-_gather_89_rule(Parser *p)
+_gather_91_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -30308,27 +30907,27 @@ _gather_89_rule(Parser *p)
     }
     asdl_seq * _res = NULL;
     int _mark = p->mark;
-    { // (slice | starred_expression) _loop0_90
+    { // (slice | starred_expression) _loop0_92
         if (p->error_indicator) {
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _gather_89[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(slice | starred_expression) _loop0_90"));
+        D(fprintf(stderr, "%*c> _gather_91[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(slice | starred_expression) _loop0_92"));
         void *elem;
         asdl_seq * seq;
         if (
-            (elem = _tmp_252_rule(p))  // slice | starred_expression
+            (elem = _tmp_254_rule(p))  // slice | starred_expression
             &&
-            (seq = _loop0_90_rule(p))  // _loop0_90
+            (seq = _loop0_92_rule(p))  // _loop0_92
         )
         {
-            D(fprintf(stderr, "%*c+ _gather_89[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(slice | starred_expression) _loop0_90"));
+            D(fprintf(stderr, "%*c+ _gather_91[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(slice | starred_expression) _loop0_92"));
             _res = _PyPegen_seq_insert_in_front(p, elem, seq);
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _gather_89[%d-%d]: %s failed!\n", p->level, ' ',
-                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(slice | starred_expression) _loop0_90"));
+        D(fprintf(stderr, "%*c%s _gather_91[%d-%d]: %s failed!\n", p->level, ' ',
+                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(slice | starred_expression) _loop0_92"));
     }
     _res = NULL;
   done:
@@ -30336,9 +30935,9 @@ _gather_89_rule(Parser *p)
     return _res;
 }
 
-// _tmp_91: ':' expression?
+// _tmp_93: ':' expression?
 static void *
-_tmp_91_rule(Parser *p)
+_tmp_93_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -30355,7 +30954,7 @@ _tmp_91_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_91[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':' expression?"));
+        D(fprintf(stderr, "%*c> _tmp_93[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':' expression?"));
         Token * _literal;
         void *d;
         if (
@@ -30364,7 +30963,7 @@ _tmp_91_rule(Parser *p)
             (d = expression_rule(p), !p->error_indicator)  // expression?
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_91[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':' expression?"));
+            D(fprintf(stderr, "%*c+ _tmp_93[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':' expression?"));
             _res = d;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
@@ -30374,7 +30973,7 @@ _tmp_91_rule(Parser *p)
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_91[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_93[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':' expression?"));
     }
     _res = NULL;
@@ -30383,9 +30982,9 @@ _tmp_91_rule(Parser *p)
     return _res;
 }
 
-// _tmp_92: STRING | FSTRING_START
+// _tmp_94: STRING | FSTRING_START
 static void *
-_tmp_92_rule(Parser *p)
+_tmp_94_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -30402,18 +31001,18 @@ _tmp_92_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_92[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "STRING"));
+        D(fprintf(stderr, "%*c> _tmp_94[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "STRING"));
         expr_ty string_var;
         if (
             (string_var = _PyPegen_string_token(p))  // STRING
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_92[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "STRING"));
+            D(fprintf(stderr, "%*c+ _tmp_94[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "STRING"));
             _res = string_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_92[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_94[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "STRING"));
     }
     { // FSTRING_START
@@ -30421,18 +31020,18 @@ _tmp_92_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_92[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "FSTRING_START"));
+        D(fprintf(stderr, "%*c> _tmp_94[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "FSTRING_START"));
         Token * fstring_start_var;
         if (
             (fstring_start_var = _PyPegen_expect_token(p, FSTRING_START))  // token='FSTRING_START'
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_92[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "FSTRING_START"));
+            D(fprintf(stderr, "%*c+ _tmp_94[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "FSTRING_START"));
             _res = fstring_start_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_92[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_94[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "FSTRING_START"));
     }
     _res = NULL;
@@ -30441,9 +31040,9 @@ _tmp_92_rule(Parser *p)
     return _res;
 }
 
-// _tmp_93: tuple | group | genexp
+// _tmp_95: tuple | group | genexp
 static void *
-_tmp_93_rule(Parser *p)
+_tmp_95_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -30460,18 +31059,18 @@ _tmp_93_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_93[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "tuple"));
+        D(fprintf(stderr, "%*c> _tmp_95[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "tuple"));
         expr_ty tuple_var;
         if (
             (tuple_var = tuple_rule(p))  // tuple
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_93[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "tuple"));
+            D(fprintf(stderr, "%*c+ _tmp_95[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "tuple"));
             _res = tuple_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_93[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_95[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "tuple"));
     }
     { // group
@@ -30479,18 +31078,18 @@ _tmp_93_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_93[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "group"));
+        D(fprintf(stderr, "%*c> _tmp_95[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "group"));
         expr_ty group_var;
         if (
             (group_var = group_rule(p))  // group
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_93[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "group"));
+            D(fprintf(stderr, "%*c+ _tmp_95[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "group"));
             _res = group_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_93[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_95[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "group"));
     }
     { // genexp
@@ -30498,18 +31097,18 @@ _tmp_93_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_93[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "genexp"));
+        D(fprintf(stderr, "%*c> _tmp_95[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "genexp"));
         expr_ty genexp_var;
         if (
             (genexp_var = genexp_rule(p))  // genexp
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_93[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "genexp"));
+            D(fprintf(stderr, "%*c+ _tmp_95[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "genexp"));
             _res = genexp_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_93[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_95[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "genexp"));
     }
     _res = NULL;
@@ -30518,9 +31117,9 @@ _tmp_93_rule(Parser *p)
     return _res;
 }
 
-// _tmp_94: list | listcomp
+// _tmp_96: list | listcomp
 static void *
-_tmp_94_rule(Parser *p)
+_tmp_96_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -30537,18 +31136,18 @@ _tmp_94_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_94[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "list"));
+        D(fprintf(stderr, "%*c> _tmp_96[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "list"));
         expr_ty list_var;
         if (
             (list_var = list_rule(p))  // list
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_94[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "list"));
+            D(fprintf(stderr, "%*c+ _tmp_96[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "list"));
             _res = list_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_94[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_96[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "list"));
     }
     { // listcomp
@@ -30556,18 +31155,18 @@ _tmp_94_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_94[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "listcomp"));
+        D(fprintf(stderr, "%*c> _tmp_96[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "listcomp"));
         expr_ty listcomp_var;
         if (
             (listcomp_var = listcomp_rule(p))  // listcomp
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_94[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "listcomp"));
+            D(fprintf(stderr, "%*c+ _tmp_96[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "listcomp"));
             _res = listcomp_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_94[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_96[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "listcomp"));
     }
     _res = NULL;
@@ -30576,9 +31175,9 @@ _tmp_94_rule(Parser *p)
     return _res;
 }
 
-// _tmp_95: dict | set | dictcomp | setcomp
+// _tmp_97: dict | set | dictcomp | setcomp
 static void *
-_tmp_95_rule(Parser *p)
+_tmp_97_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -30595,18 +31194,18 @@ _tmp_95_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_95[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "dict"));
+        D(fprintf(stderr, "%*c> _tmp_97[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "dict"));
         expr_ty dict_var;
         if (
             (dict_var = dict_rule(p))  // dict
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_95[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "dict"));
+            D(fprintf(stderr, "%*c+ _tmp_97[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "dict"));
             _res = dict_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_95[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_97[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "dict"));
     }
     { // set
@@ -30614,18 +31213,18 @@ _tmp_95_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_95[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "set"));
+        D(fprintf(stderr, "%*c> _tmp_97[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "set"));
         expr_ty set_var;
         if (
             (set_var = set_rule(p))  // set
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_95[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "set"));
+            D(fprintf(stderr, "%*c+ _tmp_97[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "set"));
             _res = set_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_95[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_97[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "set"));
     }
     { // dictcomp
@@ -30633,18 +31232,18 @@ _tmp_95_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_95[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "dictcomp"));
+        D(fprintf(stderr, "%*c> _tmp_97[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "dictcomp"));
         expr_ty dictcomp_var;
         if (
             (dictcomp_var = dictcomp_rule(p))  // dictcomp
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_95[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "dictcomp"));
+            D(fprintf(stderr, "%*c+ _tmp_97[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "dictcomp"));
             _res = dictcomp_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_95[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_97[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "dictcomp"));
     }
     { // setcomp
@@ -30652,18 +31251,18 @@ _tmp_95_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_95[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "setcomp"));
+        D(fprintf(stderr, "%*c> _tmp_97[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "setcomp"));
         expr_ty setcomp_var;
         if (
             (setcomp_var = setcomp_rule(p))  // setcomp
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_95[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "setcomp"));
+            D(fprintf(stderr, "%*c+ _tmp_97[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "setcomp"));
             _res = setcomp_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_95[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_97[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "setcomp"));
     }
     _res = NULL;
@@ -30672,9 +31271,9 @@ _tmp_95_rule(Parser *p)
     return _res;
 }
 
-// _tmp_96: yield_expr | named_expression
+// _tmp_98: yield_expr | named_expression
 static void *
-_tmp_96_rule(Parser *p)
+_tmp_98_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -30691,18 +31290,18 @@ _tmp_96_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_96[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr"));
+        D(fprintf(stderr, "%*c> _tmp_98[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr"));
         expr_ty yield_expr_var;
         if (
             (yield_expr_var = yield_expr_rule(p))  // yield_expr
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_96[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr"));
+            D(fprintf(stderr, "%*c+ _tmp_98[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr"));
             _res = yield_expr_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_96[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_98[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr"));
     }
     { // named_expression
@@ -30710,18 +31309,18 @@ _tmp_96_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_96[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "named_expression"));
+        D(fprintf(stderr, "%*c> _tmp_98[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "named_expression"));
         expr_ty named_expression_var;
         if (
             (named_expression_var = named_expression_rule(p))  // named_expression
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_96[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "named_expression"));
+            D(fprintf(stderr, "%*c+ _tmp_98[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "named_expression"));
             _res = named_expression_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_96[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_98[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "named_expression"));
     }
     _res = NULL;
@@ -30730,9 +31329,9 @@ _tmp_96_rule(Parser *p)
     return _res;
 }
 
-// _loop0_97: lambda_param_no_default
+// _loop0_99: lambda_param_no_default
 static asdl_seq *
-_loop0_97_rule(Parser *p)
+_loop0_99_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -30758,7 +31357,7 @@ _loop0_97_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop0_97[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default"));
+        D(fprintf(stderr, "%*c> _loop0_99[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default"));
         arg_ty lambda_param_no_default_var;
         while (
             (lambda_param_no_default_var = lambda_param_no_default_rule(p))  // lambda_param_no_default
@@ -30781,7 +31380,7 @@ _loop0_97_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop0_97[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop0_99[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default"));
     }
     asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena);
@@ -30798,9 +31397,9 @@ _loop0_97_rule(Parser *p)
     return _seq;
 }
 
-// _loop0_98: lambda_param_with_default
+// _loop0_100: lambda_param_with_default
 static asdl_seq *
-_loop0_98_rule(Parser *p)
+_loop0_100_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -30826,7 +31425,7 @@ _loop0_98_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop0_98[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default"));
+        D(fprintf(stderr, "%*c> _loop0_100[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default"));
         NameDefaultPair* lambda_param_with_default_var;
         while (
             (lambda_param_with_default_var = lambda_param_with_default_rule(p))  // lambda_param_with_default
@@ -30849,7 +31448,7 @@ _loop0_98_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop0_98[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop0_100[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default"));
     }
     asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena);
@@ -30866,9 +31465,9 @@ _loop0_98_rule(Parser *p)
     return _seq;
 }
 
-// _loop0_99: lambda_param_with_default
+// _loop0_101: lambda_param_with_default
 static asdl_seq *
-_loop0_99_rule(Parser *p)
+_loop0_101_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -30894,7 +31493,7 @@ _loop0_99_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop0_99[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default"));
+        D(fprintf(stderr, "%*c> _loop0_101[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default"));
         NameDefaultPair* lambda_param_with_default_var;
         while (
             (lambda_param_with_default_var = lambda_param_with_default_rule(p))  // lambda_param_with_default
@@ -30917,7 +31516,7 @@ _loop0_99_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop0_99[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop0_101[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default"));
     }
     asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena);
@@ -30934,9 +31533,9 @@ _loop0_99_rule(Parser *p)
     return _seq;
 }
 
-// _loop1_100: lambda_param_no_default
+// _loop1_102: lambda_param_no_default
 static asdl_seq *
-_loop1_100_rule(Parser *p)
+_loop1_102_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -30962,7 +31561,7 @@ _loop1_100_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop1_100[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default"));
+        D(fprintf(stderr, "%*c> _loop1_102[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default"));
         arg_ty lambda_param_no_default_var;
         while (
             (lambda_param_no_default_var = lambda_param_no_default_rule(p))  // lambda_param_no_default
@@ -30985,7 +31584,7 @@ _loop1_100_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop1_100[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop1_102[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default"));
     }
     if (_n == 0 || p->error_indicator) {
@@ -31007,9 +31606,9 @@ _loop1_100_rule(Parser *p)
     return _seq;
 }
 
-// _loop0_101: lambda_param_with_default
+// _loop0_103: lambda_param_with_default
 static asdl_seq *
-_loop0_101_rule(Parser *p)
+_loop0_103_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -31035,7 +31634,7 @@ _loop0_101_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop0_101[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default"));
+        D(fprintf(stderr, "%*c> _loop0_103[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default"));
         NameDefaultPair* lambda_param_with_default_var;
         while (
             (lambda_param_with_default_var = lambda_param_with_default_rule(p))  // lambda_param_with_default
@@ -31058,7 +31657,7 @@ _loop0_101_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop0_101[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop0_103[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default"));
     }
     asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena);
@@ -31075,9 +31674,9 @@ _loop0_101_rule(Parser *p)
     return _seq;
 }
 
-// _loop1_102: lambda_param_with_default
+// _loop1_104: lambda_param_with_default
 static asdl_seq *
-_loop1_102_rule(Parser *p)
+_loop1_104_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -31103,7 +31702,7 @@ _loop1_102_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop1_102[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default"));
+        D(fprintf(stderr, "%*c> _loop1_104[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default"));
         NameDefaultPair* lambda_param_with_default_var;
         while (
             (lambda_param_with_default_var = lambda_param_with_default_rule(p))  // lambda_param_with_default
@@ -31126,7 +31725,7 @@ _loop1_102_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop1_102[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop1_104[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default"));
     }
     if (_n == 0 || p->error_indicator) {
@@ -31148,9 +31747,9 @@ _loop1_102_rule(Parser *p)
     return _seq;
 }
 
-// _loop1_103: lambda_param_no_default
+// _loop1_105: lambda_param_no_default
 static asdl_seq *
-_loop1_103_rule(Parser *p)
+_loop1_105_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -31176,7 +31775,7 @@ _loop1_103_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop1_103[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default"));
+        D(fprintf(stderr, "%*c> _loop1_105[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default"));
         arg_ty lambda_param_no_default_var;
         while (
             (lambda_param_no_default_var = lambda_param_no_default_rule(p))  // lambda_param_no_default
@@ -31199,7 +31798,7 @@ _loop1_103_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop1_103[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop1_105[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default"));
     }
     if (_n == 0 || p->error_indicator) {
@@ -31221,9 +31820,9 @@ _loop1_103_rule(Parser *p)
     return _seq;
 }
 
-// _loop1_104: lambda_param_no_default
+// _loop1_106: lambda_param_no_default
 static asdl_seq *
-_loop1_104_rule(Parser *p)
+_loop1_106_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -31249,7 +31848,7 @@ _loop1_104_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop1_104[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default"));
+        D(fprintf(stderr, "%*c> _loop1_106[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default"));
         arg_ty lambda_param_no_default_var;
         while (
             (lambda_param_no_default_var = lambda_param_no_default_rule(p))  // lambda_param_no_default
@@ -31272,7 +31871,7 @@ _loop1_104_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop1_104[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop1_106[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default"));
     }
     if (_n == 0 || p->error_indicator) {
@@ -31294,9 +31893,9 @@ _loop1_104_rule(Parser *p)
     return _seq;
 }
 
-// _loop0_105: lambda_param_no_default
+// _loop0_107: lambda_param_no_default
 static asdl_seq *
-_loop0_105_rule(Parser *p)
+_loop0_107_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -31322,7 +31921,7 @@ _loop0_105_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop0_105[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default"));
+        D(fprintf(stderr, "%*c> _loop0_107[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default"));
         arg_ty lambda_param_no_default_var;
         while (
             (lambda_param_no_default_var = lambda_param_no_default_rule(p))  // lambda_param_no_default
@@ -31345,7 +31944,7 @@ _loop0_105_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop0_105[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop0_107[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default"));
     }
     asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena);
@@ -31362,9 +31961,9 @@ _loop0_105_rule(Parser *p)
     return _seq;
 }
 
-// _loop1_106: lambda_param_with_default
+// _loop1_108: lambda_param_with_default
 static asdl_seq *
-_loop1_106_rule(Parser *p)
+_loop1_108_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -31390,7 +31989,7 @@ _loop1_106_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop1_106[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default"));
+        D(fprintf(stderr, "%*c> _loop1_108[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default"));
         NameDefaultPair* lambda_param_with_default_var;
         while (
             (lambda_param_with_default_var = lambda_param_with_default_rule(p))  // lambda_param_with_default
@@ -31413,7 +32012,7 @@ _loop1_106_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop1_106[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop1_108[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default"));
     }
     if (_n == 0 || p->error_indicator) {
@@ -31435,9 +32034,9 @@ _loop1_106_rule(Parser *p)
     return _seq;
 }
 
-// _loop0_107: lambda_param_no_default
+// _loop0_109: lambda_param_no_default
 static asdl_seq *
-_loop0_107_rule(Parser *p)
+_loop0_109_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -31463,7 +32062,7 @@ _loop0_107_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop0_107[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default"));
+        D(fprintf(stderr, "%*c> _loop0_109[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default"));
         arg_ty lambda_param_no_default_var;
         while (
             (lambda_param_no_default_var = lambda_param_no_default_rule(p))  // lambda_param_no_default
@@ -31486,7 +32085,7 @@ _loop0_107_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop0_107[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop0_109[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default"));
     }
     asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena);
@@ -31503,9 +32102,9 @@ _loop0_107_rule(Parser *p)
     return _seq;
 }
 
-// _loop1_108: lambda_param_with_default
+// _loop1_110: lambda_param_with_default
 static asdl_seq *
-_loop1_108_rule(Parser *p)
+_loop1_110_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -31531,7 +32130,7 @@ _loop1_108_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop1_108[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default"));
+        D(fprintf(stderr, "%*c> _loop1_110[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default"));
         NameDefaultPair* lambda_param_with_default_var;
         while (
             (lambda_param_with_default_var = lambda_param_with_default_rule(p))  // lambda_param_with_default
@@ -31554,7 +32153,7 @@ _loop1_108_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop1_108[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop1_110[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default"));
     }
     if (_n == 0 || p->error_indicator) {
@@ -31576,9 +32175,9 @@ _loop1_108_rule(Parser *p)
     return _seq;
 }
 
-// _loop0_109: lambda_param_maybe_default
+// _loop0_111: lambda_param_maybe_default
 static asdl_seq *
-_loop0_109_rule(Parser *p)
+_loop0_111_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -31604,7 +32203,7 @@ _loop0_109_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop0_109[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default"));
+        D(fprintf(stderr, "%*c> _loop0_111[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default"));
         NameDefaultPair* lambda_param_maybe_default_var;
         while (
             (lambda_param_maybe_default_var = lambda_param_maybe_default_rule(p))  // lambda_param_maybe_default
@@ -31627,7 +32226,7 @@ _loop0_109_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop0_109[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop0_111[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default"));
     }
     asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena);
@@ -31644,9 +32243,9 @@ _loop0_109_rule(Parser *p)
     return _seq;
 }
 
-// _loop1_110: lambda_param_maybe_default
+// _loop1_112: lambda_param_maybe_default
 static asdl_seq *
-_loop1_110_rule(Parser *p)
+_loop1_112_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -31672,7 +32271,7 @@ _loop1_110_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop1_110[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default"));
+        D(fprintf(stderr, "%*c> _loop1_112[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default"));
         NameDefaultPair* lambda_param_maybe_default_var;
         while (
             (lambda_param_maybe_default_var = lambda_param_maybe_default_rule(p))  // lambda_param_maybe_default
@@ -31695,7 +32294,7 @@ _loop1_110_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop1_110[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop1_112[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default"));
     }
     if (_n == 0 || p->error_indicator) {
@@ -31717,9 +32316,9 @@ _loop1_110_rule(Parser *p)
     return _seq;
 }
 
-// _tmp_111: yield_expr | star_expressions
+// _tmp_113: yield_expr | star_expressions
 static void *
-_tmp_111_rule(Parser *p)
+_tmp_113_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -31736,18 +32335,18 @@ _tmp_111_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_111[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr"));
+        D(fprintf(stderr, "%*c> _tmp_113[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr"));
         expr_ty yield_expr_var;
         if (
             (yield_expr_var = yield_expr_rule(p))  // yield_expr
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_111[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr"));
+            D(fprintf(stderr, "%*c+ _tmp_113[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr"));
             _res = yield_expr_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_111[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_113[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr"));
     }
     { // star_expressions
@@ -31755,18 +32354,18 @@ _tmp_111_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_111[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions"));
+        D(fprintf(stderr, "%*c> _tmp_113[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions"));
         expr_ty star_expressions_var;
         if (
             (star_expressions_var = star_expressions_rule(p))  // star_expressions
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_111[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions"));
+            D(fprintf(stderr, "%*c+ _tmp_113[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions"));
             _res = star_expressions_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_111[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_113[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions"));
     }
     _res = NULL;
@@ -31775,9 +32374,9 @@ _tmp_111_rule(Parser *p)
     return _res;
 }
 
-// _loop0_112: fstring_format_spec
+// _loop0_114: fstring_format_spec
 static asdl_seq *
-_loop0_112_rule(Parser *p)
+_loop0_114_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -31803,7 +32402,7 @@ _loop0_112_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop0_112[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "fstring_format_spec"));
+        D(fprintf(stderr, "%*c> _loop0_114[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "fstring_format_spec"));
         expr_ty fstring_format_spec_var;
         while (
             (fstring_format_spec_var = fstring_format_spec_rule(p))  // fstring_format_spec
@@ -31826,7 +32425,7 @@ _loop0_112_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop0_112[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop0_114[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "fstring_format_spec"));
     }
     asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena);
@@ -31843,9 +32442,9 @@ _loop0_112_rule(Parser *p)
     return _seq;
 }
 
-// _loop1_113: (fstring | string)
+// _loop1_115: (fstring | string)
 static asdl_seq *
-_loop1_113_rule(Parser *p)
+_loop1_115_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -31871,13 +32470,13 @@ _loop1_113_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop1_113[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(fstring | string)"));
-        void *_tmp_253_var;
+        D(fprintf(stderr, "%*c> _loop1_115[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(fstring | string)"));
+        void *_tmp_255_var;
         while (
-            (_tmp_253_var = _tmp_253_rule(p))  // fstring | string
+            (_tmp_255_var = _tmp_255_rule(p))  // fstring | string
         )
         {
-            _res = _tmp_253_var;
+            _res = _tmp_255_var;
             if (_n == _children_capacity) {
                 _children_capacity *= 2;
                 void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *));
@@ -31894,7 +32493,7 @@ _loop1_113_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop1_113[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop1_115[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(fstring | string)"));
     }
     if (_n == 0 || p->error_indicator) {
@@ -31916,9 +32515,9 @@ _loop1_113_rule(Parser *p)
     return _seq;
 }
 
-// _tmp_114: star_named_expression ',' star_named_expressions?
+// _tmp_116: star_named_expression ',' star_named_expressions?
 static void *
-_tmp_114_rule(Parser *p)
+_tmp_116_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -31935,7 +32534,7 @@ _tmp_114_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_114[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expression ',' star_named_expressions?"));
+        D(fprintf(stderr, "%*c> _tmp_116[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expression ',' star_named_expressions?"));
         Token * _literal;
         expr_ty y;
         void *z;
@@ -31947,7 +32546,7 @@ _tmp_114_rule(Parser *p)
             (z = star_named_expressions_rule(p), !p->error_indicator)  // star_named_expressions?
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_114[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_named_expression ',' star_named_expressions?"));
+            D(fprintf(stderr, "%*c+ _tmp_116[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_named_expression ',' star_named_expressions?"));
             _res = _PyPegen_seq_insert_in_front ( p , y , z );
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
@@ -31957,7 +32556,7 @@ _tmp_114_rule(Parser *p)
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_114[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_116[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_named_expression ',' star_named_expressions?"));
     }
     _res = NULL;
@@ -31966,9 +32565,9 @@ _tmp_114_rule(Parser *p)
     return _res;
 }
 
-// _loop0_116: ',' double_starred_kvpair
+// _loop0_118: ',' double_starred_kvpair
 static asdl_seq *
-_loop0_116_rule(Parser *p)
+_loop0_118_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -31994,7 +32593,7 @@ _loop0_116_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop0_116[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' double_starred_kvpair"));
+        D(fprintf(stderr, "%*c> _loop0_118[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' double_starred_kvpair"));
         Token * _literal;
         KeyValuePair* elem;
         while (
@@ -32026,7 +32625,7 @@ _loop0_116_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop0_116[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop0_118[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' double_starred_kvpair"));
     }
     asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena);
@@ -32043,9 +32642,9 @@ _loop0_116_rule(Parser *p)
     return _seq;
 }
 
-// _gather_115: double_starred_kvpair _loop0_116
+// _gather_117: double_starred_kvpair _loop0_118
 static asdl_seq *
-_gather_115_rule(Parser *p)
+_gather_117_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -32057,27 +32656,27 @@ _gather_115_rule(Parser *p)
     }
     asdl_seq * _res = NULL;
     int _mark = p->mark;
-    { // double_starred_kvpair _loop0_116
+    { // double_starred_kvpair _loop0_118
         if (p->error_indicator) {
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _gather_115[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_116"));
+        D(fprintf(stderr, "%*c> _gather_117[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_118"));
         KeyValuePair* elem;
         asdl_seq * seq;
         if (
             (elem = double_starred_kvpair_rule(p))  // double_starred_kvpair
             &&
-            (seq = _loop0_116_rule(p))  // _loop0_116
+            (seq = _loop0_118_rule(p))  // _loop0_118
         )
         {
-            D(fprintf(stderr, "%*c+ _gather_115[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_116"));
+            D(fprintf(stderr, "%*c+ _gather_117[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_118"));
             _res = _PyPegen_seq_insert_in_front(p, elem, seq);
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _gather_115[%d-%d]: %s failed!\n", p->level, ' ',
-                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "double_starred_kvpair _loop0_116"));
+        D(fprintf(stderr, "%*c%s _gather_117[%d-%d]: %s failed!\n", p->level, ' ',
+                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "double_starred_kvpair _loop0_118"));
     }
     _res = NULL;
   done:
@@ -32085,9 +32684,9 @@ _gather_115_rule(Parser *p)
     return _res;
 }
 
-// _loop1_117: for_if_clause
+// _loop1_119: for_if_clause
 static asdl_seq *
-_loop1_117_rule(Parser *p)
+_loop1_119_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -32113,7 +32712,7 @@ _loop1_117_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop1_117[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "for_if_clause"));
+        D(fprintf(stderr, "%*c> _loop1_119[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "for_if_clause"));
         comprehension_ty for_if_clause_var;
         while (
             (for_if_clause_var = for_if_clause_rule(p))  // for_if_clause
@@ -32136,7 +32735,7 @@ _loop1_117_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop1_117[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop1_119[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "for_if_clause"));
     }
     if (_n == 0 || p->error_indicator) {
@@ -32158,9 +32757,9 @@ _loop1_117_rule(Parser *p)
     return _seq;
 }
 
-// _loop0_118: ('if' disjunction)
+// _loop0_120: ('if' disjunction)
 static asdl_seq *
-_loop0_118_rule(Parser *p)
+_loop0_120_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -32186,13 +32785,13 @@ _loop0_118_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop0_118[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('if' disjunction)"));
-        void *_tmp_254_var;
+        D(fprintf(stderr, "%*c> _loop0_120[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('if' disjunction)"));
+        void *_tmp_256_var;
         while (
-            (_tmp_254_var = _tmp_254_rule(p))  // 'if' disjunction
+            (_tmp_256_var = _tmp_256_rule(p))  // 'if' disjunction
         )
         {
-            _res = _tmp_254_var;
+            _res = _tmp_256_var;
             if (_n == _children_capacity) {
                 _children_capacity *= 2;
                 void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *));
@@ -32209,7 +32808,7 @@ _loop0_118_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop0_118[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop0_120[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "('if' disjunction)"));
     }
     asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena);
@@ -32226,9 +32825,9 @@ _loop0_118_rule(Parser *p)
     return _seq;
 }
 
-// _loop0_119: ('if' disjunction)
+// _loop0_121: ('if' disjunction)
 static asdl_seq *
-_loop0_119_rule(Parser *p)
+_loop0_121_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -32254,13 +32853,13 @@ _loop0_119_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop0_119[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('if' disjunction)"));
-        void *_tmp_255_var;
+        D(fprintf(stderr, "%*c> _loop0_121[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "('if' disjunction)"));
+        void *_tmp_257_var;
         while (
-            (_tmp_255_var = _tmp_255_rule(p))  // 'if' disjunction
+            (_tmp_257_var = _tmp_257_rule(p))  // 'if' disjunction
         )
         {
-            _res = _tmp_255_var;
+            _res = _tmp_257_var;
             if (_n == _children_capacity) {
                 _children_capacity *= 2;
                 void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *));
@@ -32277,7 +32876,7 @@ _loop0_119_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop0_119[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop0_121[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "('if' disjunction)"));
     }
     asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena);
@@ -32294,9 +32893,9 @@ _loop0_119_rule(Parser *p)
     return _seq;
 }
 
-// _tmp_120: assignment_expression | expression !':='
+// _tmp_122: assignment_expression | expression !':='
 static void *
-_tmp_120_rule(Parser *p)
+_tmp_122_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -32313,18 +32912,18 @@ _tmp_120_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_120[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "assignment_expression"));
+        D(fprintf(stderr, "%*c> _tmp_122[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "assignment_expression"));
         expr_ty assignment_expression_var;
         if (
             (assignment_expression_var = assignment_expression_rule(p))  // assignment_expression
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_120[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "assignment_expression"));
+            D(fprintf(stderr, "%*c+ _tmp_122[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "assignment_expression"));
             _res = assignment_expression_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_120[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_122[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "assignment_expression"));
     }
     { // expression !':='
@@ -32332,7 +32931,7 @@ _tmp_120_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_120[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression !':='"));
+        D(fprintf(stderr, "%*c> _tmp_122[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression !':='"));
         expr_ty expression_var;
         if (
             (expression_var = expression_rule(p))  // expression
@@ -32340,12 +32939,12 @@ _tmp_120_rule(Parser *p)
             _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 53)  // token=':='
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_120[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression !':='"));
+            D(fprintf(stderr, "%*c+ _tmp_122[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression !':='"));
             _res = expression_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_120[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_122[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression !':='"));
     }
     _res = NULL;
@@ -32354,9 +32953,9 @@ _tmp_120_rule(Parser *p)
     return _res;
 }
 
-// _loop0_122: ',' (starred_expression | (assignment_expression | expression !':=') !'=')
+// _loop0_124: ',' (starred_expression | (assignment_expression | expression !':=') !'=')
 static asdl_seq *
-_loop0_122_rule(Parser *p)
+_loop0_124_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -32382,13 +32981,13 @@ _loop0_122_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop0_122[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (starred_expression | (assignment_expression | expression !':=') !'=')"));
+        D(fprintf(stderr, "%*c> _loop0_124[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (starred_expression | (assignment_expression | expression !':=') !'=')"));
         Token * _literal;
         void *elem;
         while (
             (_literal = _PyPegen_expect_token(p, 12))  // token=','
             &&
-            (elem = _tmp_256_rule(p))  // starred_expression | (assignment_expression | expression !':=') !'='
+            (elem = _tmp_258_rule(p))  // starred_expression | (assignment_expression | expression !':=') !'='
         )
         {
             _res = elem;
@@ -32414,7 +33013,7 @@ _loop0_122_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop0_122[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop0_124[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (starred_expression | (assignment_expression | expression !':=') !'=')"));
     }
     asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena);
@@ -32431,10 +33030,10 @@ _loop0_122_rule(Parser *p)
     return _seq;
 }
 
-// _gather_121:
-//     | (starred_expression | (assignment_expression | expression !':=') !'=') _loop0_122
+// _gather_123:
+//     | (starred_expression | (assignment_expression | expression !':=') !'=') _loop0_124
 static asdl_seq *
-_gather_121_rule(Parser *p)
+_gather_123_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -32446,27 +33045,27 @@ _gather_121_rule(Parser *p)
     }
     asdl_seq * _res = NULL;
     int _mark = p->mark;
-    { // (starred_expression | (assignment_expression | expression !':=') !'=') _loop0_122
+    { // (starred_expression | (assignment_expression | expression !':=') !'=') _loop0_124
         if (p->error_indicator) {
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _gather_121[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(starred_expression | (assignment_expression | expression !':=') !'=') _loop0_122"));
+        D(fprintf(stderr, "%*c> _gather_123[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(starred_expression | (assignment_expression | expression !':=') !'=') _loop0_124"));
         void *elem;
         asdl_seq * seq;
         if (
-            (elem = _tmp_256_rule(p))  // starred_expression | (assignment_expression | expression !':=') !'='
+            (elem = _tmp_258_rule(p))  // starred_expression | (assignment_expression | expression !':=') !'='
             &&
-            (seq = _loop0_122_rule(p))  // _loop0_122
+            (seq = _loop0_124_rule(p))  // _loop0_124
         )
         {
-            D(fprintf(stderr, "%*c+ _gather_121[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(starred_expression | (assignment_expression | expression !':=') !'=') _loop0_122"));
+            D(fprintf(stderr, "%*c+ _gather_123[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(starred_expression | (assignment_expression | expression !':=') !'=') _loop0_124"));
             _res = _PyPegen_seq_insert_in_front(p, elem, seq);
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _gather_121[%d-%d]: %s failed!\n", p->level, ' ',
-                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(starred_expression | (assignment_expression | expression !':=') !'=') _loop0_122"));
+        D(fprintf(stderr, "%*c%s _gather_123[%d-%d]: %s failed!\n", p->level, ' ',
+                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(starred_expression | (assignment_expression | expression !':=') !'=') _loop0_124"));
     }
     _res = NULL;
   done:
@@ -32474,9 +33073,9 @@ _gather_121_rule(Parser *p)
     return _res;
 }
 
-// _tmp_123: ',' kwargs
+// _tmp_125: ',' kwargs
 static void *
-_tmp_123_rule(Parser *p)
+_tmp_125_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -32493,7 +33092,7 @@ _tmp_123_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_123[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwargs"));
+        D(fprintf(stderr, "%*c> _tmp_125[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwargs"));
         Token * _literal;
         asdl_seq* k;
         if (
@@ -32502,7 +33101,7 @@ _tmp_123_rule(Parser *p)
             (k = kwargs_rule(p))  // kwargs
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_123[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' kwargs"));
+            D(fprintf(stderr, "%*c+ _tmp_125[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' kwargs"));
             _res = k;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
@@ -32512,7 +33111,7 @@ _tmp_123_rule(Parser *p)
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_123[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_125[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' kwargs"));
     }
     _res = NULL;
@@ -32521,9 +33120,9 @@ _tmp_123_rule(Parser *p)
     return _res;
 }
 
-// _loop0_125: ',' kwarg_or_starred
+// _loop0_127: ',' kwarg_or_starred
 static asdl_seq *
-_loop0_125_rule(Parser *p)
+_loop0_127_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -32549,7 +33148,7 @@ _loop0_125_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop0_125[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwarg_or_starred"));
+        D(fprintf(stderr, "%*c> _loop0_127[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwarg_or_starred"));
         Token * _literal;
         KeywordOrStarred* elem;
         while (
@@ -32581,127 +33180,8 @@ _loop0_125_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop0_125[%d-%d]: %s failed!\n", p->level, ' ',
-                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' kwarg_or_starred"));
-    }
-    asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena);
-    if (!_seq) {
-        PyMem_Free(_children);
-        p->error_indicator = 1;
-        PyErr_NoMemory();
-        p->level--;
-        return NULL;
-    }
-    for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]);
-    PyMem_Free(_children);
-    p->level--;
-    return _seq;
-}
-
-// _gather_124: kwarg_or_starred _loop0_125
-static asdl_seq *
-_gather_124_rule(Parser *p)
-{
-    if (p->level++ == MAXSTACK) {
-        p->error_indicator = 1;
-        PyErr_NoMemory();
-    }
-    if (p->error_indicator) {
-        p->level--;
-        return NULL;
-    }
-    asdl_seq * _res = NULL;
-    int _mark = p->mark;
-    { // kwarg_or_starred _loop0_125
-        if (p->error_indicator) {
-            p->level--;
-            return NULL;
-        }
-        D(fprintf(stderr, "%*c> _gather_124[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kwarg_or_starred _loop0_125"));
-        KeywordOrStarred* elem;
-        asdl_seq * seq;
-        if (
-            (elem = kwarg_or_starred_rule(p))  // kwarg_or_starred
-            &&
-            (seq = _loop0_125_rule(p))  // _loop0_125
-        )
-        {
-            D(fprintf(stderr, "%*c+ _gather_124[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "kwarg_or_starred _loop0_125"));
-            _res = _PyPegen_seq_insert_in_front(p, elem, seq);
-            goto done;
-        }
-        p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _gather_124[%d-%d]: %s failed!\n", p->level, ' ',
-                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "kwarg_or_starred _loop0_125"));
-    }
-    _res = NULL;
-  done:
-    p->level--;
-    return _res;
-}
-
-// _loop0_127: ',' kwarg_or_double_starred
-static asdl_seq *
-_loop0_127_rule(Parser *p)
-{
-    if (p->level++ == MAXSTACK) {
-        p->error_indicator = 1;
-        PyErr_NoMemory();
-    }
-    if (p->error_indicator) {
-        p->level--;
-        return NULL;
-    }
-    void *_res = NULL;
-    int _mark = p->mark;
-    void **_children = PyMem_Malloc(sizeof(void *));
-    if (!_children) {
-        p->error_indicator = 1;
-        PyErr_NoMemory();
-        p->level--;
-        return NULL;
-    }
-    Py_ssize_t _children_capacity = 1;
-    Py_ssize_t _n = 0;
-    { // ',' kwarg_or_double_starred
-        if (p->error_indicator) {
-            p->level--;
-            return NULL;
-        }
-        D(fprintf(stderr, "%*c> _loop0_127[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwarg_or_double_starred"));
-        Token * _literal;
-        KeywordOrStarred* elem;
-        while (
-            (_literal = _PyPegen_expect_token(p, 12))  // token=','
-            &&
-            (elem = kwarg_or_double_starred_rule(p))  // kwarg_or_double_starred
-        )
-        {
-            _res = elem;
-            if (_res == NULL && PyErr_Occurred()) {
-                p->error_indicator = 1;
-                PyMem_Free(_children);
-                p->level--;
-                return NULL;
-            }
-            if (_n == _children_capacity) {
-                _children_capacity *= 2;
-                void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *));
-                if (!_new_children) {
-                    PyMem_Free(_children);
-                    p->error_indicator = 1;
-                    PyErr_NoMemory();
-                    p->level--;
-                    return NULL;
-                }
-                _children = _new_children;
-            }
-            _children[_n++] = _res;
-            _mark = p->mark;
-        }
-        p->mark = _mark;
         D(fprintf(stderr, "%*c%s _loop0_127[%d-%d]: %s failed!\n", p->level, ' ',
-                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' kwarg_or_double_starred"));
+                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' kwarg_or_starred"));
     }
     asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena);
     if (!_seq) {
@@ -32717,7 +33197,7 @@ _loop0_127_rule(Parser *p)
     return _seq;
 }
 
-// _gather_126: kwarg_or_double_starred _loop0_127
+// _gather_126: kwarg_or_starred _loop0_127
 static asdl_seq *
 _gather_126_rule(Parser *p)
 {
@@ -32731,27 +33211,27 @@ _gather_126_rule(Parser *p)
     }
     asdl_seq * _res = NULL;
     int _mark = p->mark;
-    { // kwarg_or_double_starred _loop0_127
+    { // kwarg_or_starred _loop0_127
         if (p->error_indicator) {
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _gather_126[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kwarg_or_double_starred _loop0_127"));
+        D(fprintf(stderr, "%*c> _gather_126[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kwarg_or_starred _loop0_127"));
         KeywordOrStarred* elem;
         asdl_seq * seq;
         if (
-            (elem = kwarg_or_double_starred_rule(p))  // kwarg_or_double_starred
+            (elem = kwarg_or_starred_rule(p))  // kwarg_or_starred
             &&
             (seq = _loop0_127_rule(p))  // _loop0_127
         )
         {
-            D(fprintf(stderr, "%*c+ _gather_126[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "kwarg_or_double_starred _loop0_127"));
+            D(fprintf(stderr, "%*c+ _gather_126[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "kwarg_or_starred _loop0_127"));
             _res = _PyPegen_seq_insert_in_front(p, elem, seq);
             goto done;
         }
         p->mark = _mark;
         D(fprintf(stderr, "%*c%s _gather_126[%d-%d]: %s failed!\n", p->level, ' ',
-                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "kwarg_or_double_starred _loop0_127"));
+                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "kwarg_or_starred _loop0_127"));
     }
     _res = NULL;
   done:
@@ -32759,7 +33239,7 @@ _gather_126_rule(Parser *p)
     return _res;
 }
 
-// _loop0_129: ',' kwarg_or_starred
+// _loop0_129: ',' kwarg_or_double_starred
 static asdl_seq *
 _loop0_129_rule(Parser *p)
 {
@@ -32782,18 +33262,18 @@ _loop0_129_rule(Parser *p)
     }
     Py_ssize_t _children_capacity = 1;
     Py_ssize_t _n = 0;
-    { // ',' kwarg_or_starred
+    { // ',' kwarg_or_double_starred
         if (p->error_indicator) {
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop0_129[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwarg_or_starred"));
+        D(fprintf(stderr, "%*c> _loop0_129[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwarg_or_double_starred"));
         Token * _literal;
         KeywordOrStarred* elem;
         while (
             (_literal = _PyPegen_expect_token(p, 12))  // token=','
             &&
-            (elem = kwarg_or_starred_rule(p))  // kwarg_or_starred
+            (elem = kwarg_or_double_starred_rule(p))  // kwarg_or_double_starred
         )
         {
             _res = elem;
@@ -32820,7 +33300,7 @@ _loop0_129_rule(Parser *p)
         }
         p->mark = _mark;
         D(fprintf(stderr, "%*c%s _loop0_129[%d-%d]: %s failed!\n", p->level, ' ',
-                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' kwarg_or_starred"));
+                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' kwarg_or_double_starred"));
     }
     asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena);
     if (!_seq) {
@@ -32836,7 +33316,7 @@ _loop0_129_rule(Parser *p)
     return _seq;
 }
 
-// _gather_128: kwarg_or_starred _loop0_129
+// _gather_128: kwarg_or_double_starred _loop0_129
 static asdl_seq *
 _gather_128_rule(Parser *p)
 {
@@ -32850,27 +33330,27 @@ _gather_128_rule(Parser *p)
     }
     asdl_seq * _res = NULL;
     int _mark = p->mark;
-    { // kwarg_or_starred _loop0_129
+    { // kwarg_or_double_starred _loop0_129
         if (p->error_indicator) {
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _gather_128[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kwarg_or_starred _loop0_129"));
+        D(fprintf(stderr, "%*c> _gather_128[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kwarg_or_double_starred _loop0_129"));
         KeywordOrStarred* elem;
         asdl_seq * seq;
         if (
-            (elem = kwarg_or_starred_rule(p))  // kwarg_or_starred
+            (elem = kwarg_or_double_starred_rule(p))  // kwarg_or_double_starred
             &&
             (seq = _loop0_129_rule(p))  // _loop0_129
         )
         {
-            D(fprintf(stderr, "%*c+ _gather_128[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "kwarg_or_starred _loop0_129"));
+            D(fprintf(stderr, "%*c+ _gather_128[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "kwarg_or_double_starred _loop0_129"));
             _res = _PyPegen_seq_insert_in_front(p, elem, seq);
             goto done;
         }
         p->mark = _mark;
         D(fprintf(stderr, "%*c%s _gather_128[%d-%d]: %s failed!\n", p->level, ' ',
-                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "kwarg_or_starred _loop0_129"));
+                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "kwarg_or_double_starred _loop0_129"));
     }
     _res = NULL;
   done:
@@ -32878,7 +33358,7 @@ _gather_128_rule(Parser *p)
     return _res;
 }
 
-// _loop0_131: ',' kwarg_or_double_starred
+// _loop0_131: ',' kwarg_or_starred
 static asdl_seq *
 _loop0_131_rule(Parser *p)
 {
@@ -32901,18 +33381,18 @@ _loop0_131_rule(Parser *p)
     }
     Py_ssize_t _children_capacity = 1;
     Py_ssize_t _n = 0;
-    { // ',' kwarg_or_double_starred
+    { // ',' kwarg_or_starred
         if (p->error_indicator) {
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop0_131[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwarg_or_double_starred"));
+        D(fprintf(stderr, "%*c> _loop0_131[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwarg_or_starred"));
         Token * _literal;
         KeywordOrStarred* elem;
         while (
             (_literal = _PyPegen_expect_token(p, 12))  // token=','
             &&
-            (elem = kwarg_or_double_starred_rule(p))  // kwarg_or_double_starred
+            (elem = kwarg_or_starred_rule(p))  // kwarg_or_starred
         )
         {
             _res = elem;
@@ -32939,7 +33419,7 @@ _loop0_131_rule(Parser *p)
         }
         p->mark = _mark;
         D(fprintf(stderr, "%*c%s _loop0_131[%d-%d]: %s failed!\n", p->level, ' ',
-                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' kwarg_or_double_starred"));
+                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' kwarg_or_starred"));
     }
     asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena);
     if (!_seq) {
@@ -32955,7 +33435,7 @@ _loop0_131_rule(Parser *p)
     return _seq;
 }
 
-// _gather_130: kwarg_or_double_starred _loop0_131
+// _gather_130: kwarg_or_starred _loop0_131
 static asdl_seq *
 _gather_130_rule(Parser *p)
 {
@@ -32969,27 +33449,27 @@ _gather_130_rule(Parser *p)
     }
     asdl_seq * _res = NULL;
     int _mark = p->mark;
-    { // kwarg_or_double_starred _loop0_131
+    { // kwarg_or_starred _loop0_131
         if (p->error_indicator) {
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _gather_130[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kwarg_or_double_starred _loop0_131"));
+        D(fprintf(stderr, "%*c> _gather_130[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kwarg_or_starred _loop0_131"));
         KeywordOrStarred* elem;
         asdl_seq * seq;
         if (
-            (elem = kwarg_or_double_starred_rule(p))  // kwarg_or_double_starred
+            (elem = kwarg_or_starred_rule(p))  // kwarg_or_starred
             &&
             (seq = _loop0_131_rule(p))  // _loop0_131
         )
         {
-            D(fprintf(stderr, "%*c+ _gather_130[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "kwarg_or_double_starred _loop0_131"));
+            D(fprintf(stderr, "%*c+ _gather_130[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "kwarg_or_starred _loop0_131"));
             _res = _PyPegen_seq_insert_in_front(p, elem, seq);
             goto done;
         }
         p->mark = _mark;
         D(fprintf(stderr, "%*c%s _gather_130[%d-%d]: %s failed!\n", p->level, ' ',
-                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "kwarg_or_double_starred _loop0_131"));
+                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "kwarg_or_starred _loop0_131"));
     }
     _res = NULL;
   done:
@@ -32997,9 +33477,128 @@ _gather_130_rule(Parser *p)
     return _res;
 }
 
-// _loop0_132: (',' star_target)
+// _loop0_133: ',' kwarg_or_double_starred
 static asdl_seq *
-_loop0_132_rule(Parser *p)
+_loop0_133_rule(Parser *p)
+{
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
+    if (p->error_indicator) {
+        p->level--;
+        return NULL;
+    }
+    void *_res = NULL;
+    int _mark = p->mark;
+    void **_children = PyMem_Malloc(sizeof(void *));
+    if (!_children) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+        p->level--;
+        return NULL;
+    }
+    Py_ssize_t _children_capacity = 1;
+    Py_ssize_t _n = 0;
+    { // ',' kwarg_or_double_starred
+        if (p->error_indicator) {
+            p->level--;
+            return NULL;
+        }
+        D(fprintf(stderr, "%*c> _loop0_133[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' kwarg_or_double_starred"));
+        Token * _literal;
+        KeywordOrStarred* elem;
+        while (
+            (_literal = _PyPegen_expect_token(p, 12))  // token=','
+            &&
+            (elem = kwarg_or_double_starred_rule(p))  // kwarg_or_double_starred
+        )
+        {
+            _res = elem;
+            if (_res == NULL && PyErr_Occurred()) {
+                p->error_indicator = 1;
+                PyMem_Free(_children);
+                p->level--;
+                return NULL;
+            }
+            if (_n == _children_capacity) {
+                _children_capacity *= 2;
+                void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *));
+                if (!_new_children) {
+                    PyMem_Free(_children);
+                    p->error_indicator = 1;
+                    PyErr_NoMemory();
+                    p->level--;
+                    return NULL;
+                }
+                _children = _new_children;
+            }
+            _children[_n++] = _res;
+            _mark = p->mark;
+        }
+        p->mark = _mark;
+        D(fprintf(stderr, "%*c%s _loop0_133[%d-%d]: %s failed!\n", p->level, ' ',
+                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' kwarg_or_double_starred"));
+    }
+    asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena);
+    if (!_seq) {
+        PyMem_Free(_children);
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+        p->level--;
+        return NULL;
+    }
+    for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]);
+    PyMem_Free(_children);
+    p->level--;
+    return _seq;
+}
+
+// _gather_132: kwarg_or_double_starred _loop0_133
+static asdl_seq *
+_gather_132_rule(Parser *p)
+{
+    if (p->level++ == MAXSTACK) {
+        p->error_indicator = 1;
+        PyErr_NoMemory();
+    }
+    if (p->error_indicator) {
+        p->level--;
+        return NULL;
+    }
+    asdl_seq * _res = NULL;
+    int _mark = p->mark;
+    { // kwarg_or_double_starred _loop0_133
+        if (p->error_indicator) {
+            p->level--;
+            return NULL;
+        }
+        D(fprintf(stderr, "%*c> _gather_132[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "kwarg_or_double_starred _loop0_133"));
+        KeywordOrStarred* elem;
+        asdl_seq * seq;
+        if (
+            (elem = kwarg_or_double_starred_rule(p))  // kwarg_or_double_starred
+            &&
+            (seq = _loop0_133_rule(p))  // _loop0_133
+        )
+        {
+            D(fprintf(stderr, "%*c+ _gather_132[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "kwarg_or_double_starred _loop0_133"));
+            _res = _PyPegen_seq_insert_in_front(p, elem, seq);
+            goto done;
+        }
+        p->mark = _mark;
+        D(fprintf(stderr, "%*c%s _gather_132[%d-%d]: %s failed!\n", p->level, ' ',
+                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "kwarg_or_double_starred _loop0_133"));
+    }
+    _res = NULL;
+  done:
+    p->level--;
+    return _res;
+}
+
+// _loop0_134: (',' star_target)
+static asdl_seq *
+_loop0_134_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -33025,13 +33624,13 @@ _loop0_132_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop0_132[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_target)"));
-        void *_tmp_257_var;
+        D(fprintf(stderr, "%*c> _loop0_134[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_target)"));
+        void *_tmp_259_var;
         while (
-            (_tmp_257_var = _tmp_257_rule(p))  // ',' star_target
+            (_tmp_259_var = _tmp_259_rule(p))  // ',' star_target
         )
         {
-            _res = _tmp_257_var;
+            _res = _tmp_259_var;
             if (_n == _children_capacity) {
                 _children_capacity *= 2;
                 void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *));
@@ -33048,7 +33647,7 @@ _loop0_132_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop0_132[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop0_134[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(',' star_target)"));
     }
     asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena);
@@ -33065,9 +33664,9 @@ _loop0_132_rule(Parser *p)
     return _seq;
 }
 
-// _loop0_134: ',' star_target
+// _loop0_136: ',' star_target
 static asdl_seq *
-_loop0_134_rule(Parser *p)
+_loop0_136_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -33093,7 +33692,7 @@ _loop0_134_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop0_134[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target"));
+        D(fprintf(stderr, "%*c> _loop0_136[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target"));
         Token * _literal;
         expr_ty elem;
         while (
@@ -33125,7 +33724,7 @@ _loop0_134_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop0_134[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop0_136[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' star_target"));
     }
     asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena);
@@ -33142,9 +33741,9 @@ _loop0_134_rule(Parser *p)
     return _seq;
 }
 
-// _gather_133: star_target _loop0_134
+// _gather_135: star_target _loop0_136
 static asdl_seq *
-_gather_133_rule(Parser *p)
+_gather_135_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -33156,27 +33755,27 @@ _gather_133_rule(Parser *p)
     }
     asdl_seq * _res = NULL;
     int _mark = p->mark;
-    { // star_target _loop0_134
+    { // star_target _loop0_136
         if (p->error_indicator) {
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _gather_133[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_target _loop0_134"));
+        D(fprintf(stderr, "%*c> _gather_135[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_target _loop0_136"));
         expr_ty elem;
         asdl_seq * seq;
         if (
             (elem = star_target_rule(p))  // star_target
             &&
-            (seq = _loop0_134_rule(p))  // _loop0_134
+            (seq = _loop0_136_rule(p))  // _loop0_136
         )
         {
-            D(fprintf(stderr, "%*c+ _gather_133[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_target _loop0_134"));
+            D(fprintf(stderr, "%*c+ _gather_135[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_target _loop0_136"));
             _res = _PyPegen_seq_insert_in_front(p, elem, seq);
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _gather_133[%d-%d]: %s failed!\n", p->level, ' ',
-                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_target _loop0_134"));
+        D(fprintf(stderr, "%*c%s _gather_135[%d-%d]: %s failed!\n", p->level, ' ',
+                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_target _loop0_136"));
     }
     _res = NULL;
   done:
@@ -33184,9 +33783,9 @@ _gather_133_rule(Parser *p)
     return _res;
 }
 
-// _loop1_135: (',' star_target)
+// _loop1_137: (',' star_target)
 static asdl_seq *
-_loop1_135_rule(Parser *p)
+_loop1_137_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -33212,13 +33811,13 @@ _loop1_135_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop1_135[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_target)"));
-        void *_tmp_258_var;
+        D(fprintf(stderr, "%*c> _loop1_137[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(',' star_target)"));
+        void *_tmp_260_var;
         while (
-            (_tmp_258_var = _tmp_258_rule(p))  // ',' star_target
+            (_tmp_260_var = _tmp_260_rule(p))  // ',' star_target
         )
         {
-            _res = _tmp_258_var;
+            _res = _tmp_260_var;
             if (_n == _children_capacity) {
                 _children_capacity *= 2;
                 void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *));
@@ -33235,7 +33834,7 @@ _loop1_135_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop1_135[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop1_137[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(',' star_target)"));
     }
     if (_n == 0 || p->error_indicator) {
@@ -33257,9 +33856,9 @@ _loop1_135_rule(Parser *p)
     return _seq;
 }
 
-// _tmp_136: !'*' star_target
+// _tmp_138: !'*' star_target
 static void *
-_tmp_136_rule(Parser *p)
+_tmp_138_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -33276,7 +33875,7 @@ _tmp_136_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_136[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "!'*' star_target"));
+        D(fprintf(stderr, "%*c> _tmp_138[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "!'*' star_target"));
         expr_ty star_target_var;
         if (
             _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 16)  // token='*'
@@ -33284,12 +33883,12 @@ _tmp_136_rule(Parser *p)
             (star_target_var = star_target_rule(p))  // star_target
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_136[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "!'*' star_target"));
+            D(fprintf(stderr, "%*c+ _tmp_138[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "!'*' star_target"));
             _res = star_target_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_136[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_138[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "!'*' star_target"));
     }
     _res = NULL;
@@ -33298,9 +33897,9 @@ _tmp_136_rule(Parser *p)
     return _res;
 }
 
-// _loop0_138: ',' del_target
+// _loop0_140: ',' del_target
 static asdl_seq *
-_loop0_138_rule(Parser *p)
+_loop0_140_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -33326,7 +33925,7 @@ _loop0_138_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop0_138[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' del_target"));
+        D(fprintf(stderr, "%*c> _loop0_140[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' del_target"));
         Token * _literal;
         expr_ty elem;
         while (
@@ -33358,7 +33957,7 @@ _loop0_138_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop0_138[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop0_140[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' del_target"));
     }
     asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena);
@@ -33375,9 +33974,9 @@ _loop0_138_rule(Parser *p)
     return _seq;
 }
 
-// _gather_137: del_target _loop0_138
+// _gather_139: del_target _loop0_140
 static asdl_seq *
-_gather_137_rule(Parser *p)
+_gather_139_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -33389,27 +33988,27 @@ _gather_137_rule(Parser *p)
     }
     asdl_seq * _res = NULL;
     int _mark = p->mark;
-    { // del_target _loop0_138
+    { // del_target _loop0_140
         if (p->error_indicator) {
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _gather_137[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "del_target _loop0_138"));
+        D(fprintf(stderr, "%*c> _gather_139[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "del_target _loop0_140"));
         expr_ty elem;
         asdl_seq * seq;
         if (
             (elem = del_target_rule(p))  // del_target
             &&
-            (seq = _loop0_138_rule(p))  // _loop0_138
+            (seq = _loop0_140_rule(p))  // _loop0_140
         )
         {
-            D(fprintf(stderr, "%*c+ _gather_137[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "del_target _loop0_138"));
+            D(fprintf(stderr, "%*c+ _gather_139[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "del_target _loop0_140"));
             _res = _PyPegen_seq_insert_in_front(p, elem, seq);
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _gather_137[%d-%d]: %s failed!\n", p->level, ' ',
-                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "del_target _loop0_138"));
+        D(fprintf(stderr, "%*c%s _gather_139[%d-%d]: %s failed!\n", p->level, ' ',
+                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "del_target _loop0_140"));
     }
     _res = NULL;
   done:
@@ -33417,9 +34016,9 @@ _gather_137_rule(Parser *p)
     return _res;
 }
 
-// _loop0_140: ',' expression
+// _loop0_142: ',' expression
 static asdl_seq *
-_loop0_140_rule(Parser *p)
+_loop0_142_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -33445,7 +34044,7 @@ _loop0_140_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop0_140[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression"));
+        D(fprintf(stderr, "%*c> _loop0_142[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression"));
         Token * _literal;
         expr_ty elem;
         while (
@@ -33477,7 +34076,7 @@ _loop0_140_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop0_140[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop0_142[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' expression"));
     }
     asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena);
@@ -33494,9 +34093,9 @@ _loop0_140_rule(Parser *p)
     return _seq;
 }
 
-// _gather_139: expression _loop0_140
+// _gather_141: expression _loop0_142
 static asdl_seq *
-_gather_139_rule(Parser *p)
+_gather_141_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -33508,27 +34107,27 @@ _gather_139_rule(Parser *p)
     }
     asdl_seq * _res = NULL;
     int _mark = p->mark;
-    { // expression _loop0_140
+    { // expression _loop0_142
         if (p->error_indicator) {
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _gather_139[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression _loop0_140"));
+        D(fprintf(stderr, "%*c> _gather_141[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression _loop0_142"));
         expr_ty elem;
         asdl_seq * seq;
         if (
             (elem = expression_rule(p))  // expression
             &&
-            (seq = _loop0_140_rule(p))  // _loop0_140
+            (seq = _loop0_142_rule(p))  // _loop0_142
         )
         {
-            D(fprintf(stderr, "%*c+ _gather_139[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression _loop0_140"));
+            D(fprintf(stderr, "%*c+ _gather_141[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression _loop0_142"));
             _res = _PyPegen_seq_insert_in_front(p, elem, seq);
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _gather_139[%d-%d]: %s failed!\n", p->level, ' ',
-                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression _loop0_140"));
+        D(fprintf(stderr, "%*c%s _gather_141[%d-%d]: %s failed!\n", p->level, ' ',
+                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression _loop0_142"));
     }
     _res = NULL;
   done:
@@ -33536,9 +34135,9 @@ _gather_139_rule(Parser *p)
     return _res;
 }
 
-// _loop0_142: ',' expression
+// _loop0_144: ',' expression
 static asdl_seq *
-_loop0_142_rule(Parser *p)
+_loop0_144_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -33564,7 +34163,7 @@ _loop0_142_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop0_142[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression"));
+        D(fprintf(stderr, "%*c> _loop0_144[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression"));
         Token * _literal;
         expr_ty elem;
         while (
@@ -33596,7 +34195,7 @@ _loop0_142_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop0_142[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop0_144[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' expression"));
     }
     asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena);
@@ -33613,9 +34212,9 @@ _loop0_142_rule(Parser *p)
     return _seq;
 }
 
-// _gather_141: expression _loop0_142
+// _gather_143: expression _loop0_144
 static asdl_seq *
-_gather_141_rule(Parser *p)
+_gather_143_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -33627,27 +34226,27 @@ _gather_141_rule(Parser *p)
     }
     asdl_seq * _res = NULL;
     int _mark = p->mark;
-    { // expression _loop0_142
+    { // expression _loop0_144
         if (p->error_indicator) {
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _gather_141[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression _loop0_142"));
+        D(fprintf(stderr, "%*c> _gather_143[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression _loop0_144"));
         expr_ty elem;
         asdl_seq * seq;
         if (
             (elem = expression_rule(p))  // expression
             &&
-            (seq = _loop0_142_rule(p))  // _loop0_142
+            (seq = _loop0_144_rule(p))  // _loop0_144
         )
         {
-            D(fprintf(stderr, "%*c+ _gather_141[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression _loop0_142"));
+            D(fprintf(stderr, "%*c+ _gather_143[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression _loop0_144"));
             _res = _PyPegen_seq_insert_in_front(p, elem, seq);
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _gather_141[%d-%d]: %s failed!\n", p->level, ' ',
-                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression _loop0_142"));
+        D(fprintf(stderr, "%*c%s _gather_143[%d-%d]: %s failed!\n", p->level, ' ',
+                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression _loop0_144"));
     }
     _res = NULL;
   done:
@@ -33655,9 +34254,9 @@ _gather_141_rule(Parser *p)
     return _res;
 }
 
-// _loop0_144: ',' expression
+// _loop0_146: ',' expression
 static asdl_seq *
-_loop0_144_rule(Parser *p)
+_loop0_146_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -33683,7 +34282,7 @@ _loop0_144_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop0_144[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression"));
+        D(fprintf(stderr, "%*c> _loop0_146[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression"));
         Token * _literal;
         expr_ty elem;
         while (
@@ -33715,7 +34314,7 @@ _loop0_144_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop0_144[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop0_146[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' expression"));
     }
     asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena);
@@ -33732,9 +34331,9 @@ _loop0_144_rule(Parser *p)
     return _seq;
 }
 
-// _gather_143: expression _loop0_144
+// _gather_145: expression _loop0_146
 static asdl_seq *
-_gather_143_rule(Parser *p)
+_gather_145_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -33746,27 +34345,27 @@ _gather_143_rule(Parser *p)
     }
     asdl_seq * _res = NULL;
     int _mark = p->mark;
-    { // expression _loop0_144
+    { // expression _loop0_146
         if (p->error_indicator) {
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _gather_143[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression _loop0_144"));
+        D(fprintf(stderr, "%*c> _gather_145[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression _loop0_146"));
         expr_ty elem;
         asdl_seq * seq;
         if (
             (elem = expression_rule(p))  // expression
             &&
-            (seq = _loop0_144_rule(p))  // _loop0_144
+            (seq = _loop0_146_rule(p))  // _loop0_146
         )
         {
-            D(fprintf(stderr, "%*c+ _gather_143[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression _loop0_144"));
+            D(fprintf(stderr, "%*c+ _gather_145[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression _loop0_146"));
             _res = _PyPegen_seq_insert_in_front(p, elem, seq);
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _gather_143[%d-%d]: %s failed!\n", p->level, ' ',
-                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression _loop0_144"));
+        D(fprintf(stderr, "%*c%s _gather_145[%d-%d]: %s failed!\n", p->level, ' ',
+                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression _loop0_146"));
     }
     _res = NULL;
   done:
@@ -33774,9 +34373,9 @@ _gather_143_rule(Parser *p)
     return _res;
 }
 
-// _loop0_146: ',' expression
+// _loop0_148: ',' expression
 static asdl_seq *
-_loop0_146_rule(Parser *p)
+_loop0_148_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -33802,7 +34401,7 @@ _loop0_146_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop0_146[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression"));
+        D(fprintf(stderr, "%*c> _loop0_148[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression"));
         Token * _literal;
         expr_ty elem;
         while (
@@ -33834,7 +34433,7 @@ _loop0_146_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop0_146[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop0_148[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' expression"));
     }
     asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena);
@@ -33851,9 +34450,9 @@ _loop0_146_rule(Parser *p)
     return _seq;
 }
 
-// _gather_145: expression _loop0_146
+// _gather_147: expression _loop0_148
 static asdl_seq *
-_gather_145_rule(Parser *p)
+_gather_147_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -33865,27 +34464,27 @@ _gather_145_rule(Parser *p)
     }
     asdl_seq * _res = NULL;
     int _mark = p->mark;
-    { // expression _loop0_146
+    { // expression _loop0_148
         if (p->error_indicator) {
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _gather_145[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression _loop0_146"));
+        D(fprintf(stderr, "%*c> _gather_147[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression _loop0_148"));
         expr_ty elem;
         asdl_seq * seq;
         if (
             (elem = expression_rule(p))  // expression
             &&
-            (seq = _loop0_146_rule(p))  // _loop0_146
+            (seq = _loop0_148_rule(p))  // _loop0_148
         )
         {
-            D(fprintf(stderr, "%*c+ _gather_145[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression _loop0_146"));
+            D(fprintf(stderr, "%*c+ _gather_147[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression _loop0_148"));
             _res = _PyPegen_seq_insert_in_front(p, elem, seq);
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _gather_145[%d-%d]: %s failed!\n", p->level, ' ',
-                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression _loop0_146"));
+        D(fprintf(stderr, "%*c%s _gather_147[%d-%d]: %s failed!\n", p->level, ' ',
+                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression _loop0_148"));
     }
     _res = NULL;
   done:
@@ -33893,9 +34492,9 @@ _gather_145_rule(Parser *p)
     return _res;
 }
 
-// _tmp_147: NEWLINE INDENT
+// _tmp_149: NEWLINE INDENT
 static void *
-_tmp_147_rule(Parser *p)
+_tmp_149_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -33912,7 +34511,7 @@ _tmp_147_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_147[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NEWLINE INDENT"));
+        D(fprintf(stderr, "%*c> _tmp_149[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NEWLINE INDENT"));
         Token * indent_var;
         Token * newline_var;
         if (
@@ -33921,12 +34520,12 @@ _tmp_147_rule(Parser *p)
             (indent_var = _PyPegen_expect_token(p, INDENT))  // token='INDENT'
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_147[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NEWLINE INDENT"));
+            D(fprintf(stderr, "%*c+ _tmp_149[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NEWLINE INDENT"));
             _res = _PyPegen_dummy_name(p, newline_var, indent_var);
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_147[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_149[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NEWLINE INDENT"));
     }
     _res = NULL;
@@ -33935,9 +34534,9 @@ _tmp_147_rule(Parser *p)
     return _res;
 }
 
-// _tmp_148: args | expression for_if_clauses
+// _tmp_150: args | expression for_if_clauses
 static void *
-_tmp_148_rule(Parser *p)
+_tmp_150_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -33954,18 +34553,18 @@ _tmp_148_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_148[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "args"));
+        D(fprintf(stderr, "%*c> _tmp_150[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "args"));
         expr_ty args_var;
         if (
             (args_var = args_rule(p))  // args
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_148[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "args"));
+            D(fprintf(stderr, "%*c+ _tmp_150[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "args"));
             _res = args_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_148[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_150[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "args"));
     }
     { // expression for_if_clauses
@@ -33973,7 +34572,7 @@ _tmp_148_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_148[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression for_if_clauses"));
+        D(fprintf(stderr, "%*c> _tmp_150[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression for_if_clauses"));
         expr_ty expression_var;
         asdl_comprehension_seq* for_if_clauses_var;
         if (
@@ -33982,12 +34581,12 @@ _tmp_148_rule(Parser *p)
             (for_if_clauses_var = for_if_clauses_rule(p))  // for_if_clauses
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_148[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression for_if_clauses"));
+            D(fprintf(stderr, "%*c+ _tmp_150[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression for_if_clauses"));
             _res = _PyPegen_dummy_name(p, expression_var, for_if_clauses_var);
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_148[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_150[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression for_if_clauses"));
     }
     _res = NULL;
@@ -33996,9 +34595,9 @@ _tmp_148_rule(Parser *p)
     return _res;
 }
 
-// _tmp_149: args ','
+// _tmp_151: args ','
 static void *
-_tmp_149_rule(Parser *p)
+_tmp_151_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -34015,7 +34614,7 @@ _tmp_149_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_149[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "args ','"));
+        D(fprintf(stderr, "%*c> _tmp_151[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "args ','"));
         Token * _literal;
         expr_ty args_var;
         if (
@@ -34024,12 +34623,12 @@ _tmp_149_rule(Parser *p)
             (_literal = _PyPegen_expect_token(p, 12))  // token=','
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_149[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "args ','"));
+            D(fprintf(stderr, "%*c+ _tmp_151[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "args ','"));
             _res = _PyPegen_dummy_name(p, args_var, _literal);
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_149[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_151[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "args ','"));
     }
     _res = NULL;
@@ -34038,9 +34637,9 @@ _tmp_149_rule(Parser *p)
     return _res;
 }
 
-// _tmp_150: ',' | ')'
+// _tmp_152: ',' | ')'
 static void *
-_tmp_150_rule(Parser *p)
+_tmp_152_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -34057,18 +34656,18 @@ _tmp_150_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_150[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','"));
+        D(fprintf(stderr, "%*c> _tmp_152[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','"));
         Token * _literal;
         if (
             (_literal = _PyPegen_expect_token(p, 12))  // token=','
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_150[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','"));
+            D(fprintf(stderr, "%*c+ _tmp_152[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','"));
             _res = _literal;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_150[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_152[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','"));
     }
     { // ')'
@@ -34076,18 +34675,18 @@ _tmp_150_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_150[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'"));
+        D(fprintf(stderr, "%*c> _tmp_152[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'"));
         Token * _literal;
         if (
             (_literal = _PyPegen_expect_token(p, 8))  // token=')'
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_150[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'"));
+            D(fprintf(stderr, "%*c+ _tmp_152[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'"));
             _res = _literal;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_150[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_152[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'"));
     }
     _res = NULL;
@@ -34096,9 +34695,9 @@ _tmp_150_rule(Parser *p)
     return _res;
 }
 
-// _tmp_151: 'True' | 'False' | 'None'
+// _tmp_153: 'True' | 'False' | 'None'
 static void *
-_tmp_151_rule(Parser *p)
+_tmp_153_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -34115,18 +34714,18 @@ _tmp_151_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_151[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'True'"));
+        D(fprintf(stderr, "%*c> _tmp_153[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'True'"));
         Token * _keyword;
         if (
             (_keyword = _PyPegen_expect_token(p, 601))  // token='True'
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_151[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'True'"));
+            D(fprintf(stderr, "%*c+ _tmp_153[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'True'"));
             _res = _keyword;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_151[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_153[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'True'"));
     }
     { // 'False'
@@ -34134,18 +34733,18 @@ _tmp_151_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_151[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'False'"));
+        D(fprintf(stderr, "%*c> _tmp_153[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'False'"));
         Token * _keyword;
         if (
             (_keyword = _PyPegen_expect_token(p, 603))  // token='False'
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_151[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'False'"));
+            D(fprintf(stderr, "%*c+ _tmp_153[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'False'"));
             _res = _keyword;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_151[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_153[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'False'"));
     }
     { // 'None'
@@ -34153,18 +34752,18 @@ _tmp_151_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_151[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'None'"));
+        D(fprintf(stderr, "%*c> _tmp_153[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'None'"));
         Token * _keyword;
         if (
             (_keyword = _PyPegen_expect_token(p, 602))  // token='None'
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_151[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'None'"));
+            D(fprintf(stderr, "%*c+ _tmp_153[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'None'"));
             _res = _keyword;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_151[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_153[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'None'"));
     }
     _res = NULL;
@@ -34173,9 +34772,9 @@ _tmp_151_rule(Parser *p)
     return _res;
 }
 
-// _tmp_152: NAME '='
+// _tmp_154: NAME '='
 static void *
-_tmp_152_rule(Parser *p)
+_tmp_154_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -34192,7 +34791,7 @@ _tmp_152_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_152[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME '='"));
+        D(fprintf(stderr, "%*c> _tmp_154[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME '='"));
         Token * _literal;
         expr_ty name_var;
         if (
@@ -34201,12 +34800,12 @@ _tmp_152_rule(Parser *p)
             (_literal = _PyPegen_expect_token(p, 22))  // token='='
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_152[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME '='"));
+            D(fprintf(stderr, "%*c+ _tmp_154[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME '='"));
             _res = _PyPegen_dummy_name(p, name_var, _literal);
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_152[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_154[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME '='"));
     }
     _res = NULL;
@@ -34215,9 +34814,9 @@ _tmp_152_rule(Parser *p)
     return _res;
 }
 
-// _tmp_153: NAME STRING | SOFT_KEYWORD
+// _tmp_155: NAME STRING | SOFT_KEYWORD
 static void *
-_tmp_153_rule(Parser *p)
+_tmp_155_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -34234,7 +34833,7 @@ _tmp_153_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_153[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME STRING"));
+        D(fprintf(stderr, "%*c> _tmp_155[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NAME STRING"));
         expr_ty name_var;
         expr_ty string_var;
         if (
@@ -34243,12 +34842,12 @@ _tmp_153_rule(Parser *p)
             (string_var = _PyPegen_string_token(p))  // STRING
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_153[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME STRING"));
+            D(fprintf(stderr, "%*c+ _tmp_155[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NAME STRING"));
             _res = _PyPegen_dummy_name(p, name_var, string_var);
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_153[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_155[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NAME STRING"));
     }
     { // SOFT_KEYWORD
@@ -34256,18 +34855,18 @@ _tmp_153_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_153[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "SOFT_KEYWORD"));
+        D(fprintf(stderr, "%*c> _tmp_155[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "SOFT_KEYWORD"));
         expr_ty soft_keyword_var;
         if (
             (soft_keyword_var = _PyPegen_soft_keyword_token(p))  // SOFT_KEYWORD
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_153[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "SOFT_KEYWORD"));
+            D(fprintf(stderr, "%*c+ _tmp_155[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "SOFT_KEYWORD"));
             _res = soft_keyword_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_153[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_155[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "SOFT_KEYWORD"));
     }
     _res = NULL;
@@ -34276,9 +34875,9 @@ _tmp_153_rule(Parser *p)
     return _res;
 }
 
-// _tmp_154: 'else' | ':'
+// _tmp_156: 'else' | ':'
 static void *
-_tmp_154_rule(Parser *p)
+_tmp_156_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -34295,18 +34894,18 @@ _tmp_154_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_154[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'else'"));
+        D(fprintf(stderr, "%*c> _tmp_156[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'else'"));
         Token * _keyword;
         if (
             (_keyword = _PyPegen_expect_token(p, 645))  // token='else'
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_154[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'else'"));
+            D(fprintf(stderr, "%*c+ _tmp_156[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'else'"));
             _res = _keyword;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_154[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_156[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'else'"));
     }
     { // ':'
@@ -34314,18 +34913,18 @@ _tmp_154_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_154[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'"));
+        D(fprintf(stderr, "%*c> _tmp_156[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'"));
         Token * _literal;
         if (
             (_literal = _PyPegen_expect_token(p, 11))  // token=':'
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_154[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'"));
+            D(fprintf(stderr, "%*c+ _tmp_156[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'"));
             _res = _literal;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_154[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_156[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'"));
     }
     _res = NULL;
@@ -34334,9 +34933,9 @@ _tmp_154_rule(Parser *p)
     return _res;
 }
 
-// _tmp_155: FSTRING_MIDDLE | fstring_replacement_field
+// _tmp_157: FSTRING_MIDDLE | fstring_replacement_field
 static void *
-_tmp_155_rule(Parser *p)
+_tmp_157_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -34353,18 +34952,18 @@ _tmp_155_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_155[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "FSTRING_MIDDLE"));
+        D(fprintf(stderr, "%*c> _tmp_157[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "FSTRING_MIDDLE"));
         Token * fstring_middle_var;
         if (
             (fstring_middle_var = _PyPegen_expect_token(p, FSTRING_MIDDLE))  // token='FSTRING_MIDDLE'
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_155[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "FSTRING_MIDDLE"));
+            D(fprintf(stderr, "%*c+ _tmp_157[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "FSTRING_MIDDLE"));
             _res = fstring_middle_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_155[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_157[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "FSTRING_MIDDLE"));
     }
     { // fstring_replacement_field
@@ -34372,18 +34971,18 @@ _tmp_155_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_155[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "fstring_replacement_field"));
+        D(fprintf(stderr, "%*c> _tmp_157[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "fstring_replacement_field"));
         expr_ty fstring_replacement_field_var;
         if (
             (fstring_replacement_field_var = fstring_replacement_field_rule(p))  // fstring_replacement_field
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_155[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "fstring_replacement_field"));
+            D(fprintf(stderr, "%*c+ _tmp_157[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "fstring_replacement_field"));
             _res = fstring_replacement_field_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_155[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_157[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "fstring_replacement_field"));
     }
     _res = NULL;
@@ -34392,9 +34991,9 @@ _tmp_155_rule(Parser *p)
     return _res;
 }
 
-// _tmp_156: '=' | ':='
+// _tmp_158: '=' | ':='
 static void *
-_tmp_156_rule(Parser *p)
+_tmp_158_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -34411,18 +35010,18 @@ _tmp_156_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_156[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='"));
+        D(fprintf(stderr, "%*c> _tmp_158[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='"));
         Token * _literal;
         if (
             (_literal = _PyPegen_expect_token(p, 22))  // token='='
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_156[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'='"));
+            D(fprintf(stderr, "%*c+ _tmp_158[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'='"));
             _res = _literal;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_156[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_158[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'='"));
     }
     { // ':='
@@ -34430,18 +35029,18 @@ _tmp_156_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_156[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':='"));
+        D(fprintf(stderr, "%*c> _tmp_158[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':='"));
         Token * _literal;
         if (
             (_literal = _PyPegen_expect_token(p, 53))  // token=':='
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_156[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':='"));
+            D(fprintf(stderr, "%*c+ _tmp_158[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':='"));
             _res = _literal;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_156[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_158[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':='"));
     }
     _res = NULL;
@@ -34450,9 +35049,9 @@ _tmp_156_rule(Parser *p)
     return _res;
 }
 
-// _tmp_157: list | tuple | genexp | 'True' | 'None' | 'False'
+// _tmp_159: list | tuple | genexp | 'True' | 'None' | 'False'
 static void *
-_tmp_157_rule(Parser *p)
+_tmp_159_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -34469,18 +35068,18 @@ _tmp_157_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_157[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "list"));
+        D(fprintf(stderr, "%*c> _tmp_159[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "list"));
         expr_ty list_var;
         if (
             (list_var = list_rule(p))  // list
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_157[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "list"));
+            D(fprintf(stderr, "%*c+ _tmp_159[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "list"));
             _res = list_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_157[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_159[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "list"));
     }
     { // tuple
@@ -34488,18 +35087,18 @@ _tmp_157_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_157[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "tuple"));
+        D(fprintf(stderr, "%*c> _tmp_159[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "tuple"));
         expr_ty tuple_var;
         if (
             (tuple_var = tuple_rule(p))  // tuple
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_157[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "tuple"));
+            D(fprintf(stderr, "%*c+ _tmp_159[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "tuple"));
             _res = tuple_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_157[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_159[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "tuple"));
     }
     { // genexp
@@ -34507,18 +35106,18 @@ _tmp_157_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_157[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "genexp"));
+        D(fprintf(stderr, "%*c> _tmp_159[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "genexp"));
         expr_ty genexp_var;
         if (
             (genexp_var = genexp_rule(p))  // genexp
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_157[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "genexp"));
+            D(fprintf(stderr, "%*c+ _tmp_159[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "genexp"));
             _res = genexp_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_157[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_159[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "genexp"));
     }
     { // 'True'
@@ -34526,18 +35125,18 @@ _tmp_157_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_157[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'True'"));
+        D(fprintf(stderr, "%*c> _tmp_159[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'True'"));
         Token * _keyword;
         if (
             (_keyword = _PyPegen_expect_token(p, 601))  // token='True'
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_157[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'True'"));
+            D(fprintf(stderr, "%*c+ _tmp_159[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'True'"));
             _res = _keyword;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_157[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_159[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'True'"));
     }
     { // 'None'
@@ -34545,18 +35144,18 @@ _tmp_157_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_157[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'None'"));
+        D(fprintf(stderr, "%*c> _tmp_159[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'None'"));
         Token * _keyword;
         if (
             (_keyword = _PyPegen_expect_token(p, 602))  // token='None'
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_157[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'None'"));
+            D(fprintf(stderr, "%*c+ _tmp_159[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'None'"));
             _res = _keyword;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_157[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_159[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'None'"));
     }
     { // 'False'
@@ -34564,18 +35163,18 @@ _tmp_157_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_157[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'False'"));
+        D(fprintf(stderr, "%*c> _tmp_159[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'False'"));
         Token * _keyword;
         if (
             (_keyword = _PyPegen_expect_token(p, 603))  // token='False'
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_157[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'False'"));
+            D(fprintf(stderr, "%*c+ _tmp_159[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'False'"));
             _res = _keyword;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_157[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_159[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'False'"));
     }
     _res = NULL;
@@ -34584,9 +35183,9 @@ _tmp_157_rule(Parser *p)
     return _res;
 }
 
-// _tmp_158: '=' | ':='
+// _tmp_160: '=' | ':='
 static void *
-_tmp_158_rule(Parser *p)
+_tmp_160_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -34603,18 +35202,18 @@ _tmp_158_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_158[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='"));
+        D(fprintf(stderr, "%*c> _tmp_160[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='"));
         Token * _literal;
         if (
             (_literal = _PyPegen_expect_token(p, 22))  // token='='
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_158[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'='"));
+            D(fprintf(stderr, "%*c+ _tmp_160[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'='"));
             _res = _literal;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_158[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_160[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'='"));
     }
     { // ':='
@@ -34622,18 +35221,18 @@ _tmp_158_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_158[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':='"));
+        D(fprintf(stderr, "%*c> _tmp_160[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':='"));
         Token * _literal;
         if (
             (_literal = _PyPegen_expect_token(p, 53))  // token=':='
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_158[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':='"));
+            D(fprintf(stderr, "%*c+ _tmp_160[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':='"));
             _res = _literal;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_158[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_160[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':='"));
     }
     _res = NULL;
@@ -34642,9 +35241,9 @@ _tmp_158_rule(Parser *p)
     return _res;
 }
 
-// _loop0_159: star_named_expressions
+// _loop0_161: star_named_expressions
 static asdl_seq *
-_loop0_159_rule(Parser *p)
+_loop0_161_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -34670,7 +35269,7 @@ _loop0_159_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop0_159[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expressions"));
+        D(fprintf(stderr, "%*c> _loop0_161[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_named_expressions"));
         asdl_expr_seq* star_named_expressions_var;
         while (
             (star_named_expressions_var = star_named_expressions_rule(p))  // star_named_expressions
@@ -34693,7 +35292,7 @@ _loop0_159_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop0_159[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop0_161[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_named_expressions"));
     }
     asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena);
@@ -34710,9 +35309,9 @@ _loop0_159_rule(Parser *p)
     return _seq;
 }
 
-// _loop0_160: (star_targets '=')
+// _loop0_162: (star_targets '=')
 static asdl_seq *
-_loop0_160_rule(Parser *p)
+_loop0_162_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -34738,13 +35337,13 @@ _loop0_160_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop0_160[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')"));
-        void *_tmp_259_var;
+        D(fprintf(stderr, "%*c> _loop0_162[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')"));
+        void *_tmp_261_var;
         while (
-            (_tmp_259_var = _tmp_259_rule(p))  // star_targets '='
+            (_tmp_261_var = _tmp_261_rule(p))  // star_targets '='
         )
         {
-            _res = _tmp_259_var;
+            _res = _tmp_261_var;
             if (_n == _children_capacity) {
                 _children_capacity *= 2;
                 void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *));
@@ -34761,7 +35360,7 @@ _loop0_160_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop0_160[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop0_162[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(star_targets '=')"));
     }
     asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena);
@@ -34778,9 +35377,9 @@ _loop0_160_rule(Parser *p)
     return _seq;
 }
 
-// _loop0_161: (star_targets '=')
+// _loop0_163: (star_targets '=')
 static asdl_seq *
-_loop0_161_rule(Parser *p)
+_loop0_163_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -34806,13 +35405,13 @@ _loop0_161_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop0_161[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')"));
-        void *_tmp_260_var;
+        D(fprintf(stderr, "%*c> _loop0_163[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(star_targets '=')"));
+        void *_tmp_262_var;
         while (
-            (_tmp_260_var = _tmp_260_rule(p))  // star_targets '='
+            (_tmp_262_var = _tmp_262_rule(p))  // star_targets '='
         )
         {
-            _res = _tmp_260_var;
+            _res = _tmp_262_var;
             if (_n == _children_capacity) {
                 _children_capacity *= 2;
                 void **_new_children = PyMem_Realloc(_children, _children_capacity*sizeof(void *));
@@ -34829,7 +35428,7 @@ _loop0_161_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop0_161[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop0_163[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(star_targets '=')"));
     }
     asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena);
@@ -34846,9 +35445,9 @@ _loop0_161_rule(Parser *p)
     return _seq;
 }
 
-// _tmp_162: yield_expr | star_expressions
+// _tmp_164: yield_expr | star_expressions
 static void *
-_tmp_162_rule(Parser *p)
+_tmp_164_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -34865,18 +35464,18 @@ _tmp_162_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_162[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr"));
+        D(fprintf(stderr, "%*c> _tmp_164[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr"));
         expr_ty yield_expr_var;
         if (
             (yield_expr_var = yield_expr_rule(p))  // yield_expr
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_162[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr"));
+            D(fprintf(stderr, "%*c+ _tmp_164[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr"));
             _res = yield_expr_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_162[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_164[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr"));
     }
     { // star_expressions
@@ -34884,18 +35483,18 @@ _tmp_162_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_162[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions"));
+        D(fprintf(stderr, "%*c> _tmp_164[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions"));
         expr_ty star_expressions_var;
         if (
             (star_expressions_var = star_expressions_rule(p))  // star_expressions
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_162[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions"));
+            D(fprintf(stderr, "%*c+ _tmp_164[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions"));
             _res = star_expressions_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_162[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_164[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions"));
     }
     _res = NULL;
@@ -34904,9 +35503,9 @@ _tmp_162_rule(Parser *p)
     return _res;
 }
 
-// _tmp_163: '[' | '(' | '{'
+// _tmp_165: '[' | '(' | '{'
 static void *
-_tmp_163_rule(Parser *p)
+_tmp_165_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -34923,18 +35522,18 @@ _tmp_163_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_163[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['"));
+        D(fprintf(stderr, "%*c> _tmp_165[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['"));
         Token * _literal;
         if (
             (_literal = _PyPegen_expect_token(p, 9))  // token='['
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_163[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['"));
+            D(fprintf(stderr, "%*c+ _tmp_165[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['"));
             _res = _literal;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_163[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_165[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'['"));
     }
     { // '('
@@ -34942,18 +35541,18 @@ _tmp_163_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_163[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'('"));
+        D(fprintf(stderr, "%*c> _tmp_165[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'('"));
         Token * _literal;
         if (
             (_literal = _PyPegen_expect_token(p, 7))  // token='('
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_163[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'('"));
+            D(fprintf(stderr, "%*c+ _tmp_165[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'('"));
             _res = _literal;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_163[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_165[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'('"));
     }
     { // '{'
@@ -34961,18 +35560,18 @@ _tmp_163_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_163[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'"));
+        D(fprintf(stderr, "%*c> _tmp_165[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'"));
         Token * _literal;
         if (
             (_literal = _PyPegen_expect_token(p, 25))  // token='{'
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_163[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{'"));
+            D(fprintf(stderr, "%*c+ _tmp_165[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{'"));
             _res = _literal;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_163[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_165[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{'"));
     }
     _res = NULL;
@@ -34981,9 +35580,9 @@ _tmp_163_rule(Parser *p)
     return _res;
 }
 
-// _tmp_164: '[' | '{'
+// _tmp_166: '[' | '{'
 static void *
-_tmp_164_rule(Parser *p)
+_tmp_166_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -35000,18 +35599,18 @@ _tmp_164_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_164[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['"));
+        D(fprintf(stderr, "%*c> _tmp_166[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['"));
         Token * _literal;
         if (
             (_literal = _PyPegen_expect_token(p, 9))  // token='['
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_164[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['"));
+            D(fprintf(stderr, "%*c+ _tmp_166[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['"));
             _res = _literal;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_164[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_166[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'['"));
     }
     { // '{'
@@ -35019,18 +35618,18 @@ _tmp_164_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_164[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'"));
+        D(fprintf(stderr, "%*c> _tmp_166[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'"));
         Token * _literal;
         if (
             (_literal = _PyPegen_expect_token(p, 25))  // token='{'
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_164[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{'"));
+            D(fprintf(stderr, "%*c+ _tmp_166[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{'"));
             _res = _literal;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_164[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_166[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{'"));
     }
     _res = NULL;
@@ -35039,9 +35638,9 @@ _tmp_164_rule(Parser *p)
     return _res;
 }
 
-// _tmp_165: '[' | '{'
+// _tmp_167: '[' | '{'
 static void *
-_tmp_165_rule(Parser *p)
+_tmp_167_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -35058,18 +35657,18 @@ _tmp_165_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_165[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['"));
+        D(fprintf(stderr, "%*c> _tmp_167[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'['"));
         Token * _literal;
         if (
             (_literal = _PyPegen_expect_token(p, 9))  // token='['
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_165[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['"));
+            D(fprintf(stderr, "%*c+ _tmp_167[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'['"));
             _res = _literal;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_165[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_167[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'['"));
     }
     { // '{'
@@ -35077,18 +35676,18 @@ _tmp_165_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_165[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'"));
+        D(fprintf(stderr, "%*c> _tmp_167[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'{'"));
         Token * _literal;
         if (
             (_literal = _PyPegen_expect_token(p, 25))  // token='{'
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_165[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{'"));
+            D(fprintf(stderr, "%*c+ _tmp_167[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'{'"));
             _res = _literal;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_165[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_167[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'{'"));
     }
     _res = NULL;
@@ -35097,9 +35696,9 @@ _tmp_165_rule(Parser *p)
     return _res;
 }
 
-// _tmp_166: slash_no_default | slash_with_default
+// _tmp_168: slash_no_default | slash_with_default
 static void *
-_tmp_166_rule(Parser *p)
+_tmp_168_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -35116,18 +35715,18 @@ _tmp_166_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_166[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_no_default"));
+        D(fprintf(stderr, "%*c> _tmp_168[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_no_default"));
         asdl_arg_seq* slash_no_default_var;
         if (
             (slash_no_default_var = slash_no_default_rule(p))  // slash_no_default
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_166[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_no_default"));
+            D(fprintf(stderr, "%*c+ _tmp_168[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_no_default"));
             _res = slash_no_default_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_166[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_168[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slash_no_default"));
     }
     { // slash_with_default
@@ -35135,18 +35734,18 @@ _tmp_166_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_166[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_with_default"));
+        D(fprintf(stderr, "%*c> _tmp_168[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_with_default"));
         SlashWithDefault* slash_with_default_var;
         if (
             (slash_with_default_var = slash_with_default_rule(p))  // slash_with_default
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_166[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_with_default"));
+            D(fprintf(stderr, "%*c+ _tmp_168[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_with_default"));
             _res = slash_with_default_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_166[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_168[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slash_with_default"));
     }
     _res = NULL;
@@ -35155,9 +35754,9 @@ _tmp_166_rule(Parser *p)
     return _res;
 }
 
-// _loop0_167: param_maybe_default
+// _loop0_169: param_maybe_default
 static asdl_seq *
-_loop0_167_rule(Parser *p)
+_loop0_169_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -35183,7 +35782,7 @@ _loop0_167_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop0_167[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default"));
+        D(fprintf(stderr, "%*c> _loop0_169[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default"));
         NameDefaultPair* param_maybe_default_var;
         while (
             (param_maybe_default_var = param_maybe_default_rule(p))  // param_maybe_default
@@ -35206,7 +35805,7 @@ _loop0_167_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop0_167[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop0_169[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default"));
     }
     asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena);
@@ -35223,9 +35822,9 @@ _loop0_167_rule(Parser *p)
     return _seq;
 }
 
-// _loop0_168: param_no_default
+// _loop0_170: param_no_default
 static asdl_seq *
-_loop0_168_rule(Parser *p)
+_loop0_170_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -35251,7 +35850,7 @@ _loop0_168_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop0_168[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default"));
+        D(fprintf(stderr, "%*c> _loop0_170[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default"));
         arg_ty param_no_default_var;
         while (
             (param_no_default_var = param_no_default_rule(p))  // param_no_default
@@ -35274,7 +35873,7 @@ _loop0_168_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop0_168[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop0_170[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default"));
     }
     asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena);
@@ -35291,9 +35890,9 @@ _loop0_168_rule(Parser *p)
     return _seq;
 }
 
-// _loop0_169: param_no_default
+// _loop0_171: param_no_default
 static asdl_seq *
-_loop0_169_rule(Parser *p)
+_loop0_171_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -35319,7 +35918,7 @@ _loop0_169_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop0_169[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default"));
+        D(fprintf(stderr, "%*c> _loop0_171[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default"));
         arg_ty param_no_default_var;
         while (
             (param_no_default_var = param_no_default_rule(p))  // param_no_default
@@ -35342,7 +35941,7 @@ _loop0_169_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop0_169[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop0_171[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default"));
     }
     asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena);
@@ -35359,9 +35958,9 @@ _loop0_169_rule(Parser *p)
     return _seq;
 }
 
-// _loop1_170: param_no_default
+// _loop1_172: param_no_default
 static asdl_seq *
-_loop1_170_rule(Parser *p)
+_loop1_172_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -35387,7 +35986,7 @@ _loop1_170_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop1_170[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default"));
+        D(fprintf(stderr, "%*c> _loop1_172[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default"));
         arg_ty param_no_default_var;
         while (
             (param_no_default_var = param_no_default_rule(p))  // param_no_default
@@ -35410,7 +36009,7 @@ _loop1_170_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop1_170[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop1_172[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default"));
     }
     if (_n == 0 || p->error_indicator) {
@@ -35432,9 +36031,9 @@ _loop1_170_rule(Parser *p)
     return _seq;
 }
 
-// _tmp_171: slash_no_default | slash_with_default
+// _tmp_173: slash_no_default | slash_with_default
 static void *
-_tmp_171_rule(Parser *p)
+_tmp_173_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -35451,18 +36050,18 @@ _tmp_171_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_171[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_no_default"));
+        D(fprintf(stderr, "%*c> _tmp_173[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_no_default"));
         asdl_arg_seq* slash_no_default_var;
         if (
             (slash_no_default_var = slash_no_default_rule(p))  // slash_no_default
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_171[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_no_default"));
+            D(fprintf(stderr, "%*c+ _tmp_173[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_no_default"));
             _res = slash_no_default_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_171[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_173[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slash_no_default"));
     }
     { // slash_with_default
@@ -35470,18 +36069,18 @@ _tmp_171_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_171[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_with_default"));
+        D(fprintf(stderr, "%*c> _tmp_173[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slash_with_default"));
         SlashWithDefault* slash_with_default_var;
         if (
             (slash_with_default_var = slash_with_default_rule(p))  // slash_with_default
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_171[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_with_default"));
+            D(fprintf(stderr, "%*c+ _tmp_173[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slash_with_default"));
             _res = slash_with_default_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_171[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_173[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slash_with_default"));
     }
     _res = NULL;
@@ -35490,9 +36089,9 @@ _tmp_171_rule(Parser *p)
     return _res;
 }
 
-// _loop0_172: param_maybe_default
+// _loop0_174: param_maybe_default
 static asdl_seq *
-_loop0_172_rule(Parser *p)
+_loop0_174_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -35518,7 +36117,7 @@ _loop0_172_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop0_172[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default"));
+        D(fprintf(stderr, "%*c> _loop0_174[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default"));
         NameDefaultPair* param_maybe_default_var;
         while (
             (param_maybe_default_var = param_maybe_default_rule(p))  // param_maybe_default
@@ -35541,7 +36140,7 @@ _loop0_172_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop0_172[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop0_174[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default"));
     }
     asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena);
@@ -35558,9 +36157,9 @@ _loop0_172_rule(Parser *p)
     return _seq;
 }
 
-// _tmp_173: ',' | param_no_default
+// _tmp_175: ',' | param_no_default
 static void *
-_tmp_173_rule(Parser *p)
+_tmp_175_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -35577,18 +36176,18 @@ _tmp_173_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_173[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','"));
+        D(fprintf(stderr, "%*c> _tmp_175[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','"));
         Token * _literal;
         if (
             (_literal = _PyPegen_expect_token(p, 12))  // token=','
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_173[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','"));
+            D(fprintf(stderr, "%*c+ _tmp_175[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','"));
             _res = _literal;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_173[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_175[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','"));
     }
     { // param_no_default
@@ -35596,18 +36195,18 @@ _tmp_173_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_173[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default"));
+        D(fprintf(stderr, "%*c> _tmp_175[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default"));
         arg_ty param_no_default_var;
         if (
             (param_no_default_var = param_no_default_rule(p))  // param_no_default
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_173[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default"));
+            D(fprintf(stderr, "%*c+ _tmp_175[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default"));
             _res = param_no_default_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_173[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_175[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default"));
     }
     _res = NULL;
@@ -35616,9 +36215,9 @@ _tmp_173_rule(Parser *p)
     return _res;
 }
 
-// _loop0_174: param_maybe_default
+// _loop0_176: param_maybe_default
 static asdl_seq *
-_loop0_174_rule(Parser *p)
+_loop0_176_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -35644,7 +36243,7 @@ _loop0_174_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop0_174[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default"));
+        D(fprintf(stderr, "%*c> _loop0_176[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default"));
         NameDefaultPair* param_maybe_default_var;
         while (
             (param_maybe_default_var = param_maybe_default_rule(p))  // param_maybe_default
@@ -35667,7 +36266,7 @@ _loop0_174_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop0_174[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop0_176[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default"));
     }
     asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena);
@@ -35684,9 +36283,9 @@ _loop0_174_rule(Parser *p)
     return _seq;
 }
 
-// _loop1_175: param_maybe_default
+// _loop1_177: param_maybe_default
 static asdl_seq *
-_loop1_175_rule(Parser *p)
+_loop1_177_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -35712,7 +36311,7 @@ _loop1_175_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop1_175[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default"));
+        D(fprintf(stderr, "%*c> _loop1_177[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default"));
         NameDefaultPair* param_maybe_default_var;
         while (
             (param_maybe_default_var = param_maybe_default_rule(p))  // param_maybe_default
@@ -35735,7 +36334,7 @@ _loop1_175_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop1_175[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop1_177[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default"));
     }
     if (_n == 0 || p->error_indicator) {
@@ -35757,9 +36356,9 @@ _loop1_175_rule(Parser *p)
     return _seq;
 }
 
-// _tmp_176: ')' | ','
+// _tmp_178: ')' | ','
 static void *
-_tmp_176_rule(Parser *p)
+_tmp_178_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -35776,18 +36375,18 @@ _tmp_176_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_176[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'"));
+        D(fprintf(stderr, "%*c> _tmp_178[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'"));
         Token * _literal;
         if (
             (_literal = _PyPegen_expect_token(p, 8))  // token=')'
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_176[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'"));
+            D(fprintf(stderr, "%*c+ _tmp_178[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'"));
             _res = _literal;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_176[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_178[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'"));
     }
     { // ','
@@ -35795,18 +36394,18 @@ _tmp_176_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_176[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','"));
+        D(fprintf(stderr, "%*c> _tmp_178[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','"));
         Token * _literal;
         if (
             (_literal = _PyPegen_expect_token(p, 12))  // token=','
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_176[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','"));
+            D(fprintf(stderr, "%*c+ _tmp_178[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','"));
             _res = _literal;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_176[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_178[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','"));
     }
     _res = NULL;
@@ -35815,9 +36414,9 @@ _tmp_176_rule(Parser *p)
     return _res;
 }
 
-// _tmp_177: ')' | ',' (')' | '**')
+// _tmp_179: ')' | ',' (')' | '**')
 static void *
-_tmp_177_rule(Parser *p)
+_tmp_179_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -35834,18 +36433,18 @@ _tmp_177_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_177[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'"));
+        D(fprintf(stderr, "%*c> _tmp_179[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'"));
         Token * _literal;
         if (
             (_literal = _PyPegen_expect_token(p, 8))  // token=')'
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_177[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'"));
+            D(fprintf(stderr, "%*c+ _tmp_179[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'"));
             _res = _literal;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_177[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_179[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'"));
     }
     { // ',' (')' | '**')
@@ -35853,21 +36452,21 @@ _tmp_177_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_177[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')"));
+        D(fprintf(stderr, "%*c> _tmp_179[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')"));
         Token * _literal;
-        void *_tmp_261_var;
+        void *_tmp_263_var;
         if (
             (_literal = _PyPegen_expect_token(p, 12))  // token=','
             &&
-            (_tmp_261_var = _tmp_261_rule(p))  // ')' | '**'
+            (_tmp_263_var = _tmp_263_rule(p))  // ')' | '**'
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_177[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')"));
-            _res = _PyPegen_dummy_name(p, _literal, _tmp_261_var);
+            D(fprintf(stderr, "%*c+ _tmp_179[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (')' | '**')"));
+            _res = _PyPegen_dummy_name(p, _literal, _tmp_263_var);
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_177[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_179[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (')' | '**')"));
     }
     _res = NULL;
@@ -35876,9 +36475,9 @@ _tmp_177_rule(Parser *p)
     return _res;
 }
 
-// _tmp_178: param_no_default | ','
+// _tmp_180: param_no_default | ','
 static void *
-_tmp_178_rule(Parser *p)
+_tmp_180_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -35895,18 +36494,18 @@ _tmp_178_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_178[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default"));
+        D(fprintf(stderr, "%*c> _tmp_180[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default"));
         arg_ty param_no_default_var;
         if (
             (param_no_default_var = param_no_default_rule(p))  // param_no_default
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_178[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default"));
+            D(fprintf(stderr, "%*c+ _tmp_180[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default"));
             _res = param_no_default_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_178[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_180[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default"));
     }
     { // ','
@@ -35914,18 +36513,18 @@ _tmp_178_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_178[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','"));
+        D(fprintf(stderr, "%*c> _tmp_180[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','"));
         Token * _literal;
         if (
             (_literal = _PyPegen_expect_token(p, 12))  // token=','
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_178[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','"));
+            D(fprintf(stderr, "%*c+ _tmp_180[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','"));
             _res = _literal;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_178[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_180[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','"));
     }
     _res = NULL;
@@ -35934,9 +36533,9 @@ _tmp_178_rule(Parser *p)
     return _res;
 }
 
-// _loop0_179: param_maybe_default
+// _loop0_181: param_maybe_default
 static asdl_seq *
-_loop0_179_rule(Parser *p)
+_loop0_181_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -35962,7 +36561,7 @@ _loop0_179_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop0_179[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default"));
+        D(fprintf(stderr, "%*c> _loop0_181[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_maybe_default"));
         NameDefaultPair* param_maybe_default_var;
         while (
             (param_maybe_default_var = param_maybe_default_rule(p))  // param_maybe_default
@@ -35985,7 +36584,7 @@ _loop0_179_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop0_179[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop0_181[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_maybe_default"));
     }
     asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena);
@@ -36002,9 +36601,9 @@ _loop0_179_rule(Parser *p)
     return _seq;
 }
 
-// _tmp_180: param_no_default | ','
+// _tmp_182: param_no_default | ','
 static void *
-_tmp_180_rule(Parser *p)
+_tmp_182_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -36021,18 +36620,18 @@ _tmp_180_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_180[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default"));
+        D(fprintf(stderr, "%*c> _tmp_182[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_no_default"));
         arg_ty param_no_default_var;
         if (
             (param_no_default_var = param_no_default_rule(p))  // param_no_default
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_180[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default"));
+            D(fprintf(stderr, "%*c+ _tmp_182[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "param_no_default"));
             _res = param_no_default_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_180[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_182[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_no_default"));
     }
     { // ','
@@ -36040,18 +36639,18 @@ _tmp_180_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_180[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','"));
+        D(fprintf(stderr, "%*c> _tmp_182[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','"));
         Token * _literal;
         if (
             (_literal = _PyPegen_expect_token(p, 12))  // token=','
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_180[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','"));
+            D(fprintf(stderr, "%*c+ _tmp_182[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','"));
             _res = _literal;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_180[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_182[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','"));
     }
     _res = NULL;
@@ -36060,9 +36659,9 @@ _tmp_180_rule(Parser *p)
     return _res;
 }
 
-// _tmp_181: '*' | '**' | '/'
+// _tmp_183: '*' | '**' | '/'
 static void *
-_tmp_181_rule(Parser *p)
+_tmp_183_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -36079,18 +36678,18 @@ _tmp_181_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_181[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*'"));
+        D(fprintf(stderr, "%*c> _tmp_183[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*'"));
         Token * _literal;
         if (
             (_literal = _PyPegen_expect_token(p, 16))  // token='*'
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_181[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*'"));
+            D(fprintf(stderr, "%*c+ _tmp_183[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*'"));
             _res = _literal;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_181[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_183[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*'"));
     }
     { // '**'
@@ -36098,18 +36697,18 @@ _tmp_181_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_181[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'"));
+        D(fprintf(stderr, "%*c> _tmp_183[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'"));
         Token * _literal;
         if (
             (_literal = _PyPegen_expect_token(p, 35))  // token='**'
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_181[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'"));
+            D(fprintf(stderr, "%*c+ _tmp_183[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'"));
             _res = _literal;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_181[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_183[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**'"));
     }
     { // '/'
@@ -36117,18 +36716,18 @@ _tmp_181_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_181[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'/'"));
+        D(fprintf(stderr, "%*c> _tmp_183[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'/'"));
         Token * _literal;
         if (
             (_literal = _PyPegen_expect_token(p, 17))  // token='/'
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_181[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'/'"));
+            D(fprintf(stderr, "%*c+ _tmp_183[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'/'"));
             _res = _literal;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_181[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_183[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'/'"));
     }
     _res = NULL;
@@ -36137,9 +36736,9 @@ _tmp_181_rule(Parser *p)
     return _res;
 }
 
-// _loop1_182: param_with_default
+// _loop1_184: param_with_default
 static asdl_seq *
-_loop1_182_rule(Parser *p)
+_loop1_184_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -36165,7 +36764,7 @@ _loop1_182_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop1_182[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default"));
+        D(fprintf(stderr, "%*c> _loop1_184[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "param_with_default"));
         NameDefaultPair* param_with_default_var;
         while (
             (param_with_default_var = param_with_default_rule(p))  // param_with_default
@@ -36188,7 +36787,7 @@ _loop1_182_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop1_182[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop1_184[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "param_with_default"));
     }
     if (_n == 0 || p->error_indicator) {
@@ -36210,9 +36809,9 @@ _loop1_182_rule(Parser *p)
     return _seq;
 }
 
-// _tmp_183: lambda_slash_no_default | lambda_slash_with_default
+// _tmp_185: lambda_slash_no_default | lambda_slash_with_default
 static void *
-_tmp_183_rule(Parser *p)
+_tmp_185_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -36229,18 +36828,18 @@ _tmp_183_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_183[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default"));
+        D(fprintf(stderr, "%*c> _tmp_185[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default"));
         asdl_arg_seq* lambda_slash_no_default_var;
         if (
             (lambda_slash_no_default_var = lambda_slash_no_default_rule(p))  // lambda_slash_no_default
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_183[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default"));
+            D(fprintf(stderr, "%*c+ _tmp_185[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default"));
             _res = lambda_slash_no_default_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_183[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_185[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_slash_no_default"));
     }
     { // lambda_slash_with_default
@@ -36248,18 +36847,18 @@ _tmp_183_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_183[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default"));
+        D(fprintf(stderr, "%*c> _tmp_185[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default"));
         SlashWithDefault* lambda_slash_with_default_var;
         if (
             (lambda_slash_with_default_var = lambda_slash_with_default_rule(p))  // lambda_slash_with_default
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_183[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default"));
+            D(fprintf(stderr, "%*c+ _tmp_185[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default"));
             _res = lambda_slash_with_default_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_183[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_185[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_slash_with_default"));
     }
     _res = NULL;
@@ -36268,9 +36867,9 @@ _tmp_183_rule(Parser *p)
     return _res;
 }
 
-// _loop0_184: lambda_param_maybe_default
+// _loop0_186: lambda_param_maybe_default
 static asdl_seq *
-_loop0_184_rule(Parser *p)
+_loop0_186_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -36296,7 +36895,7 @@ _loop0_184_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop0_184[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default"));
+        D(fprintf(stderr, "%*c> _loop0_186[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default"));
         NameDefaultPair* lambda_param_maybe_default_var;
         while (
             (lambda_param_maybe_default_var = lambda_param_maybe_default_rule(p))  // lambda_param_maybe_default
@@ -36319,7 +36918,7 @@ _loop0_184_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop0_184[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop0_186[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default"));
     }
     asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena);
@@ -36336,9 +36935,9 @@ _loop0_184_rule(Parser *p)
     return _seq;
 }
 
-// _loop0_185: lambda_param_no_default
+// _loop0_187: lambda_param_no_default
 static asdl_seq *
-_loop0_185_rule(Parser *p)
+_loop0_187_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -36364,7 +36963,7 @@ _loop0_185_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop0_185[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default"));
+        D(fprintf(stderr, "%*c> _loop0_187[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default"));
         arg_ty lambda_param_no_default_var;
         while (
             (lambda_param_no_default_var = lambda_param_no_default_rule(p))  // lambda_param_no_default
@@ -36387,7 +36986,7 @@ _loop0_185_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop0_185[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop0_187[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default"));
     }
     asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena);
@@ -36404,9 +37003,9 @@ _loop0_185_rule(Parser *p)
     return _seq;
 }
 
-// _loop0_186: lambda_param_no_default
+// _loop0_188: lambda_param_no_default
 static asdl_seq *
-_loop0_186_rule(Parser *p)
+_loop0_188_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -36432,7 +37031,7 @@ _loop0_186_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop0_186[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default"));
+        D(fprintf(stderr, "%*c> _loop0_188[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default"));
         arg_ty lambda_param_no_default_var;
         while (
             (lambda_param_no_default_var = lambda_param_no_default_rule(p))  // lambda_param_no_default
@@ -36455,7 +37054,7 @@ _loop0_186_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop0_186[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop0_188[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default"));
     }
     asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena);
@@ -36472,9 +37071,9 @@ _loop0_186_rule(Parser *p)
     return _seq;
 }
 
-// _loop0_188: ',' lambda_param
+// _loop0_190: ',' lambda_param
 static asdl_seq *
-_loop0_188_rule(Parser *p)
+_loop0_190_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -36500,7 +37099,7 @@ _loop0_188_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop0_188[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' lambda_param"));
+        D(fprintf(stderr, "%*c> _loop0_190[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' lambda_param"));
         Token * _literal;
         arg_ty elem;
         while (
@@ -36532,7 +37131,7 @@ _loop0_188_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop0_188[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop0_190[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' lambda_param"));
     }
     asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena);
@@ -36549,9 +37148,9 @@ _loop0_188_rule(Parser *p)
     return _seq;
 }
 
-// _gather_187: lambda_param _loop0_188
+// _gather_189: lambda_param _loop0_190
 static asdl_seq *
-_gather_187_rule(Parser *p)
+_gather_189_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -36563,27 +37162,27 @@ _gather_187_rule(Parser *p)
     }
     asdl_seq * _res = NULL;
     int _mark = p->mark;
-    { // lambda_param _loop0_188
+    { // lambda_param _loop0_190
         if (p->error_indicator) {
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _gather_187[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param _loop0_188"));
+        D(fprintf(stderr, "%*c> _gather_189[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param _loop0_190"));
         arg_ty elem;
         asdl_seq * seq;
         if (
             (elem = lambda_param_rule(p))  // lambda_param
             &&
-            (seq = _loop0_188_rule(p))  // _loop0_188
+            (seq = _loop0_190_rule(p))  // _loop0_190
         )
         {
-            D(fprintf(stderr, "%*c+ _gather_187[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param _loop0_188"));
+            D(fprintf(stderr, "%*c+ _gather_189[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param _loop0_190"));
             _res = _PyPegen_seq_insert_in_front(p, elem, seq);
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _gather_187[%d-%d]: %s failed!\n", p->level, ' ',
-                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param _loop0_188"));
+        D(fprintf(stderr, "%*c%s _gather_189[%d-%d]: %s failed!\n", p->level, ' ',
+                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param _loop0_190"));
     }
     _res = NULL;
   done:
@@ -36591,9 +37190,9 @@ _gather_187_rule(Parser *p)
     return _res;
 }
 
-// _tmp_189: lambda_slash_no_default | lambda_slash_with_default
+// _tmp_191: lambda_slash_no_default | lambda_slash_with_default
 static void *
-_tmp_189_rule(Parser *p)
+_tmp_191_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -36610,18 +37209,18 @@ _tmp_189_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_189[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default"));
+        D(fprintf(stderr, "%*c> _tmp_191[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default"));
         asdl_arg_seq* lambda_slash_no_default_var;
         if (
             (lambda_slash_no_default_var = lambda_slash_no_default_rule(p))  // lambda_slash_no_default
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_189[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default"));
+            D(fprintf(stderr, "%*c+ _tmp_191[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_no_default"));
             _res = lambda_slash_no_default_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_189[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_191[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_slash_no_default"));
     }
     { // lambda_slash_with_default
@@ -36629,18 +37228,18 @@ _tmp_189_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_189[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default"));
+        D(fprintf(stderr, "%*c> _tmp_191[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default"));
         SlashWithDefault* lambda_slash_with_default_var;
         if (
             (lambda_slash_with_default_var = lambda_slash_with_default_rule(p))  // lambda_slash_with_default
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_189[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default"));
+            D(fprintf(stderr, "%*c+ _tmp_191[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_slash_with_default"));
             _res = lambda_slash_with_default_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_189[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_191[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_slash_with_default"));
     }
     _res = NULL;
@@ -36649,9 +37248,9 @@ _tmp_189_rule(Parser *p)
     return _res;
 }
 
-// _loop0_190: lambda_param_maybe_default
+// _loop0_192: lambda_param_maybe_default
 static asdl_seq *
-_loop0_190_rule(Parser *p)
+_loop0_192_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -36677,7 +37276,7 @@ _loop0_190_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop0_190[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default"));
+        D(fprintf(stderr, "%*c> _loop0_192[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default"));
         NameDefaultPair* lambda_param_maybe_default_var;
         while (
             (lambda_param_maybe_default_var = lambda_param_maybe_default_rule(p))  // lambda_param_maybe_default
@@ -36700,7 +37299,7 @@ _loop0_190_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop0_190[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop0_192[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default"));
     }
     asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena);
@@ -36717,9 +37316,9 @@ _loop0_190_rule(Parser *p)
     return _seq;
 }
 
-// _tmp_191: ',' | lambda_param_no_default
+// _tmp_193: ',' | lambda_param_no_default
 static void *
-_tmp_191_rule(Parser *p)
+_tmp_193_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -36736,18 +37335,18 @@ _tmp_191_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_191[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','"));
+        D(fprintf(stderr, "%*c> _tmp_193[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','"));
         Token * _literal;
         if (
             (_literal = _PyPegen_expect_token(p, 12))  // token=','
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_191[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','"));
+            D(fprintf(stderr, "%*c+ _tmp_193[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','"));
             _res = _literal;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_191[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_193[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','"));
     }
     { // lambda_param_no_default
@@ -36755,18 +37354,18 @@ _tmp_191_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_191[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default"));
+        D(fprintf(stderr, "%*c> _tmp_193[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default"));
         arg_ty lambda_param_no_default_var;
         if (
             (lambda_param_no_default_var = lambda_param_no_default_rule(p))  // lambda_param_no_default
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_191[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default"));
+            D(fprintf(stderr, "%*c+ _tmp_193[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default"));
             _res = lambda_param_no_default_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_191[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_193[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default"));
     }
     _res = NULL;
@@ -36775,9 +37374,9 @@ _tmp_191_rule(Parser *p)
     return _res;
 }
 
-// _loop0_192: lambda_param_maybe_default
+// _loop0_194: lambda_param_maybe_default
 static asdl_seq *
-_loop0_192_rule(Parser *p)
+_loop0_194_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -36803,7 +37402,7 @@ _loop0_192_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop0_192[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default"));
+        D(fprintf(stderr, "%*c> _loop0_194[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default"));
         NameDefaultPair* lambda_param_maybe_default_var;
         while (
             (lambda_param_maybe_default_var = lambda_param_maybe_default_rule(p))  // lambda_param_maybe_default
@@ -36826,7 +37425,7 @@ _loop0_192_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop0_192[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop0_194[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default"));
     }
     asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena);
@@ -36843,9 +37442,9 @@ _loop0_192_rule(Parser *p)
     return _seq;
 }
 
-// _loop1_193: lambda_param_maybe_default
+// _loop1_195: lambda_param_maybe_default
 static asdl_seq *
-_loop1_193_rule(Parser *p)
+_loop1_195_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -36871,7 +37470,7 @@ _loop1_193_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop1_193[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default"));
+        D(fprintf(stderr, "%*c> _loop1_195[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default"));
         NameDefaultPair* lambda_param_maybe_default_var;
         while (
             (lambda_param_maybe_default_var = lambda_param_maybe_default_rule(p))  // lambda_param_maybe_default
@@ -36894,7 +37493,7 @@ _loop1_193_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop1_193[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop1_195[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default"));
     }
     if (_n == 0 || p->error_indicator) {
@@ -36916,9 +37515,9 @@ _loop1_193_rule(Parser *p)
     return _seq;
 }
 
-// _loop1_194: lambda_param_with_default
+// _loop1_196: lambda_param_with_default
 static asdl_seq *
-_loop1_194_rule(Parser *p)
+_loop1_196_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -36944,7 +37543,7 @@ _loop1_194_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop1_194[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default"));
+        D(fprintf(stderr, "%*c> _loop1_196[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_with_default"));
         NameDefaultPair* lambda_param_with_default_var;
         while (
             (lambda_param_with_default_var = lambda_param_with_default_rule(p))  // lambda_param_with_default
@@ -36967,7 +37566,7 @@ _loop1_194_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop1_194[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop1_196[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_with_default"));
     }
     if (_n == 0 || p->error_indicator) {
@@ -36989,9 +37588,9 @@ _loop1_194_rule(Parser *p)
     return _seq;
 }
 
-// _tmp_195: ':' | ',' (':' | '**')
+// _tmp_197: ':' | ',' (':' | '**')
 static void *
-_tmp_195_rule(Parser *p)
+_tmp_197_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -37008,18 +37607,18 @@ _tmp_195_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_195[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'"));
+        D(fprintf(stderr, "%*c> _tmp_197[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'"));
         Token * _literal;
         if (
             (_literal = _PyPegen_expect_token(p, 11))  // token=':'
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_195[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'"));
+            D(fprintf(stderr, "%*c+ _tmp_197[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'"));
             _res = _literal;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_195[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_197[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'"));
     }
     { // ',' (':' | '**')
@@ -37027,21 +37626,21 @@ _tmp_195_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_195[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (':' | '**')"));
+        D(fprintf(stderr, "%*c> _tmp_197[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (':' | '**')"));
         Token * _literal;
-        void *_tmp_262_var;
+        void *_tmp_264_var;
         if (
             (_literal = _PyPegen_expect_token(p, 12))  // token=','
             &&
-            (_tmp_262_var = _tmp_262_rule(p))  // ':' | '**'
+            (_tmp_264_var = _tmp_264_rule(p))  // ':' | '**'
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_195[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (':' | '**')"));
-            _res = _PyPegen_dummy_name(p, _literal, _tmp_262_var);
+            D(fprintf(stderr, "%*c+ _tmp_197[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' (':' | '**')"));
+            _res = _PyPegen_dummy_name(p, _literal, _tmp_264_var);
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_195[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_197[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (':' | '**')"));
     }
     _res = NULL;
@@ -37050,9 +37649,9 @@ _tmp_195_rule(Parser *p)
     return _res;
 }
 
-// _tmp_196: lambda_param_no_default | ','
+// _tmp_198: lambda_param_no_default | ','
 static void *
-_tmp_196_rule(Parser *p)
+_tmp_198_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -37069,18 +37668,18 @@ _tmp_196_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_196[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default"));
+        D(fprintf(stderr, "%*c> _tmp_198[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default"));
         arg_ty lambda_param_no_default_var;
         if (
             (lambda_param_no_default_var = lambda_param_no_default_rule(p))  // lambda_param_no_default
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_196[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default"));
+            D(fprintf(stderr, "%*c+ _tmp_198[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default"));
             _res = lambda_param_no_default_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_196[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_198[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default"));
     }
     { // ','
@@ -37088,18 +37687,18 @@ _tmp_196_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_196[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','"));
+        D(fprintf(stderr, "%*c> _tmp_198[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','"));
         Token * _literal;
         if (
             (_literal = _PyPegen_expect_token(p, 12))  // token=','
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_196[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','"));
+            D(fprintf(stderr, "%*c+ _tmp_198[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','"));
             _res = _literal;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_196[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_198[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','"));
     }
     _res = NULL;
@@ -37108,9 +37707,9 @@ _tmp_196_rule(Parser *p)
     return _res;
 }
 
-// _loop0_197: lambda_param_maybe_default
+// _loop0_199: lambda_param_maybe_default
 static asdl_seq *
-_loop0_197_rule(Parser *p)
+_loop0_199_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -37136,7 +37735,7 @@ _loop0_197_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop0_197[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default"));
+        D(fprintf(stderr, "%*c> _loop0_199[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_maybe_default"));
         NameDefaultPair* lambda_param_maybe_default_var;
         while (
             (lambda_param_maybe_default_var = lambda_param_maybe_default_rule(p))  // lambda_param_maybe_default
@@ -37159,7 +37758,7 @@ _loop0_197_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop0_197[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop0_199[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_maybe_default"));
     }
     asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena);
@@ -37176,9 +37775,9 @@ _loop0_197_rule(Parser *p)
     return _seq;
 }
 
-// _tmp_198: lambda_param_no_default | ','
+// _tmp_200: lambda_param_no_default | ','
 static void *
-_tmp_198_rule(Parser *p)
+_tmp_200_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -37195,18 +37794,18 @@ _tmp_198_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_198[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default"));
+        D(fprintf(stderr, "%*c> _tmp_200[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default"));
         arg_ty lambda_param_no_default_var;
         if (
             (lambda_param_no_default_var = lambda_param_no_default_rule(p))  // lambda_param_no_default
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_198[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default"));
+            D(fprintf(stderr, "%*c+ _tmp_200[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "lambda_param_no_default"));
             _res = lambda_param_no_default_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_198[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_200[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "lambda_param_no_default"));
     }
     { // ','
@@ -37214,18 +37813,18 @@ _tmp_198_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_198[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','"));
+        D(fprintf(stderr, "%*c> _tmp_200[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','"));
         Token * _literal;
         if (
             (_literal = _PyPegen_expect_token(p, 12))  // token=','
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_198[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','"));
+            D(fprintf(stderr, "%*c+ _tmp_200[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','"));
             _res = _literal;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_198[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_200[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','"));
     }
     _res = NULL;
@@ -37234,9 +37833,9 @@ _tmp_198_rule(Parser *p)
     return _res;
 }
 
-// _tmp_199: '*' | '**' | '/'
+// _tmp_201: '*' | '**' | '/'
 static void *
-_tmp_199_rule(Parser *p)
+_tmp_201_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -37253,18 +37852,18 @@ _tmp_199_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_199[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*'"));
+        D(fprintf(stderr, "%*c> _tmp_201[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'*'"));
         Token * _literal;
         if (
             (_literal = _PyPegen_expect_token(p, 16))  // token='*'
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_199[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*'"));
+            D(fprintf(stderr, "%*c+ _tmp_201[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'*'"));
             _res = _literal;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_199[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_201[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'*'"));
     }
     { // '**'
@@ -37272,18 +37871,18 @@ _tmp_199_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_199[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'"));
+        D(fprintf(stderr, "%*c> _tmp_201[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'"));
         Token * _literal;
         if (
             (_literal = _PyPegen_expect_token(p, 35))  // token='**'
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_199[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'"));
+            D(fprintf(stderr, "%*c+ _tmp_201[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'"));
             _res = _literal;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_199[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_201[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**'"));
     }
     { // '/'
@@ -37291,18 +37890,18 @@ _tmp_199_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_199[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'/'"));
+        D(fprintf(stderr, "%*c> _tmp_201[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'/'"));
         Token * _literal;
         if (
             (_literal = _PyPegen_expect_token(p, 17))  // token='/'
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_199[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'/'"));
+            D(fprintf(stderr, "%*c+ _tmp_201[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'/'"));
             _res = _literal;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_199[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_201[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'/'"));
     }
     _res = NULL;
@@ -37311,9 +37910,9 @@ _tmp_199_rule(Parser *p)
     return _res;
 }
 
-// _tmp_200: ',' | ')' | ':'
+// _tmp_202: ',' | ')' | ':'
 static void *
-_tmp_200_rule(Parser *p)
+_tmp_202_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -37330,18 +37929,18 @@ _tmp_200_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_200[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','"));
+        D(fprintf(stderr, "%*c> _tmp_202[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','"));
         Token * _literal;
         if (
             (_literal = _PyPegen_expect_token(p, 12))  // token=','
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_200[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','"));
+            D(fprintf(stderr, "%*c+ _tmp_202[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','"));
             _res = _literal;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_200[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_202[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','"));
     }
     { // ')'
@@ -37349,18 +37948,18 @@ _tmp_200_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_200[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'"));
+        D(fprintf(stderr, "%*c> _tmp_202[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'"));
         Token * _literal;
         if (
             (_literal = _PyPegen_expect_token(p, 8))  // token=')'
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_200[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'"));
+            D(fprintf(stderr, "%*c+ _tmp_202[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'"));
             _res = _literal;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_200[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_202[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'"));
     }
     { // ':'
@@ -37368,18 +37967,18 @@ _tmp_200_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_200[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'"));
+        D(fprintf(stderr, "%*c> _tmp_202[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'"));
         Token * _literal;
         if (
             (_literal = _PyPegen_expect_token(p, 11))  // token=':'
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_200[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'"));
+            D(fprintf(stderr, "%*c+ _tmp_202[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'"));
             _res = _literal;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_200[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_202[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'"));
     }
     _res = NULL;
@@ -37388,9 +37987,9 @@ _tmp_200_rule(Parser *p)
     return _res;
 }
 
-// _loop0_202: ',' (expression ['as' star_target])
+// _loop0_204: ',' (expression ['as' star_target])
 static asdl_seq *
-_loop0_202_rule(Parser *p)
+_loop0_204_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -37416,13 +38015,13 @@ _loop0_202_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop0_202[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expression ['as' star_target])"));
+        D(fprintf(stderr, "%*c> _loop0_204[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expression ['as' star_target])"));
         Token * _literal;
         void *elem;
         while (
             (_literal = _PyPegen_expect_token(p, 12))  // token=','
             &&
-            (elem = _tmp_263_rule(p))  // expression ['as' star_target]
+            (elem = _tmp_265_rule(p))  // expression ['as' star_target]
         )
         {
             _res = elem;
@@ -37448,7 +38047,7 @@ _loop0_202_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop0_202[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop0_204[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (expression ['as' star_target])"));
     }
     asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena);
@@ -37465,9 +38064,9 @@ _loop0_202_rule(Parser *p)
     return _seq;
 }
 
-// _gather_201: (expression ['as' star_target]) _loop0_202
+// _gather_203: (expression ['as' star_target]) _loop0_204
 static asdl_seq *
-_gather_201_rule(Parser *p)
+_gather_203_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -37479,27 +38078,27 @@ _gather_201_rule(Parser *p)
     }
     asdl_seq * _res = NULL;
     int _mark = p->mark;
-    { // (expression ['as' star_target]) _loop0_202
+    { // (expression ['as' star_target]) _loop0_204
         if (p->error_indicator) {
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _gather_201[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_202"));
+        D(fprintf(stderr, "%*c> _gather_203[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_204"));
         void *elem;
         asdl_seq * seq;
         if (
-            (elem = _tmp_263_rule(p))  // expression ['as' star_target]
+            (elem = _tmp_265_rule(p))  // expression ['as' star_target]
             &&
-            (seq = _loop0_202_rule(p))  // _loop0_202
+            (seq = _loop0_204_rule(p))  // _loop0_204
         )
         {
-            D(fprintf(stderr, "%*c+ _gather_201[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_202"));
+            D(fprintf(stderr, "%*c+ _gather_203[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_204"));
             _res = _PyPegen_seq_insert_in_front(p, elem, seq);
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _gather_201[%d-%d]: %s failed!\n", p->level, ' ',
-                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expression ['as' star_target]) _loop0_202"));
+        D(fprintf(stderr, "%*c%s _gather_203[%d-%d]: %s failed!\n", p->level, ' ',
+                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expression ['as' star_target]) _loop0_204"));
     }
     _res = NULL;
   done:
@@ -37507,9 +38106,9 @@ _gather_201_rule(Parser *p)
     return _res;
 }
 
-// _loop0_204: ',' (expressions ['as' star_target])
+// _loop0_206: ',' (expressions ['as' star_target])
 static asdl_seq *
-_loop0_204_rule(Parser *p)
+_loop0_206_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -37535,13 +38134,13 @@ _loop0_204_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop0_204[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expressions ['as' star_target])"));
+        D(fprintf(stderr, "%*c> _loop0_206[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expressions ['as' star_target])"));
         Token * _literal;
         void *elem;
         while (
             (_literal = _PyPegen_expect_token(p, 12))  // token=','
             &&
-            (elem = _tmp_264_rule(p))  // expressions ['as' star_target]
+            (elem = _tmp_266_rule(p))  // expressions ['as' star_target]
         )
         {
             _res = elem;
@@ -37567,7 +38166,7 @@ _loop0_204_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop0_204[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop0_206[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (expressions ['as' star_target])"));
     }
     asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena);
@@ -37584,9 +38183,9 @@ _loop0_204_rule(Parser *p)
     return _seq;
 }
 
-// _gather_203: (expressions ['as' star_target]) _loop0_204
+// _gather_205: (expressions ['as' star_target]) _loop0_206
 static asdl_seq *
-_gather_203_rule(Parser *p)
+_gather_205_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -37598,27 +38197,27 @@ _gather_203_rule(Parser *p)
     }
     asdl_seq * _res = NULL;
     int _mark = p->mark;
-    { // (expressions ['as' star_target]) _loop0_204
+    { // (expressions ['as' star_target]) _loop0_206
         if (p->error_indicator) {
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _gather_203[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_204"));
+        D(fprintf(stderr, "%*c> _gather_205[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_206"));
         void *elem;
         asdl_seq * seq;
         if (
-            (elem = _tmp_264_rule(p))  // expressions ['as' star_target]
+            (elem = _tmp_266_rule(p))  // expressions ['as' star_target]
             &&
-            (seq = _loop0_204_rule(p))  // _loop0_204
+            (seq = _loop0_206_rule(p))  // _loop0_206
         )
         {
-            D(fprintf(stderr, "%*c+ _gather_203[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_204"));
+            D(fprintf(stderr, "%*c+ _gather_205[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_206"));
             _res = _PyPegen_seq_insert_in_front(p, elem, seq);
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _gather_203[%d-%d]: %s failed!\n", p->level, ' ',
-                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expressions ['as' star_target]) _loop0_204"));
+        D(fprintf(stderr, "%*c%s _gather_205[%d-%d]: %s failed!\n", p->level, ' ',
+                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expressions ['as' star_target]) _loop0_206"));
     }
     _res = NULL;
   done:
@@ -37626,9 +38225,9 @@ _gather_203_rule(Parser *p)
     return _res;
 }
 
-// _loop0_206: ',' (expression ['as' star_target])
+// _loop0_208: ',' (expression ['as' star_target])
 static asdl_seq *
-_loop0_206_rule(Parser *p)
+_loop0_208_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -37654,13 +38253,13 @@ _loop0_206_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop0_206[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expression ['as' star_target])"));
+        D(fprintf(stderr, "%*c> _loop0_208[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expression ['as' star_target])"));
         Token * _literal;
         void *elem;
         while (
             (_literal = _PyPegen_expect_token(p, 12))  // token=','
             &&
-            (elem = _tmp_265_rule(p))  // expression ['as' star_target]
+            (elem = _tmp_267_rule(p))  // expression ['as' star_target]
         )
         {
             _res = elem;
@@ -37686,7 +38285,7 @@ _loop0_206_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop0_206[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop0_208[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (expression ['as' star_target])"));
     }
     asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena);
@@ -37703,9 +38302,9 @@ _loop0_206_rule(Parser *p)
     return _seq;
 }
 
-// _gather_205: (expression ['as' star_target]) _loop0_206
+// _gather_207: (expression ['as' star_target]) _loop0_208
 static asdl_seq *
-_gather_205_rule(Parser *p)
+_gather_207_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -37717,27 +38316,27 @@ _gather_205_rule(Parser *p)
     }
     asdl_seq * _res = NULL;
     int _mark = p->mark;
-    { // (expression ['as' star_target]) _loop0_206
+    { // (expression ['as' star_target]) _loop0_208
         if (p->error_indicator) {
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _gather_205[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_206"));
+        D(fprintf(stderr, "%*c> _gather_207[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_208"));
         void *elem;
         asdl_seq * seq;
         if (
-            (elem = _tmp_265_rule(p))  // expression ['as' star_target]
+            (elem = _tmp_267_rule(p))  // expression ['as' star_target]
             &&
-            (seq = _loop0_206_rule(p))  // _loop0_206
+            (seq = _loop0_208_rule(p))  // _loop0_208
         )
         {
-            D(fprintf(stderr, "%*c+ _gather_205[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_206"));
+            D(fprintf(stderr, "%*c+ _gather_207[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expression ['as' star_target]) _loop0_208"));
             _res = _PyPegen_seq_insert_in_front(p, elem, seq);
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _gather_205[%d-%d]: %s failed!\n", p->level, ' ',
-                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expression ['as' star_target]) _loop0_206"));
+        D(fprintf(stderr, "%*c%s _gather_207[%d-%d]: %s failed!\n", p->level, ' ',
+                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expression ['as' star_target]) _loop0_208"));
     }
     _res = NULL;
   done:
@@ -37745,9 +38344,9 @@ _gather_205_rule(Parser *p)
     return _res;
 }
 
-// _loop0_208: ',' (expressions ['as' star_target])
+// _loop0_210: ',' (expressions ['as' star_target])
 static asdl_seq *
-_loop0_208_rule(Parser *p)
+_loop0_210_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -37773,13 +38372,13 @@ _loop0_208_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop0_208[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expressions ['as' star_target])"));
+        D(fprintf(stderr, "%*c> _loop0_210[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' (expressions ['as' star_target])"));
         Token * _literal;
         void *elem;
         while (
             (_literal = _PyPegen_expect_token(p, 12))  // token=','
             &&
-            (elem = _tmp_266_rule(p))  // expressions ['as' star_target]
+            (elem = _tmp_268_rule(p))  // expressions ['as' star_target]
         )
         {
             _res = elem;
@@ -37805,7 +38404,7 @@ _loop0_208_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop0_208[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop0_210[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' (expressions ['as' star_target])"));
     }
     asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena);
@@ -37822,9 +38421,9 @@ _loop0_208_rule(Parser *p)
     return _seq;
 }
 
-// _gather_207: (expressions ['as' star_target]) _loop0_208
+// _gather_209: (expressions ['as' star_target]) _loop0_210
 static asdl_seq *
-_gather_207_rule(Parser *p)
+_gather_209_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -37836,27 +38435,27 @@ _gather_207_rule(Parser *p)
     }
     asdl_seq * _res = NULL;
     int _mark = p->mark;
-    { // (expressions ['as' star_target]) _loop0_208
+    { // (expressions ['as' star_target]) _loop0_210
         if (p->error_indicator) {
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _gather_207[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_208"));
+        D(fprintf(stderr, "%*c> _gather_209[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_210"));
         void *elem;
         asdl_seq * seq;
         if (
-            (elem = _tmp_266_rule(p))  // expressions ['as' star_target]
+            (elem = _tmp_268_rule(p))  // expressions ['as' star_target]
             &&
-            (seq = _loop0_208_rule(p))  // _loop0_208
+            (seq = _loop0_210_rule(p))  // _loop0_210
         )
         {
-            D(fprintf(stderr, "%*c+ _gather_207[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_208"));
+            D(fprintf(stderr, "%*c+ _gather_209[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(expressions ['as' star_target]) _loop0_210"));
             _res = _PyPegen_seq_insert_in_front(p, elem, seq);
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _gather_207[%d-%d]: %s failed!\n", p->level, ' ',
-                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expressions ['as' star_target]) _loop0_208"));
+        D(fprintf(stderr, "%*c%s _gather_209[%d-%d]: %s failed!\n", p->level, ' ',
+                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(expressions ['as' star_target]) _loop0_210"));
     }
     _res = NULL;
   done:
@@ -37864,9 +38463,9 @@ _gather_207_rule(Parser *p)
     return _res;
 }
 
-// _tmp_209: 'except' | 'finally'
+// _tmp_211: 'except' | 'finally'
 static void *
-_tmp_209_rule(Parser *p)
+_tmp_211_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -37883,18 +38482,18 @@ _tmp_209_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_209[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'except'"));
+        D(fprintf(stderr, "%*c> _tmp_211[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'except'"));
         Token * _keyword;
         if (
             (_keyword = _PyPegen_expect_token(p, 637))  // token='except'
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_209[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except'"));
+            D(fprintf(stderr, "%*c+ _tmp_211[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'except'"));
             _res = _keyword;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_209[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_211[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'except'"));
     }
     { // 'finally'
@@ -37902,18 +38501,18 @@ _tmp_209_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_209[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'finally'"));
+        D(fprintf(stderr, "%*c> _tmp_211[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'finally'"));
         Token * _keyword;
         if (
             (_keyword = _PyPegen_expect_token(p, 633))  // token='finally'
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_209[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'finally'"));
+            D(fprintf(stderr, "%*c+ _tmp_211[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'finally'"));
             _res = _keyword;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_209[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_211[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'finally'"));
     }
     _res = NULL;
@@ -37922,9 +38521,9 @@ _tmp_209_rule(Parser *p)
     return _res;
 }
 
-// _loop0_210: block
+// _loop0_212: block
 static asdl_seq *
-_loop0_210_rule(Parser *p)
+_loop0_212_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -37950,7 +38549,7 @@ _loop0_210_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop0_210[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "block"));
+        D(fprintf(stderr, "%*c> _loop0_212[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "block"));
         asdl_stmt_seq* block_var;
         while (
             (block_var = block_rule(p))  // block
@@ -37973,7 +38572,7 @@ _loop0_210_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop0_210[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop0_212[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "block"));
     }
     asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena);
@@ -37990,9 +38589,9 @@ _loop0_210_rule(Parser *p)
     return _seq;
 }
 
-// _loop1_211: except_block
+// _loop1_213: except_block
 static asdl_seq *
-_loop1_211_rule(Parser *p)
+_loop1_213_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -38018,7 +38617,7 @@ _loop1_211_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop1_211[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_block"));
+        D(fprintf(stderr, "%*c> _loop1_213[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_block"));
         excepthandler_ty except_block_var;
         while (
             (except_block_var = except_block_rule(p))  // except_block
@@ -38041,7 +38640,7 @@ _loop1_211_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop1_211[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop1_213[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "except_block"));
     }
     if (_n == 0 || p->error_indicator) {
@@ -38063,9 +38662,9 @@ _loop1_211_rule(Parser *p)
     return _seq;
 }
 
-// _tmp_212: 'as' NAME
+// _tmp_214: 'as' NAME
 static void *
-_tmp_212_rule(Parser *p)
+_tmp_214_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -38082,7 +38681,7 @@ _tmp_212_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_212[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME"));
+        D(fprintf(stderr, "%*c> _tmp_214[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME"));
         Token * _keyword;
         expr_ty name_var;
         if (
@@ -38091,12 +38690,12 @@ _tmp_212_rule(Parser *p)
             (name_var = _PyPegen_name_token(p))  // NAME
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_212[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME"));
+            D(fprintf(stderr, "%*c+ _tmp_214[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME"));
             _res = _PyPegen_dummy_name(p, _keyword, name_var);
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_212[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_214[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME"));
     }
     _res = NULL;
@@ -38105,9 +38704,9 @@ _tmp_212_rule(Parser *p)
     return _res;
 }
 
-// _loop0_213: block
+// _loop0_215: block
 static asdl_seq *
-_loop0_213_rule(Parser *p)
+_loop0_215_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -38133,7 +38732,7 @@ _loop0_213_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop0_213[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "block"));
+        D(fprintf(stderr, "%*c> _loop0_215[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "block"));
         asdl_stmt_seq* block_var;
         while (
             (block_var = block_rule(p))  // block
@@ -38156,7 +38755,7 @@ _loop0_213_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop0_213[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop0_215[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "block"));
     }
     asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena);
@@ -38173,9 +38772,9 @@ _loop0_213_rule(Parser *p)
     return _seq;
 }
 
-// _loop1_214: except_star_block
+// _loop1_216: except_star_block
 static asdl_seq *
-_loop1_214_rule(Parser *p)
+_loop1_216_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -38201,7 +38800,7 @@ _loop1_214_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop1_214[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_star_block"));
+        D(fprintf(stderr, "%*c> _loop1_216[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "except_star_block"));
         excepthandler_ty except_star_block_var;
         while (
             (except_star_block_var = except_star_block_rule(p))  // except_star_block
@@ -38224,7 +38823,7 @@ _loop1_214_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop1_214[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop1_216[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "except_star_block"));
     }
     if (_n == 0 || p->error_indicator) {
@@ -38246,9 +38845,9 @@ _loop1_214_rule(Parser *p)
     return _seq;
 }
 
-// _tmp_215: expression ['as' NAME]
+// _tmp_217: expression ['as' NAME]
 static void *
-_tmp_215_rule(Parser *p)
+_tmp_217_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -38265,22 +38864,22 @@ _tmp_215_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_215[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ['as' NAME]"));
+        D(fprintf(stderr, "%*c> _tmp_217[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ['as' NAME]"));
         void *_opt_var;
         UNUSED(_opt_var); // Silence compiler warnings
         expr_ty expression_var;
         if (
             (expression_var = expression_rule(p))  // expression
             &&
-            (_opt_var = _tmp_267_rule(p), !p->error_indicator)  // ['as' NAME]
+            (_opt_var = _tmp_269_rule(p), !p->error_indicator)  // ['as' NAME]
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_215[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ['as' NAME]"));
+            D(fprintf(stderr, "%*c+ _tmp_217[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ['as' NAME]"));
             _res = _PyPegen_dummy_name(p, expression_var, _opt_var);
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_215[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_217[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression ['as' NAME]"));
     }
     _res = NULL;
@@ -38289,9 +38888,9 @@ _tmp_215_rule(Parser *p)
     return _res;
 }
 
-// _tmp_216: 'as' NAME
+// _tmp_218: 'as' NAME
 static void *
-_tmp_216_rule(Parser *p)
+_tmp_218_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -38308,7 +38907,7 @@ _tmp_216_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_216[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME"));
+        D(fprintf(stderr, "%*c> _tmp_218[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME"));
         Token * _keyword;
         expr_ty name_var;
         if (
@@ -38317,12 +38916,12 @@ _tmp_216_rule(Parser *p)
             (name_var = _PyPegen_name_token(p))  // NAME
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_216[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME"));
+            D(fprintf(stderr, "%*c+ _tmp_218[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME"));
             _res = _PyPegen_dummy_name(p, _keyword, name_var);
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_216[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_218[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME"));
     }
     _res = NULL;
@@ -38331,9 +38930,9 @@ _tmp_216_rule(Parser *p)
     return _res;
 }
 
-// _tmp_217: 'as' NAME
+// _tmp_219: 'as' NAME
 static void *
-_tmp_217_rule(Parser *p)
+_tmp_219_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -38350,7 +38949,7 @@ _tmp_217_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_217[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME"));
+        D(fprintf(stderr, "%*c> _tmp_219[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME"));
         Token * _keyword;
         expr_ty name_var;
         if (
@@ -38359,12 +38958,12 @@ _tmp_217_rule(Parser *p)
             (name_var = _PyPegen_name_token(p))  // NAME
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_217[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME"));
+            D(fprintf(stderr, "%*c+ _tmp_219[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME"));
             _res = _PyPegen_dummy_name(p, _keyword, name_var);
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_217[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_219[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME"));
     }
     _res = NULL;
@@ -38373,9 +38972,9 @@ _tmp_217_rule(Parser *p)
     return _res;
 }
 
-// _tmp_218: NEWLINE | ':'
+// _tmp_220: NEWLINE | ':'
 static void *
-_tmp_218_rule(Parser *p)
+_tmp_220_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -38392,18 +38991,18 @@ _tmp_218_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_218[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NEWLINE"));
+        D(fprintf(stderr, "%*c> _tmp_220[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "NEWLINE"));
         Token * newline_var;
         if (
             (newline_var = _PyPegen_expect_token(p, NEWLINE))  // token='NEWLINE'
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_218[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NEWLINE"));
+            D(fprintf(stderr, "%*c+ _tmp_220[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "NEWLINE"));
             _res = newline_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_218[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_220[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "NEWLINE"));
     }
     { // ':'
@@ -38411,18 +39010,18 @@ _tmp_218_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_218[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'"));
+        D(fprintf(stderr, "%*c> _tmp_220[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'"));
         Token * _literal;
         if (
             (_literal = _PyPegen_expect_token(p, 11))  // token=':'
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_218[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'"));
+            D(fprintf(stderr, "%*c+ _tmp_220[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'"));
             _res = _literal;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_218[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_220[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'"));
     }
     _res = NULL;
@@ -38431,9 +39030,9 @@ _tmp_218_rule(Parser *p)
     return _res;
 }
 
-// _tmp_219: 'as' NAME
+// _tmp_221: 'as' NAME
 static void *
-_tmp_219_rule(Parser *p)
+_tmp_221_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -38450,7 +39049,7 @@ _tmp_219_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_219[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME"));
+        D(fprintf(stderr, "%*c> _tmp_221[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME"));
         Token * _keyword;
         expr_ty name_var;
         if (
@@ -38459,12 +39058,12 @@ _tmp_219_rule(Parser *p)
             (name_var = _PyPegen_name_token(p))  // NAME
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_219[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME"));
+            D(fprintf(stderr, "%*c+ _tmp_221[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME"));
             _res = _PyPegen_dummy_name(p, _keyword, name_var);
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_219[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_221[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME"));
     }
     _res = NULL;
@@ -38473,9 +39072,9 @@ _tmp_219_rule(Parser *p)
     return _res;
 }
 
-// _tmp_220: 'as' NAME
+// _tmp_222: 'as' NAME
 static void *
-_tmp_220_rule(Parser *p)
+_tmp_222_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -38492,7 +39091,7 @@ _tmp_220_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_220[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME"));
+        D(fprintf(stderr, "%*c> _tmp_222[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME"));
         Token * _keyword;
         expr_ty name_var;
         if (
@@ -38501,12 +39100,12 @@ _tmp_220_rule(Parser *p)
             (name_var = _PyPegen_name_token(p))  // NAME
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_220[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME"));
+            D(fprintf(stderr, "%*c+ _tmp_222[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME"));
             _res = _PyPegen_dummy_name(p, _keyword, name_var);
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_220[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_222[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME"));
     }
     _res = NULL;
@@ -38515,9 +39114,9 @@ _tmp_220_rule(Parser *p)
     return _res;
 }
 
-// _tmp_221: positional_patterns ','
+// _tmp_223: positional_patterns ','
 static void *
-_tmp_221_rule(Parser *p)
+_tmp_223_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -38534,7 +39133,7 @@ _tmp_221_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_221[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "positional_patterns ','"));
+        D(fprintf(stderr, "%*c> _tmp_223[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "positional_patterns ','"));
         Token * _literal;
         asdl_pattern_seq* positional_patterns_var;
         if (
@@ -38543,12 +39142,12 @@ _tmp_221_rule(Parser *p)
             (_literal = _PyPegen_expect_token(p, 12))  // token=','
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_221[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "positional_patterns ','"));
+            D(fprintf(stderr, "%*c+ _tmp_223[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "positional_patterns ','"));
             _res = _PyPegen_dummy_name(p, positional_patterns_var, _literal);
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_221[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_223[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "positional_patterns ','"));
     }
     _res = NULL;
@@ -38557,9 +39156,9 @@ _tmp_221_rule(Parser *p)
     return _res;
 }
 
-// _tmp_222: '->' expression
+// _tmp_224: '->' expression
 static void *
-_tmp_222_rule(Parser *p)
+_tmp_224_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -38576,7 +39175,7 @@ _tmp_222_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_222[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'->' expression"));
+        D(fprintf(stderr, "%*c> _tmp_224[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'->' expression"));
         Token * _literal;
         expr_ty expression_var;
         if (
@@ -38585,12 +39184,12 @@ _tmp_222_rule(Parser *p)
             (expression_var = expression_rule(p))  // expression
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_222[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'->' expression"));
+            D(fprintf(stderr, "%*c+ _tmp_224[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'->' expression"));
             _res = _PyPegen_dummy_name(p, _literal, expression_var);
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_222[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_224[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'->' expression"));
     }
     _res = NULL;
@@ -38599,9 +39198,9 @@ _tmp_222_rule(Parser *p)
     return _res;
 }
 
-// _tmp_223: '(' arguments? ')'
+// _tmp_225: '(' arguments? ')'
 static void *
-_tmp_223_rule(Parser *p)
+_tmp_225_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -38618,7 +39217,7 @@ _tmp_223_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_223[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'"));
+        D(fprintf(stderr, "%*c> _tmp_225[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'"));
         Token * _literal;
         Token * _literal_1;
         void *_opt_var;
@@ -38631,12 +39230,12 @@ _tmp_223_rule(Parser *p)
             (_literal_1 = _PyPegen_expect_token(p, 8))  // token=')'
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_223[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'"));
+            D(fprintf(stderr, "%*c+ _tmp_225[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'"));
             _res = _PyPegen_dummy_name(p, _literal, _opt_var, _literal_1);
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_223[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_225[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' arguments? ')'"));
     }
     _res = NULL;
@@ -38645,9 +39244,9 @@ _tmp_223_rule(Parser *p)
     return _res;
 }
 
-// _tmp_224: '(' arguments? ')'
+// _tmp_226: '(' arguments? ')'
 static void *
-_tmp_224_rule(Parser *p)
+_tmp_226_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -38664,7 +39263,7 @@ _tmp_224_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_224[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'"));
+        D(fprintf(stderr, "%*c> _tmp_226[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'"));
         Token * _literal;
         Token * _literal_1;
         void *_opt_var;
@@ -38677,12 +39276,12 @@ _tmp_224_rule(Parser *p)
             (_literal_1 = _PyPegen_expect_token(p, 8))  // token=')'
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_224[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'"));
+            D(fprintf(stderr, "%*c+ _tmp_226[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'(' arguments? ')'"));
             _res = _PyPegen_dummy_name(p, _literal, _opt_var, _literal_1);
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_224[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_226[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'(' arguments? ')'"));
     }
     _res = NULL;
@@ -38691,9 +39290,9 @@ _tmp_224_rule(Parser *p)
     return _res;
 }
 
-// _loop0_226: ',' double_starred_kvpair
+// _loop0_228: ',' double_starred_kvpair
 static asdl_seq *
-_loop0_226_rule(Parser *p)
+_loop0_228_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -38719,7 +39318,7 @@ _loop0_226_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop0_226[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' double_starred_kvpair"));
+        D(fprintf(stderr, "%*c> _loop0_228[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' double_starred_kvpair"));
         Token * _literal;
         KeyValuePair* elem;
         while (
@@ -38751,7 +39350,7 @@ _loop0_226_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop0_226[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop0_228[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' double_starred_kvpair"));
     }
     asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena);
@@ -38768,9 +39367,9 @@ _loop0_226_rule(Parser *p)
     return _seq;
 }
 
-// _gather_225: double_starred_kvpair _loop0_226
+// _gather_227: double_starred_kvpair _loop0_228
 static asdl_seq *
-_gather_225_rule(Parser *p)
+_gather_227_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -38782,27 +39381,27 @@ _gather_225_rule(Parser *p)
     }
     asdl_seq * _res = NULL;
     int _mark = p->mark;
-    { // double_starred_kvpair _loop0_226
+    { // double_starred_kvpair _loop0_228
         if (p->error_indicator) {
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _gather_225[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_226"));
+        D(fprintf(stderr, "%*c> _gather_227[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_228"));
         KeyValuePair* elem;
         asdl_seq * seq;
         if (
             (elem = double_starred_kvpair_rule(p))  // double_starred_kvpair
             &&
-            (seq = _loop0_226_rule(p))  // _loop0_226
+            (seq = _loop0_228_rule(p))  // _loop0_228
         )
         {
-            D(fprintf(stderr, "%*c+ _gather_225[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_226"));
+            D(fprintf(stderr, "%*c+ _gather_227[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "double_starred_kvpair _loop0_228"));
             _res = _PyPegen_seq_insert_in_front(p, elem, seq);
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _gather_225[%d-%d]: %s failed!\n", p->level, ' ',
-                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "double_starred_kvpair _loop0_226"));
+        D(fprintf(stderr, "%*c%s _gather_227[%d-%d]: %s failed!\n", p->level, ' ',
+                  p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "double_starred_kvpair _loop0_228"));
     }
     _res = NULL;
   done:
@@ -38810,9 +39409,9 @@ _gather_225_rule(Parser *p)
     return _res;
 }
 
-// _tmp_227: '}' | ','
+// _tmp_229: '}' | ','
 static void *
-_tmp_227_rule(Parser *p)
+_tmp_229_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -38829,18 +39428,18 @@ _tmp_227_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_227[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'"));
+        D(fprintf(stderr, "%*c> _tmp_229[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'"));
         Token * _literal;
         if (
             (_literal = _PyPegen_expect_token(p, 26))  // token='}'
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_227[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'"));
+            D(fprintf(stderr, "%*c+ _tmp_229[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'"));
             _res = _literal;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_227[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_229[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'}'"));
     }
     { // ','
@@ -38848,18 +39447,18 @@ _tmp_227_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_227[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','"));
+        D(fprintf(stderr, "%*c> _tmp_229[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','"));
         Token * _literal;
         if (
             (_literal = _PyPegen_expect_token(p, 12))  // token=','
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_227[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','"));
+            D(fprintf(stderr, "%*c+ _tmp_229[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','"));
             _res = _literal;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_227[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_229[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','"));
     }
     _res = NULL;
@@ -38868,9 +39467,9 @@ _tmp_227_rule(Parser *p)
     return _res;
 }
 
-// _tmp_228: '}' | ','
+// _tmp_230: '}' | ','
 static void *
-_tmp_228_rule(Parser *p)
+_tmp_230_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -38887,18 +39486,18 @@ _tmp_228_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_228[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'"));
+        D(fprintf(stderr, "%*c> _tmp_230[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'"));
         Token * _literal;
         if (
             (_literal = _PyPegen_expect_token(p, 26))  // token='}'
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_228[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'"));
+            D(fprintf(stderr, "%*c+ _tmp_230[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'"));
             _res = _literal;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_228[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_230[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'}'"));
     }
     { // ','
@@ -38906,18 +39505,18 @@ _tmp_228_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_228[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','"));
+        D(fprintf(stderr, "%*c> _tmp_230[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "','"));
         Token * _literal;
         if (
             (_literal = _PyPegen_expect_token(p, 12))  // token=','
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_228[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','"));
+            D(fprintf(stderr, "%*c+ _tmp_230[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "','"));
             _res = _literal;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_228[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_230[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "','"));
     }
     _res = NULL;
@@ -38926,9 +39525,9 @@ _tmp_228_rule(Parser *p)
     return _res;
 }
 
-// _tmp_229: yield_expr | star_expressions
+// _tmp_231: yield_expr | star_expressions
 static void *
-_tmp_229_rule(Parser *p)
+_tmp_231_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -38945,18 +39544,18 @@ _tmp_229_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_229[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr"));
+        D(fprintf(stderr, "%*c> _tmp_231[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr"));
         expr_ty yield_expr_var;
         if (
             (yield_expr_var = yield_expr_rule(p))  // yield_expr
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_229[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr"));
+            D(fprintf(stderr, "%*c+ _tmp_231[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr"));
             _res = yield_expr_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_229[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_231[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr"));
     }
     { // star_expressions
@@ -38964,18 +39563,18 @@ _tmp_229_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_229[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions"));
+        D(fprintf(stderr, "%*c> _tmp_231[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions"));
         expr_ty star_expressions_var;
         if (
             (star_expressions_var = star_expressions_rule(p))  // star_expressions
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_229[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions"));
+            D(fprintf(stderr, "%*c+ _tmp_231[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions"));
             _res = star_expressions_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_229[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_231[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions"));
     }
     _res = NULL;
@@ -38984,9 +39583,9 @@ _tmp_229_rule(Parser *p)
     return _res;
 }
 
-// _tmp_230: yield_expr | star_expressions
+// _tmp_232: yield_expr | star_expressions
 static void *
-_tmp_230_rule(Parser *p)
+_tmp_232_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -39003,18 +39602,18 @@ _tmp_230_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_230[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr"));
+        D(fprintf(stderr, "%*c> _tmp_232[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr"));
         expr_ty yield_expr_var;
         if (
             (yield_expr_var = yield_expr_rule(p))  // yield_expr
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_230[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr"));
+            D(fprintf(stderr, "%*c+ _tmp_232[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr"));
             _res = yield_expr_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_230[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_232[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr"));
     }
     { // star_expressions
@@ -39022,18 +39621,18 @@ _tmp_230_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_230[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions"));
+        D(fprintf(stderr, "%*c> _tmp_232[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions"));
         expr_ty star_expressions_var;
         if (
             (star_expressions_var = star_expressions_rule(p))  // star_expressions
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_230[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions"));
+            D(fprintf(stderr, "%*c+ _tmp_232[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions"));
             _res = star_expressions_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_230[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_232[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions"));
     }
     _res = NULL;
@@ -39042,9 +39641,9 @@ _tmp_230_rule(Parser *p)
     return _res;
 }
 
-// _tmp_231: '=' | '!' | ':' | '}'
+// _tmp_233: '=' | '!' | ':' | '}'
 static void *
-_tmp_231_rule(Parser *p)
+_tmp_233_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -39061,18 +39660,18 @@ _tmp_231_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_231[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='"));
+        D(fprintf(stderr, "%*c> _tmp_233[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'='"));
         Token * _literal;
         if (
             (_literal = _PyPegen_expect_token(p, 22))  // token='='
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_231[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'='"));
+            D(fprintf(stderr, "%*c+ _tmp_233[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'='"));
             _res = _literal;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_231[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_233[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'='"));
     }
     { // '!'
@@ -39080,18 +39679,18 @@ _tmp_231_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_231[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!'"));
+        D(fprintf(stderr, "%*c> _tmp_233[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!'"));
         Token * _literal;
         if (
             (_literal = _PyPegen_expect_token(p, 54))  // token='!'
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_231[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!'"));
+            D(fprintf(stderr, "%*c+ _tmp_233[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!'"));
             _res = _literal;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_231[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_233[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'!'"));
     }
     { // ':'
@@ -39099,18 +39698,18 @@ _tmp_231_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_231[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'"));
+        D(fprintf(stderr, "%*c> _tmp_233[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'"));
         Token * _literal;
         if (
             (_literal = _PyPegen_expect_token(p, 11))  // token=':'
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_231[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'"));
+            D(fprintf(stderr, "%*c+ _tmp_233[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'"));
             _res = _literal;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_231[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_233[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'"));
     }
     { // '}'
@@ -39118,18 +39717,18 @@ _tmp_231_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_231[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'"));
+        D(fprintf(stderr, "%*c> _tmp_233[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'"));
         Token * _literal;
         if (
             (_literal = _PyPegen_expect_token(p, 26))  // token='}'
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_231[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'"));
+            D(fprintf(stderr, "%*c+ _tmp_233[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'"));
             _res = _literal;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_231[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_233[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'}'"));
     }
     _res = NULL;
@@ -39138,9 +39737,9 @@ _tmp_231_rule(Parser *p)
     return _res;
 }
 
-// _tmp_232: yield_expr | star_expressions
+// _tmp_234: yield_expr | star_expressions
 static void *
-_tmp_232_rule(Parser *p)
+_tmp_234_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -39157,18 +39756,18 @@ _tmp_232_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_232[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr"));
+        D(fprintf(stderr, "%*c> _tmp_234[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr"));
         expr_ty yield_expr_var;
         if (
             (yield_expr_var = yield_expr_rule(p))  // yield_expr
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_232[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr"));
+            D(fprintf(stderr, "%*c+ _tmp_234[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr"));
             _res = yield_expr_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_232[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_234[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr"));
     }
     { // star_expressions
@@ -39176,18 +39775,18 @@ _tmp_232_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_232[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions"));
+        D(fprintf(stderr, "%*c> _tmp_234[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions"));
         expr_ty star_expressions_var;
         if (
             (star_expressions_var = star_expressions_rule(p))  // star_expressions
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_232[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions"));
+            D(fprintf(stderr, "%*c+ _tmp_234[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions"));
             _res = star_expressions_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_232[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_234[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions"));
     }
     _res = NULL;
@@ -39196,9 +39795,9 @@ _tmp_232_rule(Parser *p)
     return _res;
 }
 
-// _tmp_233: '!' | ':' | '}'
+// _tmp_235: '!' | ':' | '}'
 static void *
-_tmp_233_rule(Parser *p)
+_tmp_235_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -39215,18 +39814,18 @@ _tmp_233_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_233[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!'"));
+        D(fprintf(stderr, "%*c> _tmp_235[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!'"));
         Token * _literal;
         if (
             (_literal = _PyPegen_expect_token(p, 54))  // token='!'
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_233[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!'"));
+            D(fprintf(stderr, "%*c+ _tmp_235[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!'"));
             _res = _literal;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_233[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_235[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'!'"));
     }
     { // ':'
@@ -39234,18 +39833,18 @@ _tmp_233_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_233[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'"));
+        D(fprintf(stderr, "%*c> _tmp_235[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'"));
         Token * _literal;
         if (
             (_literal = _PyPegen_expect_token(p, 11))  // token=':'
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_233[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'"));
+            D(fprintf(stderr, "%*c+ _tmp_235[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'"));
             _res = _literal;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_233[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_235[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'"));
     }
     { // '}'
@@ -39253,18 +39852,18 @@ _tmp_233_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_233[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'"));
+        D(fprintf(stderr, "%*c> _tmp_235[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'"));
         Token * _literal;
         if (
             (_literal = _PyPegen_expect_token(p, 26))  // token='}'
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_233[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'"));
+            D(fprintf(stderr, "%*c+ _tmp_235[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'"));
             _res = _literal;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_233[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_235[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'}'"));
     }
     _res = NULL;
@@ -39273,9 +39872,9 @@ _tmp_233_rule(Parser *p)
     return _res;
 }
 
-// _tmp_234: yield_expr | star_expressions
+// _tmp_236: yield_expr | star_expressions
 static void *
-_tmp_234_rule(Parser *p)
+_tmp_236_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -39292,18 +39891,18 @@ _tmp_234_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_234[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr"));
+        D(fprintf(stderr, "%*c> _tmp_236[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr"));
         expr_ty yield_expr_var;
         if (
             (yield_expr_var = yield_expr_rule(p))  // yield_expr
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_234[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr"));
+            D(fprintf(stderr, "%*c+ _tmp_236[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr"));
             _res = yield_expr_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_234[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_236[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr"));
     }
     { // star_expressions
@@ -39311,18 +39910,18 @@ _tmp_234_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_234[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions"));
+        D(fprintf(stderr, "%*c> _tmp_236[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions"));
         expr_ty star_expressions_var;
         if (
             (star_expressions_var = star_expressions_rule(p))  // star_expressions
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_234[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions"));
+            D(fprintf(stderr, "%*c+ _tmp_236[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions"));
             _res = star_expressions_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_234[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_236[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions"));
     }
     _res = NULL;
@@ -39331,9 +39930,9 @@ _tmp_234_rule(Parser *p)
     return _res;
 }
 
-// _tmp_235: yield_expr | star_expressions
+// _tmp_237: yield_expr | star_expressions
 static void *
-_tmp_235_rule(Parser *p)
+_tmp_237_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -39350,18 +39949,18 @@ _tmp_235_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_235[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr"));
+        D(fprintf(stderr, "%*c> _tmp_237[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr"));
         expr_ty yield_expr_var;
         if (
             (yield_expr_var = yield_expr_rule(p))  // yield_expr
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_235[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr"));
+            D(fprintf(stderr, "%*c+ _tmp_237[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr"));
             _res = yield_expr_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_235[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_237[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr"));
     }
     { // star_expressions
@@ -39369,18 +39968,18 @@ _tmp_235_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_235[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions"));
+        D(fprintf(stderr, "%*c> _tmp_237[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions"));
         expr_ty star_expressions_var;
         if (
             (star_expressions_var = star_expressions_rule(p))  // star_expressions
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_235[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions"));
+            D(fprintf(stderr, "%*c+ _tmp_237[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions"));
             _res = star_expressions_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_235[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_237[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions"));
     }
     _res = NULL;
@@ -39389,9 +39988,9 @@ _tmp_235_rule(Parser *p)
     return _res;
 }
 
-// _tmp_236: '!' NAME
+// _tmp_238: '!' NAME
 static void *
-_tmp_236_rule(Parser *p)
+_tmp_238_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -39408,7 +40007,7 @@ _tmp_236_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_236[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!' NAME"));
+        D(fprintf(stderr, "%*c> _tmp_238[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!' NAME"));
         Token * _literal;
         expr_ty name_var;
         if (
@@ -39417,12 +40016,12 @@ _tmp_236_rule(Parser *p)
             (name_var = _PyPegen_name_token(p))  // NAME
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_236[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!' NAME"));
+            D(fprintf(stderr, "%*c+ _tmp_238[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!' NAME"));
             _res = _PyPegen_dummy_name(p, _literal, name_var);
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_236[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_238[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'!' NAME"));
     }
     _res = NULL;
@@ -39431,9 +40030,9 @@ _tmp_236_rule(Parser *p)
     return _res;
 }
 
-// _tmp_237: ':' | '}'
+// _tmp_239: ':' | '}'
 static void *
-_tmp_237_rule(Parser *p)
+_tmp_239_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -39450,18 +40049,18 @@ _tmp_237_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_237[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'"));
+        D(fprintf(stderr, "%*c> _tmp_239[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'"));
         Token * _literal;
         if (
             (_literal = _PyPegen_expect_token(p, 11))  // token=':'
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_237[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'"));
+            D(fprintf(stderr, "%*c+ _tmp_239[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'"));
             _res = _literal;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_237[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_239[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'"));
     }
     { // '}'
@@ -39469,18 +40068,18 @@ _tmp_237_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_237[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'"));
+        D(fprintf(stderr, "%*c> _tmp_239[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'"));
         Token * _literal;
         if (
             (_literal = _PyPegen_expect_token(p, 26))  // token='}'
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_237[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'"));
+            D(fprintf(stderr, "%*c+ _tmp_239[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'"));
             _res = _literal;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_237[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_239[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'}'"));
     }
     _res = NULL;
@@ -39489,9 +40088,9 @@ _tmp_237_rule(Parser *p)
     return _res;
 }
 
-// _tmp_238: yield_expr | star_expressions
+// _tmp_240: yield_expr | star_expressions
 static void *
-_tmp_238_rule(Parser *p)
+_tmp_240_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -39508,18 +40107,18 @@ _tmp_238_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_238[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr"));
+        D(fprintf(stderr, "%*c> _tmp_240[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr"));
         expr_ty yield_expr_var;
         if (
             (yield_expr_var = yield_expr_rule(p))  // yield_expr
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_238[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr"));
+            D(fprintf(stderr, "%*c+ _tmp_240[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr"));
             _res = yield_expr_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_238[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_240[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr"));
     }
     { // star_expressions
@@ -39527,18 +40126,18 @@ _tmp_238_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_238[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions"));
+        D(fprintf(stderr, "%*c> _tmp_240[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions"));
         expr_ty star_expressions_var;
         if (
             (star_expressions_var = star_expressions_rule(p))  // star_expressions
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_238[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions"));
+            D(fprintf(stderr, "%*c+ _tmp_240[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions"));
             _res = star_expressions_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_238[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_240[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions"));
     }
     _res = NULL;
@@ -39547,9 +40146,9 @@ _tmp_238_rule(Parser *p)
     return _res;
 }
 
-// _tmp_239: '!' NAME
+// _tmp_241: '!' NAME
 static void *
-_tmp_239_rule(Parser *p)
+_tmp_241_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -39566,7 +40165,7 @@ _tmp_239_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_239[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!' NAME"));
+        D(fprintf(stderr, "%*c> _tmp_241[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!' NAME"));
         Token * _literal;
         expr_ty name_var;
         if (
@@ -39575,12 +40174,12 @@ _tmp_239_rule(Parser *p)
             (name_var = _PyPegen_name_token(p))  // NAME
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_239[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!' NAME"));
+            D(fprintf(stderr, "%*c+ _tmp_241[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!' NAME"));
             _res = _PyPegen_dummy_name(p, _literal, name_var);
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_239[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_241[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'!' NAME"));
     }
     _res = NULL;
@@ -39589,9 +40188,9 @@ _tmp_239_rule(Parser *p)
     return _res;
 }
 
-// _loop0_240: fstring_format_spec
+// _loop0_242: fstring_format_spec
 static asdl_seq *
-_loop0_240_rule(Parser *p)
+_loop0_242_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -39617,7 +40216,7 @@ _loop0_240_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _loop0_240[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "fstring_format_spec"));
+        D(fprintf(stderr, "%*c> _loop0_242[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "fstring_format_spec"));
         expr_ty fstring_format_spec_var;
         while (
             (fstring_format_spec_var = fstring_format_spec_rule(p))  // fstring_format_spec
@@ -39640,7 +40239,7 @@ _loop0_240_rule(Parser *p)
             _mark = p->mark;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _loop0_240[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _loop0_242[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "fstring_format_spec"));
     }
     asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena);
@@ -39657,9 +40256,9 @@ _loop0_240_rule(Parser *p)
     return _seq;
 }
 
-// _tmp_241: yield_expr | star_expressions
+// _tmp_243: yield_expr | star_expressions
 static void *
-_tmp_241_rule(Parser *p)
+_tmp_243_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -39676,18 +40275,18 @@ _tmp_241_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_241[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr"));
+        D(fprintf(stderr, "%*c> _tmp_243[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "yield_expr"));
         expr_ty yield_expr_var;
         if (
             (yield_expr_var = yield_expr_rule(p))  // yield_expr
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_241[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr"));
+            D(fprintf(stderr, "%*c+ _tmp_243[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "yield_expr"));
             _res = yield_expr_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_241[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_243[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "yield_expr"));
     }
     { // star_expressions
@@ -39695,18 +40294,18 @@ _tmp_241_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_241[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions"));
+        D(fprintf(stderr, "%*c> _tmp_243[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_expressions"));
         expr_ty star_expressions_var;
         if (
             (star_expressions_var = star_expressions_rule(p))  // star_expressions
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_241[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions"));
+            D(fprintf(stderr, "%*c+ _tmp_243[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_expressions"));
             _res = star_expressions_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_241[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_243[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_expressions"));
     }
     _res = NULL;
@@ -39715,9 +40314,9 @@ _tmp_241_rule(Parser *p)
     return _res;
 }
 
-// _tmp_242: '!' NAME
+// _tmp_244: '!' NAME
 static void *
-_tmp_242_rule(Parser *p)
+_tmp_244_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -39734,7 +40333,7 @@ _tmp_242_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_242[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!' NAME"));
+        D(fprintf(stderr, "%*c> _tmp_244[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'!' NAME"));
         Token * _literal;
         expr_ty name_var;
         if (
@@ -39743,12 +40342,12 @@ _tmp_242_rule(Parser *p)
             (name_var = _PyPegen_name_token(p))  // NAME
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_242[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!' NAME"));
+            D(fprintf(stderr, "%*c+ _tmp_244[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'!' NAME"));
             _res = _PyPegen_dummy_name(p, _literal, name_var);
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_242[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_244[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'!' NAME"));
     }
     _res = NULL;
@@ -39757,9 +40356,9 @@ _tmp_242_rule(Parser *p)
     return _res;
 }
 
-// _tmp_243: ':' | '}'
+// _tmp_245: ':' | '}'
 static void *
-_tmp_243_rule(Parser *p)
+_tmp_245_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -39776,18 +40375,18 @@ _tmp_243_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_243[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'"));
+        D(fprintf(stderr, "%*c> _tmp_245[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'"));
         Token * _literal;
         if (
             (_literal = _PyPegen_expect_token(p, 11))  // token=':'
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_243[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'"));
+            D(fprintf(stderr, "%*c+ _tmp_245[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'"));
             _res = _literal;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_243[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_245[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'"));
     }
     { // '}'
@@ -39795,18 +40394,18 @@ _tmp_243_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_243[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'"));
+        D(fprintf(stderr, "%*c> _tmp_245[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'}'"));
         Token * _literal;
         if (
             (_literal = _PyPegen_expect_token(p, 26))  // token='}'
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_243[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'"));
+            D(fprintf(stderr, "%*c+ _tmp_245[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'}'"));
             _res = _literal;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_243[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_245[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'}'"));
     }
     _res = NULL;
@@ -39815,9 +40414,9 @@ _tmp_243_rule(Parser *p)
     return _res;
 }
 
-// _tmp_244: star_targets '='
+// _tmp_246: star_targets '='
 static void *
-_tmp_244_rule(Parser *p)
+_tmp_246_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -39834,7 +40433,7 @@ _tmp_244_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_244[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='"));
+        D(fprintf(stderr, "%*c> _tmp_246[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='"));
         Token * _literal;
         expr_ty z;
         if (
@@ -39843,7 +40442,7 @@ _tmp_244_rule(Parser *p)
             (_literal = _PyPegen_expect_token(p, 22))  // token='='
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_244[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='"));
+            D(fprintf(stderr, "%*c+ _tmp_246[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='"));
             _res = z;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
@@ -39853,7 +40452,7 @@ _tmp_244_rule(Parser *p)
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_244[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_246[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_targets '='"));
     }
     _res = NULL;
@@ -39862,9 +40461,9 @@ _tmp_244_rule(Parser *p)
     return _res;
 }
 
-// _tmp_245: '.' | '...'
+// _tmp_247: '.' | '...'
 static void *
-_tmp_245_rule(Parser *p)
+_tmp_247_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -39881,18 +40480,18 @@ _tmp_245_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_245[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'"));
+        D(fprintf(stderr, "%*c> _tmp_247[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'"));
         Token * _literal;
         if (
             (_literal = _PyPegen_expect_token(p, 23))  // token='.'
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_245[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'"));
+            D(fprintf(stderr, "%*c+ _tmp_247[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'"));
             _res = _literal;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_245[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_247[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'.'"));
     }
     { // '...'
@@ -39900,18 +40499,18 @@ _tmp_245_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_245[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'"));
+        D(fprintf(stderr, "%*c> _tmp_247[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'"));
         Token * _literal;
         if (
             (_literal = _PyPegen_expect_token(p, 52))  // token='...'
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_245[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'"));
+            D(fprintf(stderr, "%*c+ _tmp_247[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'"));
             _res = _literal;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_245[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_247[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'...'"));
     }
     _res = NULL;
@@ -39920,9 +40519,9 @@ _tmp_245_rule(Parser *p)
     return _res;
 }
 
-// _tmp_246: '.' | '...'
+// _tmp_248: '.' | '...'
 static void *
-_tmp_246_rule(Parser *p)
+_tmp_248_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -39939,18 +40538,18 @@ _tmp_246_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_246[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'"));
+        D(fprintf(stderr, "%*c> _tmp_248[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'.'"));
         Token * _literal;
         if (
             (_literal = _PyPegen_expect_token(p, 23))  // token='.'
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_246[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'"));
+            D(fprintf(stderr, "%*c+ _tmp_248[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'.'"));
             _res = _literal;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_246[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_248[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'.'"));
     }
     { // '...'
@@ -39958,18 +40557,18 @@ _tmp_246_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_246[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'"));
+        D(fprintf(stderr, "%*c> _tmp_248[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'...'"));
         Token * _literal;
         if (
             (_literal = _PyPegen_expect_token(p, 52))  // token='...'
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_246[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'"));
+            D(fprintf(stderr, "%*c+ _tmp_248[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'...'"));
             _res = _literal;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_246[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_248[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'...'"));
     }
     _res = NULL;
@@ -39978,9 +40577,9 @@ _tmp_246_rule(Parser *p)
     return _res;
 }
 
-// _tmp_247: '@' named_expression NEWLINE
+// _tmp_249: '@' named_expression NEWLINE
 static void *
-_tmp_247_rule(Parser *p)
+_tmp_249_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -39997,7 +40596,7 @@ _tmp_247_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_247[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE"));
+        D(fprintf(stderr, "%*c> _tmp_249[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE"));
         Token * _literal;
         expr_ty f;
         Token * newline_var;
@@ -40009,7 +40608,7 @@ _tmp_247_rule(Parser *p)
             (newline_var = _PyPegen_expect_token(p, NEWLINE))  // token='NEWLINE'
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_247[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE"));
+            D(fprintf(stderr, "%*c+ _tmp_249[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'@' named_expression NEWLINE"));
             _res = f;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
@@ -40019,7 +40618,7 @@ _tmp_247_rule(Parser *p)
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_247[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_249[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'@' named_expression NEWLINE"));
     }
     _res = NULL;
@@ -40028,9 +40627,9 @@ _tmp_247_rule(Parser *p)
     return _res;
 }
 
-// _tmp_248: ',' expression
+// _tmp_250: ',' expression
 static void *
-_tmp_248_rule(Parser *p)
+_tmp_250_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -40047,7 +40646,7 @@ _tmp_248_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_248[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression"));
+        D(fprintf(stderr, "%*c> _tmp_250[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' expression"));
         Token * _literal;
         expr_ty c;
         if (
@@ -40056,7 +40655,7 @@ _tmp_248_rule(Parser *p)
             (c = expression_rule(p))  // expression
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_248[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' expression"));
+            D(fprintf(stderr, "%*c+ _tmp_250[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' expression"));
             _res = c;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
@@ -40066,7 +40665,7 @@ _tmp_248_rule(Parser *p)
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_248[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_250[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' expression"));
     }
     _res = NULL;
@@ -40075,9 +40674,9 @@ _tmp_248_rule(Parser *p)
     return _res;
 }
 
-// _tmp_249: ',' star_expression
+// _tmp_251: ',' star_expression
 static void *
-_tmp_249_rule(Parser *p)
+_tmp_251_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -40094,7 +40693,7 @@ _tmp_249_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_249[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_expression"));
+        D(fprintf(stderr, "%*c> _tmp_251[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_expression"));
         Token * _literal;
         expr_ty c;
         if (
@@ -40103,7 +40702,7 @@ _tmp_249_rule(Parser *p)
             (c = star_expression_rule(p))  // star_expression
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_249[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_expression"));
+            D(fprintf(stderr, "%*c+ _tmp_251[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_expression"));
             _res = c;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
@@ -40113,7 +40712,7 @@ _tmp_249_rule(Parser *p)
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_249[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_251[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' star_expression"));
     }
     _res = NULL;
@@ -40122,9 +40721,9 @@ _tmp_249_rule(Parser *p)
     return _res;
 }
 
-// _tmp_250: 'or' conjunction
+// _tmp_252: 'or' conjunction
 static void *
-_tmp_250_rule(Parser *p)
+_tmp_252_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -40141,7 +40740,7 @@ _tmp_250_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_250[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'or' conjunction"));
+        D(fprintf(stderr, "%*c> _tmp_252[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'or' conjunction"));
         Token * _keyword;
         expr_ty c;
         if (
@@ -40150,7 +40749,7 @@ _tmp_250_rule(Parser *p)
             (c = conjunction_rule(p))  // conjunction
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_250[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'or' conjunction"));
+            D(fprintf(stderr, "%*c+ _tmp_252[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'or' conjunction"));
             _res = c;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
@@ -40160,7 +40759,7 @@ _tmp_250_rule(Parser *p)
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_250[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_252[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'or' conjunction"));
     }
     _res = NULL;
@@ -40169,9 +40768,9 @@ _tmp_250_rule(Parser *p)
     return _res;
 }
 
-// _tmp_251: 'and' inversion
+// _tmp_253: 'and' inversion
 static void *
-_tmp_251_rule(Parser *p)
+_tmp_253_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -40188,7 +40787,7 @@ _tmp_251_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_251[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'and' inversion"));
+        D(fprintf(stderr, "%*c> _tmp_253[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'and' inversion"));
         Token * _keyword;
         expr_ty c;
         if (
@@ -40197,7 +40796,7 @@ _tmp_251_rule(Parser *p)
             (c = inversion_rule(p))  // inversion
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_251[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'and' inversion"));
+            D(fprintf(stderr, "%*c+ _tmp_253[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'and' inversion"));
             _res = c;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
@@ -40207,7 +40806,7 @@ _tmp_251_rule(Parser *p)
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_251[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_253[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'and' inversion"));
     }
     _res = NULL;
@@ -40216,9 +40815,9 @@ _tmp_251_rule(Parser *p)
     return _res;
 }
 
-// _tmp_252: slice | starred_expression
+// _tmp_254: slice | starred_expression
 static void *
-_tmp_252_rule(Parser *p)
+_tmp_254_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -40235,18 +40834,18 @@ _tmp_252_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_252[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slice"));
+        D(fprintf(stderr, "%*c> _tmp_254[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "slice"));
         expr_ty slice_var;
         if (
             (slice_var = slice_rule(p))  // slice
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_252[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slice"));
+            D(fprintf(stderr, "%*c+ _tmp_254[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "slice"));
             _res = slice_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_252[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_254[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "slice"));
     }
     { // starred_expression
@@ -40254,18 +40853,18 @@ _tmp_252_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_252[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "starred_expression"));
+        D(fprintf(stderr, "%*c> _tmp_254[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "starred_expression"));
         expr_ty starred_expression_var;
         if (
             (starred_expression_var = starred_expression_rule(p))  // starred_expression
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_252[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "starred_expression"));
+            D(fprintf(stderr, "%*c+ _tmp_254[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "starred_expression"));
             _res = starred_expression_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_252[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_254[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "starred_expression"));
     }
     _res = NULL;
@@ -40274,9 +40873,9 @@ _tmp_252_rule(Parser *p)
     return _res;
 }
 
-// _tmp_253: fstring | string
+// _tmp_255: fstring | string
 static void *
-_tmp_253_rule(Parser *p)
+_tmp_255_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -40293,18 +40892,18 @@ _tmp_253_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_253[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "fstring"));
+        D(fprintf(stderr, "%*c> _tmp_255[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "fstring"));
         expr_ty fstring_var;
         if (
             (fstring_var = fstring_rule(p))  // fstring
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_253[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "fstring"));
+            D(fprintf(stderr, "%*c+ _tmp_255[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "fstring"));
             _res = fstring_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_253[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_255[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "fstring"));
     }
     { // string
@@ -40312,18 +40911,18 @@ _tmp_253_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_253[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "string"));
+        D(fprintf(stderr, "%*c> _tmp_255[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "string"));
         expr_ty string_var;
         if (
             (string_var = string_rule(p))  // string
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_253[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "string"));
+            D(fprintf(stderr, "%*c+ _tmp_255[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "string"));
             _res = string_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_253[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_255[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "string"));
     }
     _res = NULL;
@@ -40332,9 +40931,9 @@ _tmp_253_rule(Parser *p)
     return _res;
 }
 
-// _tmp_254: 'if' disjunction
+// _tmp_256: 'if' disjunction
 static void *
-_tmp_254_rule(Parser *p)
+_tmp_256_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -40351,7 +40950,7 @@ _tmp_254_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_254[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction"));
+        D(fprintf(stderr, "%*c> _tmp_256[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction"));
         Token * _keyword;
         expr_ty z;
         if (
@@ -40360,7 +40959,7 @@ _tmp_254_rule(Parser *p)
             (z = disjunction_rule(p))  // disjunction
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_254[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' disjunction"));
+            D(fprintf(stderr, "%*c+ _tmp_256[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' disjunction"));
             _res = z;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
@@ -40370,7 +40969,7 @@ _tmp_254_rule(Parser *p)
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_254[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_256[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'if' disjunction"));
     }
     _res = NULL;
@@ -40379,9 +40978,9 @@ _tmp_254_rule(Parser *p)
     return _res;
 }
 
-// _tmp_255: 'if' disjunction
+// _tmp_257: 'if' disjunction
 static void *
-_tmp_255_rule(Parser *p)
+_tmp_257_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -40398,7 +40997,7 @@ _tmp_255_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_255[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction"));
+        D(fprintf(stderr, "%*c> _tmp_257[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'if' disjunction"));
         Token * _keyword;
         expr_ty z;
         if (
@@ -40407,7 +41006,7 @@ _tmp_255_rule(Parser *p)
             (z = disjunction_rule(p))  // disjunction
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_255[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' disjunction"));
+            D(fprintf(stderr, "%*c+ _tmp_257[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'if' disjunction"));
             _res = z;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
@@ -40417,7 +41016,7 @@ _tmp_255_rule(Parser *p)
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_255[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_257[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'if' disjunction"));
     }
     _res = NULL;
@@ -40426,9 +41025,9 @@ _tmp_255_rule(Parser *p)
     return _res;
 }
 
-// _tmp_256: starred_expression | (assignment_expression | expression !':=') !'='
+// _tmp_258: starred_expression | (assignment_expression | expression !':=') !'='
 static void *
-_tmp_256_rule(Parser *p)
+_tmp_258_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -40445,18 +41044,18 @@ _tmp_256_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_256[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "starred_expression"));
+        D(fprintf(stderr, "%*c> _tmp_258[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "starred_expression"));
         expr_ty starred_expression_var;
         if (
             (starred_expression_var = starred_expression_rule(p))  // starred_expression
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_256[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "starred_expression"));
+            D(fprintf(stderr, "%*c+ _tmp_258[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "starred_expression"));
             _res = starred_expression_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_256[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_258[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "starred_expression"));
     }
     { // (assignment_expression | expression !':=') !'='
@@ -40464,20 +41063,20 @@ _tmp_256_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_256[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(assignment_expression | expression !':=') !'='"));
-        void *_tmp_268_var;
+        D(fprintf(stderr, "%*c> _tmp_258[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "(assignment_expression | expression !':=') !'='"));
+        void *_tmp_270_var;
         if (
-            (_tmp_268_var = _tmp_268_rule(p))  // assignment_expression | expression !':='
+            (_tmp_270_var = _tmp_270_rule(p))  // assignment_expression | expression !':='
             &&
             _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 22)  // token='='
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_256[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(assignment_expression | expression !':=') !'='"));
-            _res = _tmp_268_var;
+            D(fprintf(stderr, "%*c+ _tmp_258[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "(assignment_expression | expression !':=') !'='"));
+            _res = _tmp_270_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_256[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_258[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "(assignment_expression | expression !':=') !'='"));
     }
     _res = NULL;
@@ -40486,9 +41085,9 @@ _tmp_256_rule(Parser *p)
     return _res;
 }
 
-// _tmp_257: ',' star_target
+// _tmp_259: ',' star_target
 static void *
-_tmp_257_rule(Parser *p)
+_tmp_259_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -40505,7 +41104,7 @@ _tmp_257_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_257[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target"));
+        D(fprintf(stderr, "%*c> _tmp_259[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target"));
         Token * _literal;
         expr_ty c;
         if (
@@ -40514,7 +41113,7 @@ _tmp_257_rule(Parser *p)
             (c = star_target_rule(p))  // star_target
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_257[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_target"));
+            D(fprintf(stderr, "%*c+ _tmp_259[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_target"));
             _res = c;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
@@ -40524,7 +41123,7 @@ _tmp_257_rule(Parser *p)
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_257[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_259[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' star_target"));
     }
     _res = NULL;
@@ -40533,9 +41132,9 @@ _tmp_257_rule(Parser *p)
     return _res;
 }
 
-// _tmp_258: ',' star_target
+// _tmp_260: ',' star_target
 static void *
-_tmp_258_rule(Parser *p)
+_tmp_260_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -40552,7 +41151,7 @@ _tmp_258_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_258[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target"));
+        D(fprintf(stderr, "%*c> _tmp_260[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "',' star_target"));
         Token * _literal;
         expr_ty c;
         if (
@@ -40561,7 +41160,7 @@ _tmp_258_rule(Parser *p)
             (c = star_target_rule(p))  // star_target
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_258[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_target"));
+            D(fprintf(stderr, "%*c+ _tmp_260[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "',' star_target"));
             _res = c;
             if (_res == NULL && PyErr_Occurred()) {
                 p->error_indicator = 1;
@@ -40571,7 +41170,7 @@ _tmp_258_rule(Parser *p)
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_258[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_260[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "',' star_target"));
     }
     _res = NULL;
@@ -40580,9 +41179,9 @@ _tmp_258_rule(Parser *p)
     return _res;
 }
 
-// _tmp_259: star_targets '='
+// _tmp_261: star_targets '='
 static void *
-_tmp_259_rule(Parser *p)
+_tmp_261_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -40599,7 +41198,7 @@ _tmp_259_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_259[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='"));
+        D(fprintf(stderr, "%*c> _tmp_261[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='"));
         Token * _literal;
         expr_ty star_targets_var;
         if (
@@ -40608,12 +41207,12 @@ _tmp_259_rule(Parser *p)
             (_literal = _PyPegen_expect_token(p, 22))  // token='='
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_259[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='"));
+            D(fprintf(stderr, "%*c+ _tmp_261[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='"));
             _res = _PyPegen_dummy_name(p, star_targets_var, _literal);
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_259[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_261[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_targets '='"));
     }
     _res = NULL;
@@ -40622,9 +41221,9 @@ _tmp_259_rule(Parser *p)
     return _res;
 }
 
-// _tmp_260: star_targets '='
+// _tmp_262: star_targets '='
 static void *
-_tmp_260_rule(Parser *p)
+_tmp_262_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -40641,7 +41240,7 @@ _tmp_260_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_260[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='"));
+        D(fprintf(stderr, "%*c> _tmp_262[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "star_targets '='"));
         Token * _literal;
         expr_ty star_targets_var;
         if (
@@ -40650,12 +41249,12 @@ _tmp_260_rule(Parser *p)
             (_literal = _PyPegen_expect_token(p, 22))  // token='='
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_260[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='"));
+            D(fprintf(stderr, "%*c+ _tmp_262[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "star_targets '='"));
             _res = _PyPegen_dummy_name(p, star_targets_var, _literal);
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_260[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_262[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "star_targets '='"));
     }
     _res = NULL;
@@ -40664,9 +41263,9 @@ _tmp_260_rule(Parser *p)
     return _res;
 }
 
-// _tmp_261: ')' | '**'
+// _tmp_263: ')' | '**'
 static void *
-_tmp_261_rule(Parser *p)
+_tmp_263_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -40683,18 +41282,18 @@ _tmp_261_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_261[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'"));
+        D(fprintf(stderr, "%*c> _tmp_263[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "')'"));
         Token * _literal;
         if (
             (_literal = _PyPegen_expect_token(p, 8))  // token=')'
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_261[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'"));
+            D(fprintf(stderr, "%*c+ _tmp_263[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "')'"));
             _res = _literal;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_261[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_263[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "')'"));
     }
     { // '**'
@@ -40702,18 +41301,18 @@ _tmp_261_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_261[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'"));
+        D(fprintf(stderr, "%*c> _tmp_263[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'"));
         Token * _literal;
         if (
             (_literal = _PyPegen_expect_token(p, 35))  // token='**'
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_261[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'"));
+            D(fprintf(stderr, "%*c+ _tmp_263[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'"));
             _res = _literal;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_261[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_263[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**'"));
     }
     _res = NULL;
@@ -40722,9 +41321,9 @@ _tmp_261_rule(Parser *p)
     return _res;
 }
 
-// _tmp_262: ':' | '**'
+// _tmp_264: ':' | '**'
 static void *
-_tmp_262_rule(Parser *p)
+_tmp_264_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -40741,18 +41340,18 @@ _tmp_262_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_262[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'"));
+        D(fprintf(stderr, "%*c> _tmp_264[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "':'"));
         Token * _literal;
         if (
             (_literal = _PyPegen_expect_token(p, 11))  // token=':'
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_262[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'"));
+            D(fprintf(stderr, "%*c+ _tmp_264[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "':'"));
             _res = _literal;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_262[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_264[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "':'"));
     }
     { // '**'
@@ -40760,18 +41359,18 @@ _tmp_262_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_262[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'"));
+        D(fprintf(stderr, "%*c> _tmp_264[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'**'"));
         Token * _literal;
         if (
             (_literal = _PyPegen_expect_token(p, 35))  // token='**'
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_262[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'"));
+            D(fprintf(stderr, "%*c+ _tmp_264[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'**'"));
             _res = _literal;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_262[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_264[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'**'"));
     }
     _res = NULL;
@@ -40780,9 +41379,9 @@ _tmp_262_rule(Parser *p)
     return _res;
 }
 
-// _tmp_263: expression ['as' star_target]
+// _tmp_265: expression ['as' star_target]
 static void *
-_tmp_263_rule(Parser *p)
+_tmp_265_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -40799,22 +41398,22 @@ _tmp_263_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_263[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]"));
+        D(fprintf(stderr, "%*c> _tmp_265[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]"));
         void *_opt_var;
         UNUSED(_opt_var); // Silence compiler warnings
         expr_ty expression_var;
         if (
             (expression_var = expression_rule(p))  // expression
             &&
-            (_opt_var = _tmp_269_rule(p), !p->error_indicator)  // ['as' star_target]
+            (_opt_var = _tmp_271_rule(p), !p->error_indicator)  // ['as' star_target]
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_263[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]"));
+            D(fprintf(stderr, "%*c+ _tmp_265[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]"));
             _res = _PyPegen_dummy_name(p, expression_var, _opt_var);
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_263[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_265[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression ['as' star_target]"));
     }
     _res = NULL;
@@ -40823,9 +41422,9 @@ _tmp_263_rule(Parser *p)
     return _res;
 }
 
-// _tmp_264: expressions ['as' star_target]
+// _tmp_266: expressions ['as' star_target]
 static void *
-_tmp_264_rule(Parser *p)
+_tmp_266_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -40842,22 +41441,22 @@ _tmp_264_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_264[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]"));
+        D(fprintf(stderr, "%*c> _tmp_266[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]"));
         void *_opt_var;
         UNUSED(_opt_var); // Silence compiler warnings
         expr_ty expressions_var;
         if (
             (expressions_var = expressions_rule(p))  // expressions
             &&
-            (_opt_var = _tmp_270_rule(p), !p->error_indicator)  // ['as' star_target]
+            (_opt_var = _tmp_272_rule(p), !p->error_indicator)  // ['as' star_target]
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_264[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]"));
+            D(fprintf(stderr, "%*c+ _tmp_266[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]"));
             _res = _PyPegen_dummy_name(p, expressions_var, _opt_var);
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_264[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_266[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expressions ['as' star_target]"));
     }
     _res = NULL;
@@ -40866,9 +41465,9 @@ _tmp_264_rule(Parser *p)
     return _res;
 }
 
-// _tmp_265: expression ['as' star_target]
+// _tmp_267: expression ['as' star_target]
 static void *
-_tmp_265_rule(Parser *p)
+_tmp_267_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -40885,22 +41484,22 @@ _tmp_265_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_265[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]"));
+        D(fprintf(stderr, "%*c> _tmp_267[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]"));
         void *_opt_var;
         UNUSED(_opt_var); // Silence compiler warnings
         expr_ty expression_var;
         if (
             (expression_var = expression_rule(p))  // expression
             &&
-            (_opt_var = _tmp_271_rule(p), !p->error_indicator)  // ['as' star_target]
+            (_opt_var = _tmp_273_rule(p), !p->error_indicator)  // ['as' star_target]
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_265[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]"));
+            D(fprintf(stderr, "%*c+ _tmp_267[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression ['as' star_target]"));
             _res = _PyPegen_dummy_name(p, expression_var, _opt_var);
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_265[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_267[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression ['as' star_target]"));
     }
     _res = NULL;
@@ -40909,9 +41508,9 @@ _tmp_265_rule(Parser *p)
     return _res;
 }
 
-// _tmp_266: expressions ['as' star_target]
+// _tmp_268: expressions ['as' star_target]
 static void *
-_tmp_266_rule(Parser *p)
+_tmp_268_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -40928,22 +41527,22 @@ _tmp_266_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_266[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]"));
+        D(fprintf(stderr, "%*c> _tmp_268[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]"));
         void *_opt_var;
         UNUSED(_opt_var); // Silence compiler warnings
         expr_ty expressions_var;
         if (
             (expressions_var = expressions_rule(p))  // expressions
             &&
-            (_opt_var = _tmp_272_rule(p), !p->error_indicator)  // ['as' star_target]
+            (_opt_var = _tmp_274_rule(p), !p->error_indicator)  // ['as' star_target]
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_266[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]"));
+            D(fprintf(stderr, "%*c+ _tmp_268[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expressions ['as' star_target]"));
             _res = _PyPegen_dummy_name(p, expressions_var, _opt_var);
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_266[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_268[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expressions ['as' star_target]"));
     }
     _res = NULL;
@@ -40952,9 +41551,9 @@ _tmp_266_rule(Parser *p)
     return _res;
 }
 
-// _tmp_267: 'as' NAME
+// _tmp_269: 'as' NAME
 static void *
-_tmp_267_rule(Parser *p)
+_tmp_269_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -40971,7 +41570,7 @@ _tmp_267_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_267[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME"));
+        D(fprintf(stderr, "%*c> _tmp_269[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' NAME"));
         Token * _keyword;
         expr_ty name_var;
         if (
@@ -40980,12 +41579,12 @@ _tmp_267_rule(Parser *p)
             (name_var = _PyPegen_name_token(p))  // NAME
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_267[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME"));
+            D(fprintf(stderr, "%*c+ _tmp_269[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' NAME"));
             _res = _PyPegen_dummy_name(p, _keyword, name_var);
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_267[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_269[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' NAME"));
     }
     _res = NULL;
@@ -40994,9 +41593,9 @@ _tmp_267_rule(Parser *p)
     return _res;
 }
 
-// _tmp_268: assignment_expression | expression !':='
+// _tmp_270: assignment_expression | expression !':='
 static void *
-_tmp_268_rule(Parser *p)
+_tmp_270_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -41013,18 +41612,18 @@ _tmp_268_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_268[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "assignment_expression"));
+        D(fprintf(stderr, "%*c> _tmp_270[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "assignment_expression"));
         expr_ty assignment_expression_var;
         if (
             (assignment_expression_var = assignment_expression_rule(p))  // assignment_expression
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_268[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "assignment_expression"));
+            D(fprintf(stderr, "%*c+ _tmp_270[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "assignment_expression"));
             _res = assignment_expression_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_268[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_270[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "assignment_expression"));
     }
     { // expression !':='
@@ -41032,7 +41631,7 @@ _tmp_268_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_268[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression !':='"));
+        D(fprintf(stderr, "%*c> _tmp_270[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "expression !':='"));
         expr_ty expression_var;
         if (
             (expression_var = expression_rule(p))  // expression
@@ -41040,12 +41639,12 @@ _tmp_268_rule(Parser *p)
             _PyPegen_lookahead_with_int(0, _PyPegen_expect_token, p, 53)  // token=':='
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_268[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression !':='"));
+            D(fprintf(stderr, "%*c+ _tmp_270[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "expression !':='"));
             _res = expression_var;
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_268[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_270[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "expression !':='"));
     }
     _res = NULL;
@@ -41054,9 +41653,9 @@ _tmp_268_rule(Parser *p)
     return _res;
 }
 
-// _tmp_269: 'as' star_target
+// _tmp_271: 'as' star_target
 static void *
-_tmp_269_rule(Parser *p)
+_tmp_271_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -41073,7 +41672,7 @@ _tmp_269_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_269[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target"));
+        D(fprintf(stderr, "%*c> _tmp_271[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target"));
         Token * _keyword;
         expr_ty star_target_var;
         if (
@@ -41082,12 +41681,12 @@ _tmp_269_rule(Parser *p)
             (star_target_var = star_target_rule(p))  // star_target
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_269[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target"));
+            D(fprintf(stderr, "%*c+ _tmp_271[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target"));
             _res = _PyPegen_dummy_name(p, _keyword, star_target_var);
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_269[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_271[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' star_target"));
     }
     _res = NULL;
@@ -41096,9 +41695,9 @@ _tmp_269_rule(Parser *p)
     return _res;
 }
 
-// _tmp_270: 'as' star_target
+// _tmp_272: 'as' star_target
 static void *
-_tmp_270_rule(Parser *p)
+_tmp_272_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -41115,7 +41714,7 @@ _tmp_270_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_270[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target"));
+        D(fprintf(stderr, "%*c> _tmp_272[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target"));
         Token * _keyword;
         expr_ty star_target_var;
         if (
@@ -41124,12 +41723,12 @@ _tmp_270_rule(Parser *p)
             (star_target_var = star_target_rule(p))  // star_target
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_270[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target"));
+            D(fprintf(stderr, "%*c+ _tmp_272[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target"));
             _res = _PyPegen_dummy_name(p, _keyword, star_target_var);
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_270[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_272[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' star_target"));
     }
     _res = NULL;
@@ -41138,9 +41737,9 @@ _tmp_270_rule(Parser *p)
     return _res;
 }
 
-// _tmp_271: 'as' star_target
+// _tmp_273: 'as' star_target
 static void *
-_tmp_271_rule(Parser *p)
+_tmp_273_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -41157,7 +41756,7 @@ _tmp_271_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_271[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target"));
+        D(fprintf(stderr, "%*c> _tmp_273[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target"));
         Token * _keyword;
         expr_ty star_target_var;
         if (
@@ -41166,12 +41765,12 @@ _tmp_271_rule(Parser *p)
             (star_target_var = star_target_rule(p))  // star_target
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_271[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target"));
+            D(fprintf(stderr, "%*c+ _tmp_273[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target"));
             _res = _PyPegen_dummy_name(p, _keyword, star_target_var);
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_271[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_273[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' star_target"));
     }
     _res = NULL;
@@ -41180,9 +41779,9 @@ _tmp_271_rule(Parser *p)
     return _res;
 }
 
-// _tmp_272: 'as' star_target
+// _tmp_274: 'as' star_target
 static void *
-_tmp_272_rule(Parser *p)
+_tmp_274_rule(Parser *p)
 {
     if (p->level++ == MAXSTACK) {
         p->error_indicator = 1;
@@ -41199,7 +41798,7 @@ _tmp_272_rule(Parser *p)
             p->level--;
             return NULL;
         }
-        D(fprintf(stderr, "%*c> _tmp_272[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target"));
+        D(fprintf(stderr, "%*c> _tmp_274[%d-%d]: %s\n", p->level, ' ', _mark, p->mark, "'as' star_target"));
         Token * _keyword;
         expr_ty star_target_var;
         if (
@@ -41208,12 +41807,12 @@ _tmp_272_rule(Parser *p)
             (star_target_var = star_target_rule(p))  // star_target
         )
         {
-            D(fprintf(stderr, "%*c+ _tmp_272[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target"));
+            D(fprintf(stderr, "%*c+ _tmp_274[%d-%d]: %s succeeded!\n", p->level, ' ', _mark, p->mark, "'as' star_target"));
             _res = _PyPegen_dummy_name(p, _keyword, star_target_var);
             goto done;
         }
         p->mark = _mark;
-        D(fprintf(stderr, "%*c%s _tmp_272[%d-%d]: %s failed!\n", p->level, ' ',
+        D(fprintf(stderr, "%*c%s _tmp_274[%d-%d]: %s failed!\n", p->level, ' ',
                   p->error_indicator ? "ERROR!" : "-", _mark, p->mark, "'as' star_target"));
     }
     _res = NULL;
diff --git a/Python/Python-ast.c b/Python/Python-ast.c
index 81ab71c0fc3b..d62cccbb6e24 100644
--- a/Python/Python-ast.c
+++ b/Python/Python-ast.c
@@ -131,6 +131,7 @@ void _PyAST_Fini(PyInterpreterState *interp)
     Py_CLEAR(state->Not_type);
     Py_CLEAR(state->Or_singleton);
     Py_CLEAR(state->Or_type);
+    Py_CLEAR(state->ParamSpec_type);
     Py_CLEAR(state->Pass_type);
     Py_CLEAR(state->Pow_singleton);
     Py_CLEAR(state->Pow_type);
@@ -150,7 +151,10 @@ void _PyAST_Fini(PyInterpreterState *interp)
     Py_CLEAR(state->TryStar_type);
     Py_CLEAR(state->Try_type);
     Py_CLEAR(state->Tuple_type);
+    Py_CLEAR(state->TypeAlias_type);
     Py_CLEAR(state->TypeIgnore_type);
+    Py_CLEAR(state->TypeVarTuple_type);
+    Py_CLEAR(state->TypeVar_type);
     Py_CLEAR(state->UAdd_singleton);
     Py_CLEAR(state->UAdd_type);
     Py_CLEAR(state->USub_singleton);
@@ -179,6 +183,7 @@ void _PyAST_Fini(PyInterpreterState *interp)
     Py_CLEAR(state->bases);
     Py_CLEAR(state->body);
     Py_CLEAR(state->boolop_type);
+    Py_CLEAR(state->bound);
     Py_CLEAR(state->cases);
     Py_CLEAR(state->cause);
     Py_CLEAR(state->cls);
@@ -256,6 +261,8 @@ void _PyAST_Fini(PyInterpreterState *interp)
     Py_CLEAR(state->type_comment);
     Py_CLEAR(state->type_ignore_type);
     Py_CLEAR(state->type_ignores);
+    Py_CLEAR(state->typeparam_type);
+    Py_CLEAR(state->typeparams);
     Py_CLEAR(state->unaryop_type);
     Py_CLEAR(state->upper);
     Py_CLEAR(state->value);
@@ -289,6 +296,7 @@ static int init_identifiers(struct ast_state *state)
     if ((state->attr = PyUnicode_InternFromString("attr")) == NULL) return 0;
     if ((state->bases = PyUnicode_InternFromString("bases")) == NULL) return 0;
     if ((state->body = PyUnicode_InternFromString("body")) == NULL) return 0;
+    if ((state->bound = PyUnicode_InternFromString("bound")) == NULL) return 0;
     if ((state->cases = PyUnicode_InternFromString("cases")) == NULL) return 0;
     if ((state->cause = PyUnicode_InternFromString("cause")) == NULL) return 0;
     if ((state->cls = PyUnicode_InternFromString("cls")) == NULL) return 0;
@@ -354,6 +362,7 @@ static int init_identifiers(struct ast_state *state)
     if ((state->type = PyUnicode_InternFromString("type")) == NULL) return 0;
     if ((state->type_comment = PyUnicode_InternFromString("type_comment")) == NULL) return 0;
     if ((state->type_ignores = PyUnicode_InternFromString("type_ignores")) == NULL) return 0;
+    if ((state->typeparams = PyUnicode_InternFromString("typeparams")) == NULL) return 0;
     if ((state->upper = PyUnicode_InternFromString("upper")) == NULL) return 0;
     if ((state->value = PyUnicode_InternFromString("value")) == NULL) return 0;
     if ((state->values = PyUnicode_InternFromString("values")) == NULL) return 0;
@@ -374,6 +383,7 @@ GENERATE_ASDL_SEQ_CONSTRUCTOR(withitem, withitem_ty)
 GENERATE_ASDL_SEQ_CONSTRUCTOR(match_case, match_case_ty)
 GENERATE_ASDL_SEQ_CONSTRUCTOR(pattern, pattern_ty)
 GENERATE_ASDL_SEQ_CONSTRUCTOR(type_ignore, type_ignore_ty)
+GENERATE_ASDL_SEQ_CONSTRUCTOR(typeparam, typeparam_ty)
 
 static PyObject* ast2obj_mod(struct ast_state *state, void*);
 static const char * const Module_fields[]={
@@ -399,6 +409,7 @@ static const char * const stmt_attributes[] = {
 static PyObject* ast2obj_stmt(struct ast_state *state, void*);
 static const char * const FunctionDef_fields[]={
     "name",
+    "typeparams",
     "args",
     "body",
     "decorator_list",
@@ -407,6 +418,7 @@ static const char * const FunctionDef_fields[]={
 };
 static const char * const AsyncFunctionDef_fields[]={
     "name",
+    "typeparams",
     "args",
     "body",
     "decorator_list",
@@ -415,6 +427,7 @@ static const char * const AsyncFunctionDef_fields[]={
 };
 static const char * const ClassDef_fields[]={
     "name",
+    "typeparams",
     "bases",
     "keywords",
     "body",
@@ -431,6 +444,11 @@ static const char * const Assign_fields[]={
     "value",
     "type_comment",
 };
+static const char * const TypeAlias_fields[]={
+    "name",
+    "typeparams",
+    "value",
+};
 static const char * const AugAssign_fields[]={
     "target",
     "op",
@@ -757,6 +775,23 @@ static const char * const TypeIgnore_fields[]={
     "lineno",
     "tag",
 };
+static const char * const typeparam_attributes[] = {
+    "lineno",
+    "col_offset",
+    "end_lineno",
+    "end_col_offset",
+};
+static PyObject* ast2obj_typeparam(struct ast_state *state, void*);
+static const char * const TypeVar_fields[]={
+    "name",
+    "bound",
+};
+static const char * const ParamSpec_fields[]={
+    "name",
+};
+static const char * const TypeVarTuple_fields[]={
+    "name",
+};
 
 
 
@@ -1134,12 +1169,13 @@ init_types(struct ast_state *state)
         "FunctionType(expr* argtypes, expr returns)");
     if (!state->FunctionType_type) return 0;
     state->stmt_type = make_type(state, "stmt", state->AST_type, NULL, 0,
-        "stmt = FunctionDef(identifier name, arguments args, stmt* body, expr* decorator_list, expr? returns, string? type_comment)\n"
-        "     | AsyncFunctionDef(identifier name, arguments args, stmt* body, expr* decorator_list, expr? returns, string? type_comment)\n"
-        "     | ClassDef(identifier name, expr* bases, keyword* keywords, stmt* body, expr* decorator_list)\n"
+        "stmt = FunctionDef(identifier name, typeparam* typeparams, arguments args, stmt* body, expr* decorator_list, expr? returns, string? type_comment)\n"
+        "     | AsyncFunctionDef(identifier name, typeparam* typeparams, arguments args, stmt* body, expr* decorator_list, expr? returns, string? type_comment)\n"
+        "     | ClassDef(identifier name, typeparam* typeparams, expr* bases, keyword* keywords, stmt* body, expr* decorator_list)\n"
         "     | Return(expr? value)\n"
         "     | Delete(expr* targets)\n"
         "     | Assign(expr* targets, expr value, string? type_comment)\n"
+        "     | TypeAlias(expr name, typeparam* typeparams, expr value)\n"
         "     | AugAssign(expr target, operator op, expr value)\n"
         "     | AnnAssign(expr target, expr annotation, expr? value, int simple)\n"
         "     | For(expr target, expr iter, stmt* body, stmt* orelse, string? type_comment)\n"
@@ -1169,8 +1205,8 @@ init_types(struct ast_state *state)
         -1)
         return 0;
     state->FunctionDef_type = make_type(state, "FunctionDef", state->stmt_type,
-                                        FunctionDef_fields, 6,
-        "FunctionDef(identifier name, arguments args, stmt* body, expr* decorator_list, expr? returns, string? type_comment)");
+                                        FunctionDef_fields, 7,
+        "FunctionDef(identifier name, typeparam* typeparams, arguments args, stmt* body, expr* decorator_list, expr? returns, string? type_comment)");
     if (!state->FunctionDef_type) return 0;
     if (PyObject_SetAttr(state->FunctionDef_type, state->returns, Py_None) ==
         -1)
@@ -1180,8 +1216,8 @@ init_types(struct ast_state *state)
         return 0;
     state->AsyncFunctionDef_type = make_type(state, "AsyncFunctionDef",
                                              state->stmt_type,
-                                             AsyncFunctionDef_fields, 6,
-        "AsyncFunctionDef(identifier name, arguments args, stmt* body, expr* decorator_list, expr? returns, string? type_comment)");
+                                             AsyncFunctionDef_fields, 7,
+        "AsyncFunctionDef(identifier name, typeparam* typeparams, arguments args, stmt* body, expr* decorator_list, expr? returns, string? type_comment)");
     if (!state->AsyncFunctionDef_type) return 0;
     if (PyObject_SetAttr(state->AsyncFunctionDef_type, state->returns, Py_None)
         == -1)
@@ -1190,8 +1226,8 @@ init_types(struct ast_state *state)
         Py_None) == -1)
         return 0;
     state->ClassDef_type = make_type(state, "ClassDef", state->stmt_type,
-                                     ClassDef_fields, 5,
-        "ClassDef(identifier name, expr* bases, keyword* keywords, stmt* body, expr* decorator_list)");
+                                     ClassDef_fields, 6,
+        "ClassDef(identifier name, typeparam* typeparams, expr* bases, keyword* keywords, stmt* body, expr* decorator_list)");
     if (!state->ClassDef_type) return 0;
     state->Return_type = make_type(state, "Return", state->stmt_type,
                                    Return_fields, 1,
@@ -1210,6 +1246,10 @@ init_types(struct ast_state *state)
     if (PyObject_SetAttr(state->Assign_type, state->type_comment, Py_None) ==
         -1)
         return 0;
+    state->TypeAlias_type = make_type(state, "TypeAlias", state->stmt_type,
+                                      TypeAlias_fields, 3,
+        "TypeAlias(expr name, typeparam* typeparams, expr value)");
+    if (!state->TypeAlias_type) return 0;
     state->AugAssign_type = make_type(state, "AugAssign", state->stmt_type,
                                       AugAssign_fields, 3,
         "AugAssign(expr target, operator op, expr value)");
@@ -1854,6 +1894,36 @@ init_types(struct ast_state *state)
                                        TypeIgnore_fields, 2,
         "TypeIgnore(int lineno, string tag)");
     if (!state->TypeIgnore_type) return 0;
+    state->typeparam_type = make_type(state, "typeparam", state->AST_type,
+                                      NULL, 0,
+        "typeparam = TypeVar(identifier name, expr? bound)\n"
+        "          | ParamSpec(identifier name)\n"
+        "          | TypeVarTuple(identifier name)");
+    if (!state->typeparam_type) return 0;
+    if (!add_attributes(state, state->typeparam_type, typeparam_attributes, 4))
+        return 0;
+    if (PyObject_SetAttr(state->typeparam_type, state->end_lineno, Py_None) ==
+        -1)
+        return 0;
+    if (PyObject_SetAttr(state->typeparam_type, state->end_col_offset, Py_None)
+        == -1)
+        return 0;
+    state->TypeVar_type = make_type(state, "TypeVar", state->typeparam_type,
+                                    TypeVar_fields, 2,
+        "TypeVar(identifier name, expr? bound)");
+    if (!state->TypeVar_type) return 0;
+    if (PyObject_SetAttr(state->TypeVar_type, state->bound, Py_None) == -1)
+        return 0;
+    state->ParamSpec_type = make_type(state, "ParamSpec",
+                                      state->typeparam_type, ParamSpec_fields,
+                                      1,
+        "ParamSpec(identifier name)");
+    if (!state->ParamSpec_type) return 0;
+    state->TypeVarTuple_type = make_type(state, "TypeVarTuple",
+                                         state->typeparam_type,
+                                         TypeVarTuple_fields, 1,
+        "TypeVarTuple(identifier name)");
+    if (!state->TypeVarTuple_type) return 0;
 
     state->recursion_depth = 0;
     state->recursion_limit = 0;
@@ -1897,6 +1967,8 @@ static int obj2ast_pattern(struct ast_state *state, PyObject* obj, pattern_ty*
                            out, PyArena* arena);
 static int obj2ast_type_ignore(struct ast_state *state, PyObject* obj,
                                type_ignore_ty* out, PyArena* arena);
+static int obj2ast_typeparam(struct ast_state *state, PyObject* obj,
+                             typeparam_ty* out, PyArena* arena);
 
 mod_ty
 _PyAST_Module(asdl_stmt_seq * body, asdl_type_ignore_seq * type_ignores,
@@ -1960,10 +2032,11 @@ _PyAST_FunctionType(asdl_expr_seq * argtypes, expr_ty returns, PyArena *arena)
 }
 
 stmt_ty
-_PyAST_FunctionDef(identifier name, arguments_ty args, asdl_stmt_seq * body,
-                   asdl_expr_seq * decorator_list, expr_ty returns, string
-                   type_comment, int lineno, int col_offset, int end_lineno,
-                   int end_col_offset, PyArena *arena)
+_PyAST_FunctionDef(identifier name, asdl_typeparam_seq * typeparams,
+                   arguments_ty args, asdl_stmt_seq * body, asdl_expr_seq *
+                   decorator_list, expr_ty returns, string type_comment, int
+                   lineno, int col_offset, int end_lineno, int end_col_offset,
+                   PyArena *arena)
 {
     stmt_ty p;
     if (!name) {
@@ -1981,6 +2054,7 @@ _PyAST_FunctionDef(identifier name, arguments_ty args, asdl_stmt_seq * body,
         return NULL;
     p->kind = FunctionDef_kind;
     p->v.FunctionDef.name = name;
+    p->v.FunctionDef.typeparams = typeparams;
     p->v.FunctionDef.args = args;
     p->v.FunctionDef.body = body;
     p->v.FunctionDef.decorator_list = decorator_list;
@@ -1994,10 +2068,11 @@ _PyAST_FunctionDef(identifier name, arguments_ty args, asdl_stmt_seq * body,
 }
 
 stmt_ty
-_PyAST_AsyncFunctionDef(identifier name, arguments_ty args, asdl_stmt_seq *
-                        body, asdl_expr_seq * decorator_list, expr_ty returns,
-                        string type_comment, int lineno, int col_offset, int
-                        end_lineno, int end_col_offset, PyArena *arena)
+_PyAST_AsyncFunctionDef(identifier name, asdl_typeparam_seq * typeparams,
+                        arguments_ty args, asdl_stmt_seq * body, asdl_expr_seq
+                        * decorator_list, expr_ty returns, string type_comment,
+                        int lineno, int col_offset, int end_lineno, int
+                        end_col_offset, PyArena *arena)
 {
     stmt_ty p;
     if (!name) {
@@ -2015,6 +2090,7 @@ _PyAST_AsyncFunctionDef(identifier name, arguments_ty args, asdl_stmt_seq *
         return NULL;
     p->kind = AsyncFunctionDef_kind;
     p->v.AsyncFunctionDef.name = name;
+    p->v.AsyncFunctionDef.typeparams = typeparams;
     p->v.AsyncFunctionDef.args = args;
     p->v.AsyncFunctionDef.body = body;
     p->v.AsyncFunctionDef.decorator_list = decorator_list;
@@ -2028,10 +2104,10 @@ _PyAST_AsyncFunctionDef(identifier name, arguments_ty args, asdl_stmt_seq *
 }
 
 stmt_ty
-_PyAST_ClassDef(identifier name, asdl_expr_seq * bases, asdl_keyword_seq *
-                keywords, asdl_stmt_seq * body, asdl_expr_seq * decorator_list,
-                int lineno, int col_offset, int end_lineno, int end_col_offset,
-                PyArena *arena)
+_PyAST_ClassDef(identifier name, asdl_typeparam_seq * typeparams, asdl_expr_seq
+                * bases, asdl_keyword_seq * keywords, asdl_stmt_seq * body,
+                asdl_expr_seq * decorator_list, int lineno, int col_offset, int
+                end_lineno, int end_col_offset, PyArena *arena)
 {
     stmt_ty p;
     if (!name) {
@@ -2044,6 +2120,7 @@ _PyAST_ClassDef(identifier name, asdl_expr_seq * bases, asdl_keyword_seq *
         return NULL;
     p->kind = ClassDef_kind;
     p->v.ClassDef.name = name;
+    p->v.ClassDef.typeparams = typeparams;
     p->v.ClassDef.bases = bases;
     p->v.ClassDef.keywords = keywords;
     p->v.ClassDef.body = body;
@@ -2114,6 +2191,36 @@ _PyAST_Assign(asdl_expr_seq * targets, expr_ty value, string type_comment, int
     return p;
 }
 
+stmt_ty
+_PyAST_TypeAlias(expr_ty name, asdl_typeparam_seq * typeparams, expr_ty value,
+                 int lineno, int col_offset, int end_lineno, int
+                 end_col_offset, PyArena *arena)
+{
+    stmt_ty p;
+    if (!name) {
+        PyErr_SetString(PyExc_ValueError,
+                        "field 'name' is required for TypeAlias");
+        return NULL;
+    }
+    if (!value) {
+        PyErr_SetString(PyExc_ValueError,
+                        "field 'value' is required for TypeAlias");
+        return NULL;
+    }
+    p = (stmt_ty)_PyArena_Malloc(arena, sizeof(*p));
+    if (!p)
+        return NULL;
+    p->kind = TypeAlias_kind;
+    p->v.TypeAlias.name = name;
+    p->v.TypeAlias.typeparams = typeparams;
+    p->v.TypeAlias.value = value;
+    p->lineno = lineno;
+    p->col_offset = col_offset;
+    p->end_lineno = end_lineno;
+    p->end_col_offset = end_col_offset;
+    return p;
+}
+
 stmt_ty
 _PyAST_AugAssign(expr_ty target, operator_ty op, expr_ty value, int lineno, int
                  col_offset, int end_lineno, int end_col_offset, PyArena *arena)
@@ -3606,6 +3713,73 @@ _PyAST_TypeIgnore(int lineno, string tag, PyArena *arena)
     return p;
 }
 
+typeparam_ty
+_PyAST_TypeVar(identifier name, expr_ty bound, int lineno, int col_offset, int
+               end_lineno, int end_col_offset, PyArena *arena)
+{
+    typeparam_ty p;
+    if (!name) {
+        PyErr_SetString(PyExc_ValueError,
+                        "field 'name' is required for TypeVar");
+        return NULL;
+    }
+    p = (typeparam_ty)_PyArena_Malloc(arena, sizeof(*p));
+    if (!p)
+        return NULL;
+    p->kind = TypeVar_kind;
+    p->v.TypeVar.name = name;
+    p->v.TypeVar.bound = bound;
+    p->lineno = lineno;
+    p->col_offset = col_offset;
+    p->end_lineno = end_lineno;
+    p->end_col_offset = end_col_offset;
+    return p;
+}
+
+typeparam_ty
+_PyAST_ParamSpec(identifier name, int lineno, int col_offset, int end_lineno,
+                 int end_col_offset, PyArena *arena)
+{
+    typeparam_ty p;
+    if (!name) {
+        PyErr_SetString(PyExc_ValueError,
+                        "field 'name' is required for ParamSpec");
+        return NULL;
+    }
+    p = (typeparam_ty)_PyArena_Malloc(arena, sizeof(*p));
+    if (!p)
+        return NULL;
+    p->kind = ParamSpec_kind;
+    p->v.ParamSpec.name = name;
+    p->lineno = lineno;
+    p->col_offset = col_offset;
+    p->end_lineno = end_lineno;
+    p->end_col_offset = end_col_offset;
+    return p;
+}
+
+typeparam_ty
+_PyAST_TypeVarTuple(identifier name, int lineno, int col_offset, int
+                    end_lineno, int end_col_offset, PyArena *arena)
+{
+    typeparam_ty p;
+    if (!name) {
+        PyErr_SetString(PyExc_ValueError,
+                        "field 'name' is required for TypeVarTuple");
+        return NULL;
+    }
+    p = (typeparam_ty)_PyArena_Malloc(arena, sizeof(*p));
+    if (!p)
+        return NULL;
+    p->kind = TypeVarTuple_kind;
+    p->v.TypeVarTuple.name = name;
+    p->lineno = lineno;
+    p->col_offset = col_offset;
+    p->end_lineno = end_lineno;
+    p->end_col_offset = end_col_offset;
+    return p;
+}
+
 
 PyObject*
 ast2obj_mod(struct ast_state *state, void* _o)
@@ -3708,6 +3882,12 @@ ast2obj_stmt(struct ast_state *state, void* _o)
         if (PyObject_SetAttr(result, state->name, value) == -1)
             goto failed;
         Py_DECREF(value);
+        value = ast2obj_list(state, (asdl_seq*)o->v.FunctionDef.typeparams,
+                             ast2obj_typeparam);
+        if (!value) goto failed;
+        if (PyObject_SetAttr(result, state->typeparams, value) == -1)
+            goto failed;
+        Py_DECREF(value);
         value = ast2obj_arguments(state, o->v.FunctionDef.args);
         if (!value) goto failed;
         if (PyObject_SetAttr(result, state->args, value) == -1)
@@ -3745,6 +3925,13 @@ ast2obj_stmt(struct ast_state *state, void* _o)
         if (PyObject_SetAttr(result, state->name, value) == -1)
             goto failed;
         Py_DECREF(value);
+        value = ast2obj_list(state,
+                             (asdl_seq*)o->v.AsyncFunctionDef.typeparams,
+                             ast2obj_typeparam);
+        if (!value) goto failed;
+        if (PyObject_SetAttr(result, state->typeparams, value) == -1)
+            goto failed;
+        Py_DECREF(value);
         value = ast2obj_arguments(state, o->v.AsyncFunctionDef.args);
         if (!value) goto failed;
         if (PyObject_SetAttr(result, state->args, value) == -1)
@@ -3783,6 +3970,12 @@ ast2obj_stmt(struct ast_state *state, void* _o)
         if (PyObject_SetAttr(result, state->name, value) == -1)
             goto failed;
         Py_DECREF(value);
+        value = ast2obj_list(state, (asdl_seq*)o->v.ClassDef.typeparams,
+                             ast2obj_typeparam);
+        if (!value) goto failed;
+        if (PyObject_SetAttr(result, state->typeparams, value) == -1)
+            goto failed;
+        Py_DECREF(value);
         value = ast2obj_list(state, (asdl_seq*)o->v.ClassDef.bases,
                              ast2obj_expr);
         if (!value) goto failed;
@@ -3850,6 +4043,27 @@ ast2obj_stmt(struct ast_state *state, void* _o)
             goto failed;
         Py_DECREF(value);
         break;
+    case TypeAlias_kind:
+        tp = (PyTypeObject *)state->TypeAlias_type;
+        result = PyType_GenericNew(tp, NULL, NULL);
+        if (!result) goto failed;
+        value = ast2obj_expr(state, o->v.TypeAlias.name);
+        if (!value) goto failed;
+        if (PyObject_SetAttr(result, state->name, value) == -1)
+            goto failed;
+        Py_DECREF(value);
+        value = ast2obj_list(state, (asdl_seq*)o->v.TypeAlias.typeparams,
+                             ast2obj_typeparam);
+        if (!value) goto failed;
+        if (PyObject_SetAttr(result, state->typeparams, value) == -1)
+            goto failed;
+        Py_DECREF(value);
+        value = ast2obj_expr(state, o->v.TypeAlias.value);
+        if (!value) goto failed;
+        if (PyObject_SetAttr(result, state->value, value) == -1)
+            goto failed;
+        Py_DECREF(value);
+        break;
     case AugAssign_kind:
         tp = (PyTypeObject *)state->AugAssign_type;
         result = PyType_GenericNew(tp, NULL, NULL);
@@ -5441,6 +5655,85 @@ ast2obj_type_ignore(struct ast_state *state, void* _o)
     return NULL;
 }
 
+PyObject*
+ast2obj_typeparam(struct ast_state *state, void* _o)
+{
+    typeparam_ty o = (typeparam_ty)_o;
+    PyObject *result = NULL, *value = NULL;
+    PyTypeObject *tp;
+    if (!o) {
+        Py_RETURN_NONE;
+    }
+    if (++state->recursion_depth > state->recursion_limit) {
+        PyErr_SetString(PyExc_RecursionError,
+            "maximum recursion depth exceeded during ast construction");
+        return 0;
+    }
+    switch (o->kind) {
+    case TypeVar_kind:
+        tp = (PyTypeObject *)state->TypeVar_type;
+        result = PyType_GenericNew(tp, NULL, NULL);
+        if (!result) goto failed;
+        value = ast2obj_identifier(state, o->v.TypeVar.name);
+        if (!value) goto failed;
+        if (PyObject_SetAttr(result, state->name, value) == -1)
+            goto failed;
+        Py_DECREF(value);
+        value = ast2obj_expr(state, o->v.TypeVar.bound);
+        if (!value) goto failed;
+        if (PyObject_SetAttr(result, state->bound, value) == -1)
+            goto failed;
+        Py_DECREF(value);
+        break;
+    case ParamSpec_kind:
+        tp = (PyTypeObject *)state->ParamSpec_type;
+        result = PyType_GenericNew(tp, NULL, NULL);
+        if (!result) goto failed;
+        value = ast2obj_identifier(state, o->v.ParamSpec.name);
+        if (!value) goto failed;
+        if (PyObject_SetAttr(result, state->name, value) == -1)
+            goto failed;
+        Py_DECREF(value);
+        break;
+    case TypeVarTuple_kind:
+        tp = (PyTypeObject *)state->TypeVarTuple_type;
+        result = PyType_GenericNew(tp, NULL, NULL);
+        if (!result) goto failed;
+        value = ast2obj_identifier(state, o->v.TypeVarTuple.name);
+        if (!value) goto failed;
+        if (PyObject_SetAttr(result, state->name, value) == -1)
+            goto failed;
+        Py_DECREF(value);
+        break;
+    }
+    value = ast2obj_int(state, o->lineno);
+    if (!value) goto failed;
+    if (PyObject_SetAttr(result, state->lineno, value) < 0)
+        goto failed;
+    Py_DECREF(value);
+    value = ast2obj_int(state, o->col_offset);
+    if (!value) goto failed;
+    if (PyObject_SetAttr(result, state->col_offset, value) < 0)
+        goto failed;
+    Py_DECREF(value);
+    value = ast2obj_int(state, o->end_lineno);
+    if (!value) goto failed;
+    if (PyObject_SetAttr(result, state->end_lineno, value) < 0)
+        goto failed;
+    Py_DECREF(value);
+    value = ast2obj_int(state, o->end_col_offset);
+    if (!value) goto failed;
+    if (PyObject_SetAttr(result, state->end_col_offset, value) < 0)
+        goto failed;
+    Py_DECREF(value);
+    state->recursion_depth--;
+    return result;
+failed:
+    Py_XDECREF(value);
+    Py_XDECREF(result);
+    return NULL;
+}
+
 
 int
 obj2ast_mod(struct ast_state *state, PyObject* obj, mod_ty* out, PyArena* arena)
@@ -5781,6 +6074,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena*
     }
     if (isinstance) {
         identifier name;
+        asdl_typeparam_seq* typeparams;
         arguments_ty args;
         asdl_stmt_seq* body;
         asdl_expr_seq* decorator_list;
@@ -5804,6 +6098,42 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena*
             if (res != 0) goto failed;
             Py_CLEAR(tmp);
         }
+        if (_PyObject_LookupAttr(obj, state->typeparams, &tmp) < 0) {
+            return 1;
+        }
+        if (tmp == NULL) {
+            PyErr_SetString(PyExc_TypeError, "required field \"typeparams\" missing from FunctionDef");
+            return 1;
+        }
+        else {
+            int res;
+            Py_ssize_t len;
+            Py_ssize_t i;
+            if (!PyList_Check(tmp)) {
+                PyErr_Format(PyExc_TypeError, "FunctionDef field \"typeparams\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+                goto failed;
+            }
+            len = PyList_GET_SIZE(tmp);
+            typeparams = _Py_asdl_typeparam_seq_new(len, arena);
+            if (typeparams == NULL) goto failed;
+            for (i = 0; i < len; i++) {
+                typeparam_ty val;
+                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
+                if (_Py_EnterRecursiveCall(" while traversing 'FunctionDef' node")) {
+                    goto failed;
+                }
+                res = obj2ast_typeparam(state, tmp2, &val, arena);
+                _Py_LeaveRecursiveCall();
+                Py_DECREF(tmp2);
+                if (res != 0) goto failed;
+                if (len != PyList_GET_SIZE(tmp)) {
+                    PyErr_SetString(PyExc_RuntimeError, "FunctionDef field \"typeparams\" changed size during iteration");
+                    goto failed;
+                }
+                asdl_seq_SET(typeparams, i, val);
+            }
+            Py_CLEAR(tmp);
+        }
         if (_PyObject_LookupAttr(obj, state->args, &tmp) < 0) {
             return 1;
         }
@@ -5927,9 +6257,9 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena*
             if (res != 0) goto failed;
             Py_CLEAR(tmp);
         }
-        *out = _PyAST_FunctionDef(name, args, body, decorator_list, returns,
-                                  type_comment, lineno, col_offset, end_lineno,
-                                  end_col_offset, arena);
+        *out = _PyAST_FunctionDef(name, typeparams, args, body, decorator_list,
+                                  returns, type_comment, lineno, col_offset,
+                                  end_lineno, end_col_offset, arena);
         if (*out == NULL) goto failed;
         return 0;
     }
@@ -5940,6 +6270,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena*
     }
     if (isinstance) {
         identifier name;
+        asdl_typeparam_seq* typeparams;
         arguments_ty args;
         asdl_stmt_seq* body;
         asdl_expr_seq* decorator_list;
@@ -5963,6 +6294,42 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena*
             if (res != 0) goto failed;
             Py_CLEAR(tmp);
         }
+        if (_PyObject_LookupAttr(obj, state->typeparams, &tmp) < 0) {
+            return 1;
+        }
+        if (tmp == NULL) {
+            PyErr_SetString(PyExc_TypeError, "required field \"typeparams\" missing from AsyncFunctionDef");
+            return 1;
+        }
+        else {
+            int res;
+            Py_ssize_t len;
+            Py_ssize_t i;
+            if (!PyList_Check(tmp)) {
+                PyErr_Format(PyExc_TypeError, "AsyncFunctionDef field \"typeparams\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+                goto failed;
+            }
+            len = PyList_GET_SIZE(tmp);
+            typeparams = _Py_asdl_typeparam_seq_new(len, arena);
+            if (typeparams == NULL) goto failed;
+            for (i = 0; i < len; i++) {
+                typeparam_ty val;
+                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
+                if (_Py_EnterRecursiveCall(" while traversing 'AsyncFunctionDef' node")) {
+                    goto failed;
+                }
+                res = obj2ast_typeparam(state, tmp2, &val, arena);
+                _Py_LeaveRecursiveCall();
+                Py_DECREF(tmp2);
+                if (res != 0) goto failed;
+                if (len != PyList_GET_SIZE(tmp)) {
+                    PyErr_SetString(PyExc_RuntimeError, "AsyncFunctionDef field \"typeparams\" changed size during iteration");
+                    goto failed;
+                }
+                asdl_seq_SET(typeparams, i, val);
+            }
+            Py_CLEAR(tmp);
+        }
         if (_PyObject_LookupAttr(obj, state->args, &tmp) < 0) {
             return 1;
         }
@@ -6086,10 +6453,10 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena*
             if (res != 0) goto failed;
             Py_CLEAR(tmp);
         }
-        *out = _PyAST_AsyncFunctionDef(name, args, body, decorator_list,
-                                       returns, type_comment, lineno,
-                                       col_offset, end_lineno, end_col_offset,
-                                       arena);
+        *out = _PyAST_AsyncFunctionDef(name, typeparams, args, body,
+                                       decorator_list, returns, type_comment,
+                                       lineno, col_offset, end_lineno,
+                                       end_col_offset, arena);
         if (*out == NULL) goto failed;
         return 0;
     }
@@ -6100,6 +6467,7 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena*
     }
     if (isinstance) {
         identifier name;
+        asdl_typeparam_seq* typeparams;
         asdl_expr_seq* bases;
         asdl_keyword_seq* keywords;
         asdl_stmt_seq* body;
@@ -6122,6 +6490,42 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena*
             if (res != 0) goto failed;
             Py_CLEAR(tmp);
         }
+        if (_PyObject_LookupAttr(obj, state->typeparams, &tmp) < 0) {
+            return 1;
+        }
+        if (tmp == NULL) {
+            PyErr_SetString(PyExc_TypeError, "required field \"typeparams\" missing from ClassDef");
+            return 1;
+        }
+        else {
+            int res;
+            Py_ssize_t len;
+            Py_ssize_t i;
+            if (!PyList_Check(tmp)) {
+                PyErr_Format(PyExc_TypeError, "ClassDef field \"typeparams\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+                goto failed;
+            }
+            len = PyList_GET_SIZE(tmp);
+            typeparams = _Py_asdl_typeparam_seq_new(len, arena);
+            if (typeparams == NULL) goto failed;
+            for (i = 0; i < len; i++) {
+                typeparam_ty val;
+                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
+                if (_Py_EnterRecursiveCall(" while traversing 'ClassDef' node")) {
+                    goto failed;
+                }
+                res = obj2ast_typeparam(state, tmp2, &val, arena);
+                _Py_LeaveRecursiveCall();
+                Py_DECREF(tmp2);
+                if (res != 0) goto failed;
+                if (len != PyList_GET_SIZE(tmp)) {
+                    PyErr_SetString(PyExc_RuntimeError, "ClassDef field \"typeparams\" changed size during iteration");
+                    goto failed;
+                }
+                asdl_seq_SET(typeparams, i, val);
+            }
+            Py_CLEAR(tmp);
+        }
         if (_PyObject_LookupAttr(obj, state->bases, &tmp) < 0) {
             return 1;
         }
@@ -6266,9 +6670,9 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena*
             }
             Py_CLEAR(tmp);
         }
-        *out = _PyAST_ClassDef(name, bases, keywords, body, decorator_list,
-                               lineno, col_offset, end_lineno, end_col_offset,
-                               arena);
+        *out = _PyAST_ClassDef(name, typeparams, bases, keywords, body,
+                               decorator_list, lineno, col_offset, end_lineno,
+                               end_col_offset, arena);
         if (*out == NULL) goto failed;
         return 0;
     }
@@ -6436,6 +6840,91 @@ obj2ast_stmt(struct ast_state *state, PyObject* obj, stmt_ty* out, PyArena*
         if (*out == NULL) goto failed;
         return 0;
     }
+    tp = state->TypeAlias_type;
+    isinstance = PyObject_IsInstance(obj, tp);
+    if (isinstance == -1) {
+        return 1;
+    }
+    if (isinstance) {
+        expr_ty name;
+        asdl_typeparam_seq* typeparams;
+        expr_ty value;
+
+        if (_PyObject_LookupAttr(obj, state->name, &tmp) < 0) {
+            return 1;
+        }
+        if (tmp == NULL) {
+            PyErr_SetString(PyExc_TypeError, "required field \"name\" missing from TypeAlias");
+            return 1;
+        }
+        else {
+            int res;
+            if (_Py_EnterRecursiveCall(" while traversing 'TypeAlias' node")) {
+                goto failed;
+            }
+            res = obj2ast_expr(state, tmp, &name, arena);
+            _Py_LeaveRecursiveCall();
+            if (res != 0) goto failed;
+            Py_CLEAR(tmp);
+        }
+        if (_PyObject_LookupAttr(obj, state->typeparams, &tmp) < 0) {
+            return 1;
+        }
+        if (tmp == NULL) {
+            PyErr_SetString(PyExc_TypeError, "required field \"typeparams\" missing from TypeAlias");
+            return 1;
+        }
+        else {
+            int res;
+            Py_ssize_t len;
+            Py_ssize_t i;
+            if (!PyList_Check(tmp)) {
+                PyErr_Format(PyExc_TypeError, "TypeAlias field \"typeparams\" must be a list, not a %.200s", _PyType_Name(Py_TYPE(tmp)));
+                goto failed;
+            }
+            len = PyList_GET_SIZE(tmp);
+            typeparams = _Py_asdl_typeparam_seq_new(len, arena);
+            if (typeparams == NULL) goto failed;
+            for (i = 0; i < len; i++) {
+                typeparam_ty val;
+                PyObject *tmp2 = Py_NewRef(PyList_GET_ITEM(tmp, i));
+                if (_Py_EnterRecursiveCall(" while traversing 'TypeAlias' node")) {
+                    goto failed;
+                }
+                res = obj2ast_typeparam(state, tmp2, &val, arena);
+                _Py_LeaveRecursiveCall();
+                Py_DECREF(tmp2);
+                if (res != 0) goto failed;
+                if (len != PyList_GET_SIZE(tmp)) {
+                    PyErr_SetString(PyExc_RuntimeError, "TypeAlias field \"typeparams\" changed size during iteration");
+                    goto failed;
+                }
+                asdl_seq_SET(typeparams, i, val);
+            }
+            Py_CLEAR(tmp);
+        }
+        if (_PyObject_LookupAttr(obj, state->value, &tmp) < 0) {
+            return 1;
+        }
+        if (tmp == NULL) {
+            PyErr_SetString(PyExc_TypeError, "required field \"value\" missing from TypeAlias");
+            return 1;
+        }
+        else {
+            int res;
+            if (_Py_EnterRecursiveCall(" while traversing 'TypeAlias' node")) {
+                goto failed;
+            }
+            res = obj2ast_expr(state, tmp, &value, arena);
+            _Py_LeaveRecursiveCall();
+            if (res != 0) goto failed;
+            Py_CLEAR(tmp);
+        }
+        *out = _PyAST_TypeAlias(name, typeparams, value, lineno, col_offset,
+                                end_lineno, end_col_offset, arena);
+        if (*out == NULL) goto failed;
+        return 0;
+    }
     tp = state->AugAssign_type;
     isinstance = PyObject_IsInstance(obj, tp);
     if (isinstance == -1) {
@@ -11803,6 +12292,206 @@ obj2ast_type_ignore(struct ast_state *state, PyObject* obj, type_ignore_ty*
     return 1;
 }
 
+int
+obj2ast_typeparam(struct ast_state *state, PyObject* obj, typeparam_ty* out,
+                  PyArena* arena)
+{
+    int isinstance;
+
+    PyObject *tmp = NULL;
+    PyObject *tp;
+    int lineno;
+    int col_offset;
+    int end_lineno;
+    int end_col_offset;
+
+    if (obj == Py_None) {
+        *out = NULL;
+        return 0;
+    }
+    if (_PyObject_LookupAttr(obj, state->lineno, &tmp) < 0) {
+        return 1;
+    }
+    if (tmp == NULL) {
+        PyErr_SetString(PyExc_TypeError, "required field \"lineno\" missing from typeparam");
+        return 1;
+    }
+    else {
+        int res;
+        if (_Py_EnterRecursiveCall(" while traversing 'typeparam' node")) {
+            goto failed;
+        }
+        res = obj2ast_int(state, tmp, &lineno, arena);
+        _Py_LeaveRecursiveCall();
+        if (res != 0) goto failed;
+        Py_CLEAR(tmp);
+    }
+    if (_PyObject_LookupAttr(obj, state->col_offset, &tmp) < 0) {
+        return 1;
+    }
+    if (tmp == NULL) {
+        PyErr_SetString(PyExc_TypeError, "required field \"col_offset\" missing from typeparam");
+        return 1;
+    }
+    else {
+        int res;
+        if (_Py_EnterRecursiveCall(" while traversing 'typeparam' node")) {
+            goto failed;
+        }
+        res = obj2ast_int(state, tmp, &col_offset, arena);
+        _Py_LeaveRecursiveCall();
+        if (res != 0) goto failed;
+        Py_CLEAR(tmp);
+    }
+    if (_PyObject_LookupAttr(obj, state->end_lineno, &tmp) < 0) {
+        return 1;
+    }
+    if (tmp == NULL || tmp == Py_None) {
+        Py_CLEAR(tmp);
+        end_lineno = lineno;
+    }
+    else {
+        int res;
+        if (_Py_EnterRecursiveCall(" while traversing 'typeparam' node")) {
+            goto failed;
+        }
+        res = obj2ast_int(state, tmp, &end_lineno, arena);
+        _Py_LeaveRecursiveCall();
+        if (res != 0) goto failed;
+        Py_CLEAR(tmp);
+    }
+    if (_PyObject_LookupAttr(obj, state->end_col_offset, &tmp) < 0) {
+        return 1;
+    }
+    if (tmp == NULL || tmp == Py_None) {
+        Py_CLEAR(tmp);
+        end_col_offset = col_offset;
+    }
+    else {
+        int res;
+        if (_Py_EnterRecursiveCall(" while traversing 'typeparam' node")) {
+            goto failed;
+        }
+        res = obj2ast_int(state, tmp, &end_col_offset, arena);
+        _Py_LeaveRecursiveCall();
+        if (res != 0) goto failed;
+        Py_CLEAR(tmp);
+    }
+    tp = state->TypeVar_type;
+    isinstance = PyObject_IsInstance(obj, tp);
+    if (isinstance == -1) {
+        return 1;
+    }
+    if (isinstance) {
+        identifier name;
+        expr_ty bound;
+
+        if (_PyObject_LookupAttr(obj, state->name, &tmp) < 0) {
+            return 1;
+        }
+        if (tmp == NULL) {
+            PyErr_SetString(PyExc_TypeError, "required field \"name\" missing from TypeVar");
+            return 1;
+        }
+        else {
+            int res;
+            if (_Py_EnterRecursiveCall(" while traversing 'TypeVar' node")) {
+                goto failed;
+            }
+            res = obj2ast_identifier(state, tmp, &name, arena);
+            _Py_LeaveRecursiveCall();
+            if (res != 0) goto failed;
+            Py_CLEAR(tmp);
+        }
+        if (_PyObject_LookupAttr(obj, state->bound, &tmp) < 0) {
+            return 1;
+        }
+        if (tmp == NULL || tmp == Py_None) {
+            Py_CLEAR(tmp);
+            bound = NULL;
+        }
+        else {
+            int res;
+            if (_Py_EnterRecursiveCall(" while traversing 'TypeVar' node")) {
+                goto failed;
+            }
+            res = obj2ast_expr(state, tmp, &bound, arena);
+            _Py_LeaveRecursiveCall();
+            if (res != 0) goto failed;
+            Py_CLEAR(tmp);
+        }
+        *out = _PyAST_TypeVar(name, bound, lineno, col_offset, end_lineno,
+                              end_col_offset, arena);
+        if (*out == NULL) goto failed;
+        return 0;
+    }
+    tp = state->ParamSpec_type;
+    isinstance = PyObject_IsInstance(obj, tp);
+    if (isinstance == -1) {
+        return 1;
+    }
+    if (isinstance) {
+        identifier name;
+
+        if (_PyObject_LookupAttr(obj, state->name, &tmp) < 0) {
+            return 1;
+        }
+        if (tmp == NULL) {
+            PyErr_SetString(PyExc_TypeError, "required field \"name\" missing from ParamSpec");
+            return 1;
+        }
+        else {
+            int res;
+            if (_Py_EnterRecursiveCall(" while traversing 'ParamSpec' node")) {
+                goto failed;
+            }
+            res = obj2ast_identifier(state, tmp, &name, arena);
+            _Py_LeaveRecursiveCall();
+            if (res != 0) goto failed;
+            Py_CLEAR(tmp);
+        }
+        *out = _PyAST_ParamSpec(name, lineno, col_offset, end_lineno,
+                                end_col_offset, arena);
+        if (*out == NULL) goto failed;
+        return 0;
+    }
+    tp = state->TypeVarTuple_type;
+    isinstance = PyObject_IsInstance(obj, tp);
+    if (isinstance == -1) {
+        return 1;
+    }
+    if (isinstance) {
+        identifier name;
+
+        if (_PyObject_LookupAttr(obj, state->name, &tmp) < 0) {
+            return 1;
+        }
+        if (tmp == NULL) {
+            PyErr_SetString(PyExc_TypeError, "required field \"name\" missing from TypeVarTuple");
+            return 1;
+        }
+        else {
+            int res;
+            if (_Py_EnterRecursiveCall(" while traversing 'TypeVarTuple' node")) {
+                goto failed;
+            }
+            res = obj2ast_identifier(state, tmp, &name, arena);
+            _Py_LeaveRecursiveCall();
+            if (res != 0) goto failed;
+            Py_CLEAR(tmp);
+        }
+        *out = _PyAST_TypeVarTuple(name, lineno, col_offset, end_lineno,
+                                   end_col_offset, arena);
+        if (*out == NULL) goto failed;
+        return 0;
+    }
+
+    PyErr_Format(PyExc_TypeError, "expected some sort of typeparam, but got %R", obj);
+    failed:
+    Py_XDECREF(tmp);
+    return 1;
+}
+
 
 static int
 astmodule_exec(PyObject *m)
@@ -11861,6 +12550,9 @@ astmodule_exec(PyObject *m)
     if (PyModule_AddObjectRef(m, "Assign", state->Assign_type) < 0) {
         return -1;
     }
+    if (PyModule_AddObjectRef(m, "TypeAlias", state->TypeAlias_type) < 0) {
+        return -1;
+    }
     if (PyModule_AddObjectRef(m, "AugAssign", state->AugAssign_type) < 0) {
         return -1;
     }
@@ -12188,6 +12880,19 @@ astmodule_exec(PyObject *m)
     if (PyModule_AddObjectRef(m, "TypeIgnore", state->TypeIgnore_type) < 0) {
         return -1;
     }
+    if (PyModule_AddObjectRef(m, "typeparam", state->typeparam_type) < 0) {
+        return -1;
+    }
+    if (PyModule_AddObjectRef(m, "TypeVar", state->TypeVar_type) < 0) {
+        return -1;
+    }
+    if (PyModule_AddObjectRef(m, "ParamSpec", state->ParamSpec_type) < 0) {
+        return -1;
+    }
+    if (PyModule_AddObjectRef(m, "TypeVarTuple", state->TypeVarTuple_type) < 0)
+        {
+        return -1;
+    }
     return 0;
 }
 
diff --git a/Python/ast.c b/Python/ast.c
index f079e64bbdfc..0844f2afa06b 100644
--- a/Python/ast.c
+++ b/Python/ast.c
@@ -17,10 +17,12 @@ struct validator {
 static int validate_stmts(struct validator *, asdl_stmt_seq *);
 static int validate_exprs(struct validator *, asdl_expr_seq *, expr_context_ty, int);
 static int validate_patterns(struct validator *, asdl_pattern_seq *, int);
+static int validate_typeparams(struct validator *, asdl_typeparam_seq *);
 static int _validate_nonempty_seq(asdl_seq *, const char *, const char *);
 static int validate_stmt(struct validator *, stmt_ty);
 static int validate_expr(struct validator *, expr_ty, expr_context_ty);
 static int validate_pattern(struct validator *, pattern_ty, int);
+static int validate_typeparam(struct validator *, typeparam_ty);
 
 #define VALIDATE_POSITIONS(node) \
     if (node->lineno > node->end_lineno) { \
@@ -726,6 +728,7 @@ validate_stmt(struct validator *state, stmt_ty stmt)
     switch (stmt->kind) {
     case FunctionDef_kind:
         ret = validate_body(state, stmt->v.FunctionDef.body, "FunctionDef") &&
+            validate_typeparams(state, stmt->v.FunctionDef.typeparams) &&
             validate_arguments(state, stmt->v.FunctionDef.args) &&
             validate_exprs(state, stmt->v.FunctionDef.decorator_list, Load, 0) &&
             (!stmt->v.FunctionDef.returns ||
@@ -733,6 +736,7 @@ validate_stmt(struct validator *state, stmt_ty stmt)
         break;
     case ClassDef_kind:
         ret = validate_body(state, stmt->v.ClassDef.body, "ClassDef") &&
+            validate_typeparams(state, stmt->v.ClassDef.typeparams) &&
             validate_exprs(state, stmt->v.ClassDef.bases, Load, 0) &&
             validate_keywords(state, stmt->v.ClassDef.keywords) &&
             validate_exprs(state, stmt->v.ClassDef.decorator_list, Load, 0);
@@ -763,6 +767,11 @@ validate_stmt(struct validator *state, stmt_ty stmt)
                 validate_expr(state, stmt->v.AnnAssign.value, Load)) &&
                validate_expr(state, stmt->v.AnnAssign.annotation, Load);
         break;
+    case TypeAlias_kind:
+        ret = validate_expr(state, stmt->v.TypeAlias.name, Store) &&
+            validate_typeparams(state, stmt->v.TypeAlias.typeparams) &&
+            validate_expr(state, stmt->v.TypeAlias.value, Load);
+        break;
     case For_kind:
         ret = validate_expr(state, stmt->v.For.target, Store) &&
             validate_expr(state, stmt->v.For.iter, Load) &&
@@ -910,6 +919,7 @@ validate_stmt(struct validator *state, stmt_ty stmt)
         break;
     case AsyncFunctionDef_kind:
         ret = validate_body(state, stmt->v.AsyncFunctionDef.body, "AsyncFunctionDef") &&
+            validate_typeparams(state, stmt->v.AsyncFunctionDef.typeparams) &&
             validate_arguments(state, stmt->v.AsyncFunctionDef.args) &&
             validate_exprs(state, stmt->v.AsyncFunctionDef.decorator_list, Load, 0) &&
             (!stmt->v.AsyncFunctionDef.returns ||
@@ -982,6 +992,41 @@ validate_patterns(struct validator *state, asdl_pattern_seq *patterns, int star_
     return 1;
 }
 
+static int
+validate_typeparam(struct validator *state, typeparam_ty tp)
+{
+    VALIDATE_POSITIONS(tp);
+    int ret = -1;
+    switch (tp->kind) {
+        case TypeVar_kind:
+            ret = validate_name(tp->v.TypeVar.name) &&
+                (!tp->v.TypeVar.bound ||
+                 validate_expr(state, tp->v.TypeVar.bound, Load));
+            break;
+        case ParamSpec_kind:
+            ret = validate_name(tp->v.ParamSpec.name);
+            break;
+        case TypeVarTuple_kind:
+            ret = validate_name(tp->v.TypeVarTuple.name);
+            break;
+    }
+    return ret;
+}
+
+static int
+validate_typeparams(struct validator *state, asdl_typeparam_seq *tps)
+{
+    Py_ssize_t i;
+    for (i = 0; i < asdl_seq_LEN(tps); i++) {
+        typeparam_ty tp = asdl_seq_GET(tps, i);
+        if (tp) {
+            if (!validate_typeparam(state, tp))
+                return 0;
+        }
+    }
+    return 1;
+}
+
 
 /* See comments in symtable.c. */
 #define COMPILER_STACK_FRAME_SCALE 3
diff --git a/Python/ast_opt.c b/Python/ast_opt.c
index 3883ec9e21c7..c5b3e0754673 100644
--- a/Python/ast_opt.c
+++ b/Python/ast_opt.c
@@ -642,6 +642,7 @@ static int astfold_withitem(withitem_ty node_, PyArena *ctx_, _PyASTOptimizeStat
 static int astfold_excepthandler(excepthandler_ty node_, PyArena *ctx_, _PyASTOptimizeState *state);
 static int astfold_match_case(match_case_ty node_, PyArena *ctx_, _PyASTOptimizeState *state);
 static int astfold_pattern(pattern_ty node_, PyArena *ctx_, _PyASTOptimizeState *state);
+static int astfold_typeparam(typeparam_ty node_, PyArena *ctx_, _PyASTOptimizeState *state);
 
 #define CALL(FUNC, TYPE, ARG) \
     if (!FUNC((ARG), ctx_, state)) \
@@ -880,6 +881,7 @@ astfold_stmt(stmt_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
     }
     switch (node_->kind) {
     case FunctionDef_kind:
+        CALL_SEQ(astfold_typeparam, typeparam, node_->v.FunctionDef.typeparams);
         CALL(astfold_arguments, arguments_ty, node_->v.FunctionDef.args);
         CALL(astfold_body, asdl_seq, node_->v.FunctionDef.body);
         CALL_SEQ(astfold_expr, expr, node_->v.FunctionDef.decorator_list);
@@ -888,6 +890,7 @@ astfold_stmt(stmt_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
         }
         break;
     case AsyncFunctionDef_kind:
+        CALL_SEQ(astfold_typeparam, typeparam, node_->v.AsyncFunctionDef.typeparams);
         CALL(astfold_arguments, arguments_ty, node_->v.AsyncFunctionDef.args);
         CALL(astfold_body, asdl_seq, node_->v.AsyncFunctionDef.body);
         CALL_SEQ(astfold_expr, expr, node_->v.AsyncFunctionDef.decorator_list);
@@ -896,6 +899,7 @@ astfold_stmt(stmt_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
         }
         break;
     case ClassDef_kind:
+        CALL_SEQ(astfold_typeparam, typeparam, node_->v.ClassDef.typeparams);
         CALL_SEQ(astfold_expr, expr, node_->v.ClassDef.bases);
         CALL_SEQ(astfold_keyword, keyword, node_->v.ClassDef.keywords);
         CALL(astfold_body, asdl_seq, node_->v.ClassDef.body);
@@ -922,6 +926,11 @@ astfold_stmt(stmt_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
         }
         CALL_OPT(astfold_expr, expr_ty, node_->v.AnnAssign.value);
         break;
+    case TypeAlias_kind:
+        CALL(astfold_expr, expr_ty, node_->v.TypeAlias.name);
+        CALL_SEQ(astfold_typeparam, typeparam, node_->v.TypeAlias.typeparams);
+        CALL(astfold_expr, expr_ty, node_->v.TypeAlias.value);
+        break;
     case For_kind:
         CALL(astfold_expr, expr_ty, node_->v.For.target);
         CALL(astfold_expr, expr_ty, node_->v.For.iter);
@@ -1074,6 +1083,21 @@ astfold_match_case(match_case_ty node_, PyArena *ctx_, _PyASTOptimizeState *stat
     return 1;
 }
 
+static int
+astfold_typeparam(typeparam_ty node_, PyArena *ctx_, _PyASTOptimizeState *state)
+{
+    switch (node_->kind) {
+        case TypeVar_kind:
+            CALL_OPT(astfold_expr, expr_ty, node_->v.TypeVar.bound);
+            break;
+        case ParamSpec_kind:
+            break;
+        case TypeVarTuple_kind:
+            break;
+    }
+    return 1;
+}
+
 #undef CALL
 #undef CALL_OPT
 #undef CALL_SEQ
diff --git a/Python/bytecodes.c b/Python/bytecodes.c
index d84a078f1100..1b8820f94dbc 100644
--- a/Python/bytecodes.c
+++ b/Python/bytecodes.c
@@ -56,7 +56,7 @@ static PyObject *value, *value1, *value2, *left, *right, *res, *sum, *prod, *sub
 static PyObject *container, *start, *stop, *v, *lhs, *rhs, *res2;
 static PyObject *list, *tuple, *dict, *owner, *set, *str, *tup, *map, *keys;
 static PyObject *exit_func, *lasti, *val, *retval, *obj, *iter;
-static PyObject *aiter, *awaitable, *iterable, *w, *exc_value, *bc;
+static PyObject *aiter, *awaitable, *iterable, *w, *exc_value, *bc, *locals;
 static PyObject *orig, *excs, *update, *b, *fromlist, *level, *from;
 static PyObject **pieces, **values;
 static size_t jump;
@@ -125,6 +125,7 @@ dummy_func(
     PyObject *subject;
     PyObject *top;
     PyObject *type;
+    PyObject *typevars;
     int values_or_none;
 
     switch (opcode) {
@@ -1002,6 +1003,7 @@ dummy_func(
             }
         }
 
+
         inst(STORE_NAME, (v -- )) {
             PyObject *name = GETITEM(frame->f_code->co_names, oparg);
             PyObject *ns = LOCALS();
@@ -1158,31 +1160,41 @@ dummy_func(
             }
         }
 
-        inst(LOAD_NAME, ( -- v)) {
-            PyObject *name = GETITEM(frame->f_code->co_names, oparg);
-            PyObject *locals = LOCALS();
+        op(_LOAD_LOCALS, ( -- locals)) {
+            locals = LOCALS();
             if (locals == NULL) {
-                _PyErr_Format(tstate, PyExc_SystemError,
-                              "no locals when loading %R", name);
-                goto error;
+                _PyErr_SetString(tstate, PyExc_SystemError,
+                                 "no locals found");
+                ERROR_IF(true, error);
             }
-            if (PyDict_CheckExact(locals)) {
-                v = PyDict_GetItemWithError(locals, name);
+            Py_INCREF(locals);
+        }
+
+        macro(LOAD_LOCALS) = _LOAD_LOCALS;
+
+        op(_LOAD_FROM_DICT_OR_GLOBALS, (mod_or_class_dict -- v)) {
+            PyObject *name = GETITEM(frame->f_code->co_names, oparg);
+            if (PyDict_CheckExact(mod_or_class_dict)) {
+                v = PyDict_GetItemWithError(mod_or_class_dict, name);
                 if (v != NULL) {
                     Py_INCREF(v);
                 }
                 else if (_PyErr_Occurred(tstate)) {
+                    Py_DECREF(mod_or_class_dict);
                     goto error;
                 }
             }
             else {
-                v = PyObject_GetItem(locals, name);
+                v = PyObject_GetItem(mod_or_class_dict, name);
                 if (v == NULL) {
-                    if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError))
+                    if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) {
+                        Py_DECREF(mod_or_class_dict);
                         goto error;
+                    }
                     _PyErr_Clear(tstate);
                 }
             }
+            Py_DECREF(mod_or_class_dict);
             if (v == NULL) {
                 v = PyDict_GetItemWithError(GLOBALS(), name);
                 if (v != NULL) {
@@ -1219,6 +1231,10 @@ dummy_func(
             }
         }
 
+        macro(LOAD_NAME) = _LOAD_LOCALS + _LOAD_FROM_DICT_OR_GLOBALS;
+
+        macro(LOAD_FROM_DICT_OR_GLOBALS) = _LOAD_FROM_DICT_OR_GLOBALS;
+
         family(load_global, INLINE_CACHE_ENTRIES_LOAD_GLOBAL) = {
             LOAD_GLOBAL,
             LOAD_GLOBAL_MODULE,
@@ -1339,29 +1355,32 @@ dummy_func(
             Py_DECREF(oldobj);
         }
 
-        inst(LOAD_CLASSDEREF, ( -- value)) {
-            PyObject *name, *locals = LOCALS();
-            assert(locals);
+        inst(LOAD_FROM_DICT_OR_DEREF, (class_dict -- value)) {
+            PyObject *name;
+            assert(class_dict);
             assert(oparg >= 0 && oparg < frame->f_code->co_nlocalsplus);
             name = PyTuple_GET_ITEM(frame->f_code->co_localsplusnames, oparg);
-            if (PyDict_CheckExact(locals)) {
-                value = PyDict_GetItemWithError(locals, name);
+            if (PyDict_CheckExact(class_dict)) {
+                value = PyDict_GetItemWithError(class_dict, name);
                 if (value != NULL) {
                     Py_INCREF(value);
                 }
                 else if (_PyErr_Occurred(tstate)) {
+                    Py_DECREF(class_dict);
                     goto error;
                 }
             }
             else {
-                value = PyObject_GetItem(locals, name);
+                value = PyObject_GetItem(class_dict, name);
                 if (value == NULL) {
                     if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) {
+                        Py_DECREF(class_dict);
                         goto error;
                     }
                     _PyErr_Clear(tstate);
                 }
             }
+            Py_DECREF(class_dict);
             if (!value) {
                 PyObject *cell = GETLOCAL(oparg);
                 value = PyCell_GET(cell);
diff --git a/Python/compile.c b/Python/compile.c
index bf5e4a52482a..7adbf9208989 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -147,6 +147,7 @@ enum {
     COMPILER_SCOPE_ASYNC_FUNCTION,
     COMPILER_SCOPE_LAMBDA,
     COMPILER_SCOPE_COMPREHENSION,
+    COMPILER_SCOPE_TYPEPARAMS,
 };
 
 
@@ -231,6 +232,7 @@ instr_sequence_next_inst(instr_sequence *seq) {
                                           &seq->s_allocated,
                                           INITIAL_INSTR_SEQUENCE_SIZE,
                                           sizeof(instruction)));
+    assert(seq->s_allocated >= 0);
     assert(seq->s_used < seq->s_allocated);
     return seq->s_used++;
 }
@@ -714,6 +716,19 @@ compiler_set_qualname(struct compiler *c)
         capsule = PyList_GET_ITEM(c->c_stack, stack_size - 1);
         parent = (struct compiler_unit *)PyCapsule_GetPointer(capsule, CAPSULE_NAME);
         assert(parent);
+        if (parent->u_scope_type == COMPILER_SCOPE_TYPEPARAMS) {
+            /* The parent is a type parameter scope, so we need to
+               look at the grandparent. */
+            if (stack_size == 2) {
+                // If we're immediately within the module, we can skip
+                // the rest and just set the qualname to be the same as name.
+                u->u_metadata.u_qualname = Py_NewRef(u->u_metadata.u_name);
+                return SUCCESS;
+            }
+            capsule = PyList_GET_ITEM(c->c_stack, stack_size - 2);
+            parent = (struct compiler_unit *)PyCapsule_GetPointer(capsule, CAPSULE_NAME);
+            assert(parent);
+        }
 
         if (u->u_scope_type == COMPILER_SCOPE_FUNCTION
             || u->u_scope_type == COMPILER_SCOPE_ASYNC_FUNCTION
@@ -1114,16 +1129,18 @@ codegen_addop_j(instr_sequence *seq, location loc,
     return instr_sequence_addop(seq, opcode, target.id, loc);
 }
 
-#define ADDOP(C, LOC, OP) \
-    RETURN_IF_ERROR(codegen_addop_noarg(INSTR_SEQUENCE(C), (OP), (LOC)))
-
-#define ADDOP_IN_SCOPE(C, LOC, OP) { \
-    if (codegen_addop_noarg(INSTR_SEQUENCE(C), (OP), (LOC)) < 0) { \
-        compiler_exit_scope(C); \
+#define RETURN_IF_ERROR_IN_SCOPE(C, CALL) { \
+    if ((CALL) < 0) { \
+        compiler_exit_scope((C)); \
         return ERROR; \
     } \
 }
 
+#define ADDOP(C, LOC, OP) \
+    RETURN_IF_ERROR(codegen_addop_noarg(INSTR_SEQUENCE(C), (OP), (LOC)))
+
+#define ADDOP_IN_SCOPE(C, LOC, OP) RETURN_IF_ERROR_IN_SCOPE((C), codegen_addop_noarg(INSTR_SEQUENCE(C), (OP), (LOC)))
+
 #define ADDOP_LOAD_CONST(C, LOC, O) \
     RETURN_IF_ERROR(compiler_addop_load_const((C)->c_const_cache, (C)->u, (LOC), (O)))
 
@@ -1183,12 +1200,8 @@ codegen_addop_j(instr_sequence *seq, location loc,
 #define VISIT(C, TYPE, V) \
     RETURN_IF_ERROR(compiler_visit_ ## TYPE((C), (V)));
 
-#define VISIT_IN_SCOPE(C, TYPE, V) {\
-    if (compiler_visit_ ## TYPE((C), (V)) < 0) { \
-        compiler_exit_scope(C); \
-        return ERROR; \
-    } \
-}
+#define VISIT_IN_SCOPE(C, TYPE, V) \
+    RETURN_IF_ERROR_IN_SCOPE((C), compiler_visit_ ## TYPE((C), (V)))
 
 #define VISIT_SEQ(C, TYPE, SEQ) { \
     int _i; \
@@ -1252,6 +1265,16 @@ compiler_enter_scope(struct compiler *c, identifier name,
             return ERROR;
         }
     }
+    if (u->u_ste->ste_needs_classdict) {
+        /* Cook up an implicit __classdict__ cell. */
+        Py_ssize_t res;
+        assert(u->u_scope_type == COMPILER_SCOPE_CLASS);
+        res = dict_add_o(u->u_metadata.u_cellvars, &_Py_ID(__classdict__));
+        if (res < 0) {
+            compiler_unit_free(u);
+            return ERROR;
+        }
+    }
 
     u->u_metadata.u_freevars = dictbytype(u->u_ste->ste_symbols, FREE, DEF_FREE_CLASS,
                                PyDict_GET_SIZE(u->u_metadata.u_cellvars));
@@ -1718,8 +1741,10 @@ get_ref_type(struct compiler *c, PyObject *name)
 {
     int scope;
     if (c->u->u_scope_type == COMPILER_SCOPE_CLASS &&
-        _PyUnicode_EqualToASCIIString(name, "__class__"))
+        (_PyUnicode_EqualToASCIIString(name, "__class__") ||
+         _PyUnicode_EqualToASCIIString(name, "__classdict__"))) {
         return CELL;
+    }
     scope = _PyST_GetScope(c->u->u_ste, name);
     if (scope == 0) {
         PyErr_Format(PyExc_SystemError,
@@ -2085,26 +2110,81 @@ wrap_in_stopiteration_handler(struct compiler *c)
 }
 
 static int
-compiler_function(struct compiler *c, stmt_ty s, int is_async)
+compiler_type_params(struct compiler *c, asdl_typeparam_seq *typeparams)
+{
+    if (!typeparams) {
+        return SUCCESS;
+    }
+    Py_ssize_t n = asdl_seq_LEN(typeparams);
+
+    for (Py_ssize_t i = 0; i < n; i++) {
+        typeparam_ty typeparam = asdl_seq_GET(typeparams, i);
+        location loc = LOC(typeparam);
+        switch(typeparam->kind) {
+        case TypeVar_kind:
+            ADDOP_LOAD_CONST(c, loc, typeparam->v.TypeVar.name);
+            if (typeparam->v.TypeVar.bound) {
+                expr_ty bound = typeparam->v.TypeVar.bound;
+                if (compiler_enter_scope(c, typeparam->v.TypeVar.name, COMPILER_SCOPE_TYPEPARAMS,
+                                        (void *)typeparam, bound->lineno) == -1) {
+                    return ERROR;
+                }
+                VISIT_IN_SCOPE(c, expr, bound);
+                ADDOP_IN_SCOPE(c, loc, RETURN_VALUE);
+                PyCodeObject *co = optimize_and_assemble(c, 1);
+                compiler_exit_scope(c);
+                if (co == NULL) {
+                    return ERROR;
+                }
+                if (compiler_make_closure(c, loc, co, 0) < 0) {
+                    Py_DECREF(co);
+                    return ERROR;
+                }
+                Py_DECREF(co);
+
+                int intrinsic = bound->kind == Tuple_kind
+                    ? INTRINSIC_TYPEVAR_WITH_CONSTRAINTS
+                    : INTRINSIC_TYPEVAR_WITH_BOUND;
+                ADDOP_I(c, loc, CALL_INTRINSIC_2, intrinsic);
+            }
+            else {
+                ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_TYPEVAR);
+            }
+            ADDOP_I(c, loc, COPY, 1);
+            RETURN_IF_ERROR(compiler_nameop(c, loc, typeparam->v.TypeVar.name, Store));
+            break;
+        case TypeVarTuple_kind:
+            ADDOP_LOAD_CONST(c, loc, typeparam->v.TypeVarTuple.name);
+            ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_TYPEVARTUPLE);
+            ADDOP_I(c, loc, COPY, 1);
+            RETURN_IF_ERROR(compiler_nameop(c, loc, typeparam->v.TypeVarTuple.name, Store));
+            break;
+        case ParamSpec_kind:
+            ADDOP_LOAD_CONST(c, loc, typeparam->v.ParamSpec.name);
+            ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_PARAMSPEC);
+            ADDOP_I(c, loc, COPY, 1);
+            RETURN_IF_ERROR(compiler_nameop(c, loc, typeparam->v.ParamSpec.name, Store));
+            break;
+        }
+    }
+    ADDOP_I(c, LOC(asdl_seq_GET(typeparams, 0)), BUILD_TUPLE, n);
+    return SUCCESS;
+}
+
+static int
+compiler_function_body(struct compiler *c, stmt_ty s, int is_async, Py_ssize_t funcflags,
+                       int firstlineno)
 {
-    PyCodeObject *co;
     PyObject *docstring = NULL;
     arguments_ty args;
-    expr_ty returns;
     identifier name;
-    asdl_expr_seq* decos;
     asdl_stmt_seq *body;
-    Py_ssize_t i, funcflags;
-    int annotations;
     int scope_type;
-    int firstlineno;
 
     if (is_async) {
         assert(s->kind == AsyncFunctionDef_kind);
 
         args = s->v.AsyncFunctionDef.args;
-        returns = s->v.AsyncFunctionDef.returns;
-        decos = s->v.AsyncFunctionDef.decorator_list;
         name = s->v.AsyncFunctionDef.name;
         body = s->v.AsyncFunctionDef.body;
 
@@ -2113,33 +2193,12 @@ compiler_function(struct compiler *c, stmt_ty s, int is_async)
         assert(s->kind == FunctionDef_kind);
 
         args = s->v.FunctionDef.args;
-        returns = s->v.FunctionDef.returns;
-        decos = s->v.FunctionDef.decorator_list;
         name = s->v.FunctionDef.name;
         body = s->v.FunctionDef.body;
 
         scope_type = COMPILER_SCOPE_FUNCTION;
     }
 
-    RETURN_IF_ERROR(compiler_check_debug_args(c, args));
-    RETURN_IF_ERROR(compiler_decorators(c, decos));
-
-    firstlineno = s->lineno;
-    if (asdl_seq_LEN(decos)) {
-        firstlineno = ((expr_ty)asdl_seq_GET(decos, 0))->lineno;
-    }
-
-    location loc = LOC(s);
-    funcflags = compiler_default_arguments(c, loc, args);
-    if (funcflags == -1) {
-        return ERROR;
-    }
-    annotations = compiler_visit_annotations(c, loc, args, returns);
-    RETURN_IF_ERROR(annotations);
-    if (annotations > 0) {
-        funcflags |= 0x04;
-    }
-
     RETURN_IF_ERROR(
         compiler_enter_scope(c, name, scope_type, (void *)s, firstlineno));
 
@@ -2155,7 +2214,7 @@ compiler_function(struct compiler *c, stmt_ty s, int is_async)
     c->u->u_metadata.u_argcount = asdl_seq_LEN(args->args);
     c->u->u_metadata.u_posonlyargcount = asdl_seq_LEN(args->posonlyargs);
     c->u->u_metadata.u_kwonlyargcount = asdl_seq_LEN(args->kwonlyargs);
-    for (i = docstring ? 1 : 0; i < asdl_seq_LEN(body); i++) {
+    for (Py_ssize_t i = docstring ? 1 : 0; i < asdl_seq_LEN(body); i++) {
         VISIT_IN_SCOPE(c, stmt, (stmt_ty)asdl_seq_GET(body, i));
     }
     if (c->u->u_ste->ste_coroutine || c->u->u_ste->ste_generator) {
@@ -2164,29 +2223,52 @@ compiler_function(struct compiler *c, stmt_ty s, int is_async)
             return ERROR;
         }
     }
-    co = optimize_and_assemble(c, 1);
+    PyCodeObject *co = optimize_and_assemble(c, 1);
     compiler_exit_scope(c);
     if (co == NULL) {
         Py_XDECREF(co);
         return ERROR;
     }
+    location loc = LOC(s);
     if (compiler_make_closure(c, loc, co, funcflags) < 0) {
         Py_DECREF(co);
         return ERROR;
     }
     Py_DECREF(co);
-
-    RETURN_IF_ERROR(compiler_apply_decorators(c, decos));
-    return compiler_nameop(c, loc, name, Store);
+    return SUCCESS;
 }
 
 static int
-compiler_class(struct compiler *c, stmt_ty s)
+compiler_function(struct compiler *c, stmt_ty s, int is_async)
 {
-    PyCodeObject *co;
-    int i, firstlineno;
-    asdl_expr_seq *decos = s->v.ClassDef.decorator_list;
+    arguments_ty args;
+    expr_ty returns;
+    identifier name;
+    asdl_expr_seq *decos;
+    asdl_typeparam_seq *typeparams;
+    Py_ssize_t funcflags;
+    int annotations;
+    int firstlineno;
+
+    if (is_async) {
+        assert(s->kind == AsyncFunctionDef_kind);
 
+        args = s->v.AsyncFunctionDef.args;
+        returns = s->v.AsyncFunctionDef.returns;
+        decos = s->v.AsyncFunctionDef.decorator_list;
+        name = s->v.AsyncFunctionDef.name;
+        typeparams = s->v.AsyncFunctionDef.typeparams;
+    } else {
+        assert(s->kind == FunctionDef_kind);
+
+        args = s->v.FunctionDef.args;
+        returns = s->v.FunctionDef.returns;
+        decos = s->v.FunctionDef.decorator_list;
+        name = s->v.FunctionDef.name;
+        typeparams = s->v.FunctionDef.typeparams;
+    }
+
+    RETURN_IF_ERROR(compiler_check_debug_args(c, args));
     RETURN_IF_ERROR(compiler_decorators(c, decos));
 
     firstlineno = s->lineno;
@@ -2194,6 +2276,108 @@ compiler_class(struct compiler *c, stmt_ty s)
         firstlineno = ((expr_ty)asdl_seq_GET(decos, 0))->lineno;
     }
 
+    location loc = LOC(s);
+
+    int is_generic = asdl_seq_LEN(typeparams) > 0;
+
+    if (is_generic) {
+        // Used by the CALL to the type parameters function.
+        ADDOP(c, loc, PUSH_NULL);
+    }
+
+    funcflags = compiler_default_arguments(c, loc, args);
+    if (funcflags == -1) {
+        return ERROR;
+    }
+
+    int num_typeparam_args = 0;
+
+    if (is_generic) {
+        if (funcflags & 0x01) {
+            num_typeparam_args += 1;
+        }
+        if (funcflags & 0x02) {
+            num_typeparam_args += 1;
+        }
+        if (num_typeparam_args == 2) {
+            ADDOP_I(c, loc, SWAP, 2);
+        }
+        PyObject *typeparams_name = PyUnicode_FromFormat("<generic parameters of %U>", name);
+        if (!typeparams_name) {
+            return ERROR;
+        }
+        if (compiler_enter_scope(c, typeparams_name, COMPILER_SCOPE_TYPEPARAMS,
+                                 (void *)typeparams, firstlineno) == -1) {
+            Py_DECREF(typeparams_name);
+            return ERROR;
+        }
+        Py_DECREF(typeparams_name);
+        RETURN_IF_ERROR_IN_SCOPE(c, compiler_type_params(c, typeparams));
+        if ((funcflags & 0x01) || (funcflags & 0x02)) {
+            RETURN_IF_ERROR_IN_SCOPE(c, codegen_addop_i(INSTR_SEQUENCE(c), LOAD_FAST, 0, loc));
+        }
+        if ((funcflags & 0x01) && (funcflags & 0x02)) {
+            RETURN_IF_ERROR_IN_SCOPE(c, codegen_addop_i(INSTR_SEQUENCE(c), LOAD_FAST, 1, loc));
+        }
+    }
+
+    annotations = compiler_visit_annotations(c, loc, args, returns);
+    if (annotations < 0) {
+        if (is_generic) {
+            compiler_exit_scope(c);
+        }
+        return ERROR;
+    }
+    if (annotations > 0) {
+        funcflags |= 0x04;
+    }
+
+    if (compiler_function_body(c, s, is_async, funcflags, firstlineno) < 0) {
+        if (is_generic) {
+            compiler_exit_scope(c);
+        }
+        return ERROR;
+    }
+
+    if (is_generic) {
+        RETURN_IF_ERROR_IN_SCOPE(c, codegen_addop_i(
+            INSTR_SEQUENCE(c), SWAP, 2, loc));
+        RETURN_IF_ERROR_IN_SCOPE(c, codegen_addop_i(
+            INSTR_SEQUENCE(c), CALL_INTRINSIC_2, INTRINSIC_SET_FUNCTION_TYPE_PARAMS, loc));
+
+        c->u->u_metadata.u_argcount = num_typeparam_args;
+        PyCodeObject *co = optimize_and_assemble(c, 0);
+        compiler_exit_scope(c);
+        if (co == NULL) {
+            return ERROR;
+        }
+        if (compiler_make_closure(c, loc, co, 0) < 0) {
+            Py_DECREF(co);
+            return ERROR;
+        }
+        Py_DECREF(co);
+        if (num_typeparam_args > 0) {
+            ADDOP_I(c, loc, SWAP, num_typeparam_args + 1);
+        }
+        ADDOP_I(c, loc, CALL, num_typeparam_args);
+    }
+
+    RETURN_IF_ERROR(compiler_apply_decorators(c, decos));
+    return compiler_nameop(c, loc, name, Store);
+}
+
+static int
+compiler_set_type_params_in_class(struct compiler *c, location loc)
+{
+    _Py_DECLARE_STR(type_params, ".type_params");
+    RETURN_IF_ERROR(compiler_nameop(c, loc, &_Py_STR(type_params), Load));
+    RETURN_IF_ERROR(compiler_nameop(c, loc, &_Py_ID(__type_params__), Store));
+    return 1;
+}
+
+static int
+compiler_class_body(struct compiler *c, stmt_ty s, int firstlineno)
+{
     /* ultimately generate code for:
          <name> = __build_class__(<func>, <name>, *<bases>, **<keywords>)
        where:
@@ -2204,68 +2388,100 @@ compiler_class(struct compiler *c, stmt_ty s)
          <keywords> is the keyword arguments and **kwds argument
        This borrows from compiler_call.
     */
+
     /* 1. compile the class body into a code object */
     RETURN_IF_ERROR(
         compiler_enter_scope(c, s->v.ClassDef.name,
                              COMPILER_SCOPE_CLASS, (void *)s, firstlineno));
 
-    /* this block represents what we do in the new scope */
-    {
-        location loc = LOCATION(firstlineno, firstlineno, 0, 0);
-        /* use the class name for name mangling */
-        Py_XSETREF(c->u->u_private, Py_NewRef(s->v.ClassDef.name));
-        /* load (global) __name__ ... */
-        if (compiler_nameop(c, loc, &_Py_ID(__name__), Load) < 0) {
+    location loc = LOCATION(firstlineno, firstlineno, 0, 0);
+    /* use the class name for name mangling */
+    Py_XSETREF(c->u->u_private, Py_NewRef(s->v.ClassDef.name));
+    /* load (global) __name__ ... */
+    if (compiler_nameop(c, loc, &_Py_ID(__name__), Load) < 0) {
+        compiler_exit_scope(c);
+        return ERROR;
+    }
+    /* ... and store it as __module__ */
+    if (compiler_nameop(c, loc, &_Py_ID(__module__), Store) < 0) {
+        compiler_exit_scope(c);
+        return ERROR;
+    }
+    assert(c->u->u_metadata.u_qualname);
+    ADDOP_LOAD_CONST(c, loc, c->u->u_metadata.u_qualname);
+    if (compiler_nameop(c, loc, &_Py_ID(__qualname__), Store) < 0) {
+        compiler_exit_scope(c);
+        return ERROR;
+    }
+    asdl_typeparam_seq *typeparams = s->v.ClassDef.typeparams;
+    if (asdl_seq_LEN(typeparams) > 0) {
+        if (!compiler_set_type_params_in_class(c, loc)) {
             compiler_exit_scope(c);
             return ERROR;
         }
-        /* ... and store it as __module__ */
-        if (compiler_nameop(c, loc, &_Py_ID(__module__), Store) < 0) {
+    }
+    if (c->u->u_ste->ste_needs_classdict) {
+        ADDOP(c, loc, LOAD_LOCALS);
+
+        // We can't use compiler_nameop here because we need to generate a
+        // STORE_DEREF in a class namespace, and compiler_nameop() won't do
+        // that by default.
+        PyObject *cellvars = c->u->u_metadata.u_cellvars;
+        if (compiler_addop_o(c->u, loc, STORE_DEREF, cellvars,
+                             &_Py_ID(__classdict__)) < 0) {
             compiler_exit_scope(c);
             return ERROR;
         }
-        assert(c->u->u_metadata.u_qualname);
-        ADDOP_LOAD_CONST(c, loc, c->u->u_metadata.u_qualname);
-        if (compiler_nameop(c, loc, &_Py_ID(__qualname__), Store) < 0) {
+    }
+    /* compile the body proper */
+    if (compiler_body(c, loc, s->v.ClassDef.body) < 0) {
+        compiler_exit_scope(c);
+        return ERROR;
+    }
+    /* The following code is artificial */
+    /* Set __classdictcell__ if necessary */
+    if (c->u->u_ste->ste_needs_classdict) {
+        /* Store __classdictcell__ into class namespace */
+        int i = compiler_lookup_arg(c->u->u_metadata.u_cellvars, &_Py_ID(__classdict__));
+        if (i < 0) {
             compiler_exit_scope(c);
             return ERROR;
         }
-        /* compile the body proper */
-        if (compiler_body(c, loc, s->v.ClassDef.body) < 0) {
+        ADDOP_I(c, NO_LOCATION, LOAD_CLOSURE, i);
+        if (compiler_nameop(c, NO_LOCATION, &_Py_ID(__classdictcell__), Store) < 0) {
             compiler_exit_scope(c);
             return ERROR;
         }
-        /* The following code is artificial */
-        /* Return __classcell__ if it is referenced, otherwise return None */
-        if (c->u->u_ste->ste_needs_class_closure) {
-            /* Store __classcell__ into class namespace & return it */
-            i = compiler_lookup_arg(c->u->u_metadata.u_cellvars, &_Py_ID(__class__));
-            if (i < 0) {
-                compiler_exit_scope(c);
-                return ERROR;
-            }
-            ADDOP_I(c, NO_LOCATION, LOAD_CLOSURE, i);
-            ADDOP_I(c, NO_LOCATION, COPY, 1);
-            if (compiler_nameop(c, NO_LOCATION, &_Py_ID(__classcell__), Store) < 0) {
-                compiler_exit_scope(c);
-                return ERROR;
-            }
+    }
+    /* Return __classcell__ if it is referenced, otherwise return None */
+    if (c->u->u_ste->ste_needs_class_closure) {
+        /* Store __classcell__ into class namespace & return it */
+        int i = compiler_lookup_arg(c->u->u_metadata.u_cellvars, &_Py_ID(__class__));
+        if (i < 0) {
+            compiler_exit_scope(c);
+            return ERROR;
         }
-        else {
-            /* No methods referenced __class__, so just return None */
-            ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
+        ADDOP_I(c, NO_LOCATION, LOAD_CLOSURE, i);
+        ADDOP_I(c, NO_LOCATION, COPY, 1);
+        if (compiler_nameop(c, NO_LOCATION, &_Py_ID(__classcell__), Store) < 0) {
+            compiler_exit_scope(c);
+            return ERROR;
         }
-        ADDOP_IN_SCOPE(c, NO_LOCATION, RETURN_VALUE);
-        /* create the code object */
-        co = optimize_and_assemble(c, 1);
     }
+    else {
+        /* No methods referenced __class__, so just return None */
+        ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
+    }
+    ADDOP_IN_SCOPE(c, NO_LOCATION, RETURN_VALUE);
+    /* create the code object */
+    PyCodeObject *co = optimize_and_assemble(c, 1);
+
     /* leave the new scope */
     compiler_exit_scope(c);
     if (co == NULL) {
         return ERROR;
     }
 
-    location loc = LOC(s);
     /* 2. load the 'build_class' function */
     ADDOP(c, loc, PUSH_NULL);
     ADDOP(c, loc, LOAD_BUILD_CLASS);
@@ -2280,10 +2496,100 @@ compiler_class(struct compiler *c, stmt_ty s)
     /* 4. load class name */
     ADDOP_LOAD_CONST(c, loc, s->v.ClassDef.name);
 
-    /* 5. generate the rest of the code for the call */
-    RETURN_IF_ERROR(compiler_call_helper(c, loc, 2,
-                                         s->v.ClassDef.bases,
-                                         s->v.ClassDef.keywords));
+    return SUCCESS;
+}
+
+static int
+compiler_class(struct compiler *c, stmt_ty s)
+{
+    asdl_expr_seq *decos = s->v.ClassDef.decorator_list;
+
+    RETURN_IF_ERROR(compiler_decorators(c, decos));
+
+    int firstlineno = s->lineno;
+    if (asdl_seq_LEN(decos)) {
+        firstlineno = ((expr_ty)asdl_seq_GET(decos, 0))->lineno;
+    }
+    location loc = LOC(s);
+
+    asdl_typeparam_seq *typeparams = s->v.ClassDef.typeparams;
+    int is_generic = asdl_seq_LEN(typeparams) > 0;
+    if (is_generic) {
+        Py_XSETREF(c->u->u_private, Py_NewRef(s->v.ClassDef.name));
+        ADDOP(c, loc, PUSH_NULL);
+        PyObject *typeparams_name = PyUnicode_FromFormat("<generic parameters of %U>",
+                                                         s->v.ClassDef.name);
+        if (!typeparams_name) {
+            return ERROR;
+        }
+        if (compiler_enter_scope(c, typeparams_name, COMPILER_SCOPE_TYPEPARAMS,
+                                 (void *)typeparams, firstlineno) == -1) {
+            Py_DECREF(typeparams_name);
+            return ERROR;
+        }
+        Py_DECREF(typeparams_name);
+        RETURN_IF_ERROR_IN_SCOPE(c, compiler_type_params(c, typeparams));
+        _Py_DECLARE_STR(type_params, ".type_params");
+        RETURN_IF_ERROR_IN_SCOPE(c, compiler_nameop(c, loc, &_Py_STR(type_params), Store));
+    }
+
+    if (compiler_class_body(c, s, firstlineno) < 0) {
+        if (is_generic) {
+            compiler_exit_scope(c);
+        }
+        return ERROR;
+    }
+
+    /* generate the rest of the code for the call */
+
+    if (is_generic) {
+        _Py_DECLARE_STR(type_params, ".type_params");
+        _Py_DECLARE_STR(generic_base, ".generic_base");
+        RETURN_IF_ERROR_IN_SCOPE(c, compiler_nameop(c, loc, &_Py_STR(type_params), Load));
+        RETURN_IF_ERROR_IN_SCOPE(
+            c, codegen_addop_i(INSTR_SEQUENCE(c), CALL_INTRINSIC_1, INTRINSIC_SUBSCRIPT_GENERIC, loc)
+        )
+        RETURN_IF_ERROR_IN_SCOPE(c, compiler_nameop(c, loc, &_Py_STR(generic_base), Store));
+
+        Py_ssize_t original_len = asdl_seq_LEN(s->v.ClassDef.bases);
+        asdl_expr_seq *bases = _Py_asdl_expr_seq_new(
+            original_len + 1, c->c_arena);
+        if (bases == NULL) {
+            compiler_exit_scope(c);
+            return ERROR;
+        }
+        for (Py_ssize_t i = 0; i < original_len; i++) {
+            asdl_seq_SET(bases, i, asdl_seq_GET(s->v.ClassDef.bases, i));
+        }
+        expr_ty name_node = _PyAST_Name(
+            &_Py_STR(generic_base), Load,
+            loc.lineno, loc.col_offset, loc.end_lineno, loc.end_col_offset, c->c_arena
+        );
+        if (name_node == NULL) {
+            compiler_exit_scope(c);
+            return ERROR;
+        }
+        asdl_seq_SET(bases, original_len, name_node);
+        RETURN_IF_ERROR_IN_SCOPE(c, compiler_call_helper(c, loc, 2,
+                                                         bases,
+                                                         s->v.ClassDef.keywords));
+
+        PyCodeObject *co = optimize_and_assemble(c, 0);
+        compiler_exit_scope(c);
+        if (co == NULL) {
+            return ERROR;
+        }
+        if (compiler_make_closure(c, loc, co, 0) < 0) {
+            Py_DECREF(co);
+            return ERROR;
+        }
+        Py_DECREF(co);
+        ADDOP_I(c, loc, CALL, 0);
+    } else {
+        RETURN_IF_ERROR(compiler_call_helper(c, loc, 2,
+                                            s->v.ClassDef.bases,
+                                            s->v.ClassDef.keywords));
+    }
 
     /* 6. apply decorators */
     RETURN_IF_ERROR(compiler_apply_decorators(c, decos));
@@ -2293,6 +2599,87 @@ compiler_class(struct compiler *c, stmt_ty s)
     return SUCCESS;
 }
 
+static int
+compiler_typealias_body(struct compiler *c, stmt_ty s)
+{
+    location loc = LOC(s);
+    PyObject *name = s->v.TypeAlias.name->v.Name.id;
+    RETURN_IF_ERROR(
+        compiler_enter_scope(c, name, COMPILER_SCOPE_FUNCTION, s, loc.lineno));
+    /* Make None the first constant, so the evaluate function can't have a
+        docstring. */
+    RETURN_IF_ERROR(compiler_add_const(c->c_const_cache, c->u, Py_None));
+    VISIT_IN_SCOPE(c, expr, s->v.TypeAlias.value);
+    ADDOP_IN_SCOPE(c, loc, RETURN_VALUE);
+    PyCodeObject *co = optimize_and_assemble(c, 0);
+    compiler_exit_scope(c);
+    if (co == NULL) {
+        return ERROR;
+    }
+    if (compiler_make_closure(c, loc, co, 0) < 0) {
+        Py_DECREF(co);
+        return ERROR;
+    }
+    Py_DECREF(co);
+    ADDOP_I(c, loc, BUILD_TUPLE, 3);
+    ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_TYPEALIAS);
+    return SUCCESS;
+}
+
+static int
+compiler_typealias(struct compiler *c, stmt_ty s)
+{
+    location loc = LOC(s);
+    asdl_typeparam_seq *typeparams = s->v.TypeAlias.typeparams;
+    int is_generic = asdl_seq_LEN(typeparams) > 0;
+    PyObject *name = s->v.TypeAlias.name->v.Name.id;
+    if (is_generic) {
+        ADDOP(c, loc, PUSH_NULL);
+        PyObject *typeparams_name = PyUnicode_FromFormat("<generic parameters of %U>",
+                                                         name);
+        if (!typeparams_name) {
+            return ERROR;
+        }
+        if (compiler_enter_scope(c, typeparams_name, COMPILER_SCOPE_TYPEPARAMS,
+                                 (void *)typeparams, loc.lineno) == -1) {
+            Py_DECREF(typeparams_name);
+            return ERROR;
+        }
+        Py_DECREF(typeparams_name);
+        RETURN_IF_ERROR_IN_SCOPE(
+            c, compiler_addop_load_const(c->c_const_cache, c->u, loc, name)
+        );
+        RETURN_IF_ERROR_IN_SCOPE(c, compiler_type_params(c, typeparams));
+    }
+    else {
+        ADDOP_LOAD_CONST(c, loc, name);
+        ADDOP_LOAD_CONST(c, loc, Py_None);
+    }
+
+    if (compiler_typealias_body(c, s) < 0) {
+        if (is_generic) {
+            compiler_exit_scope(c);
+        }
+        return ERROR;
+    }
+
+    if (is_generic) {
+        PyCodeObject *co = optimize_and_assemble(c, 0);
+        compiler_exit_scope(c);
+        if (co == NULL) {
+            return ERROR;
+        }
+        if (compiler_make_closure(c, loc, co, 0) < 0) {
+            Py_DECREF(co);
+            return ERROR;
+        }
+        Py_DECREF(co);
+        ADDOP_I(c, loc, CALL, 0);
+    }
+    RETURN_IF_ERROR(compiler_nameop(c, loc, name, Store));
+    return SUCCESS;
+}
+
 /* Return false if the expression is a constant value except named singletons.
    Return true otherwise. */
 static bool
@@ -2705,7 +3092,7 @@ compiler_return(struct compiler *c, stmt_ty s)
     location loc = LOC(s);
     int preserve_tos = ((s->v.Return.value != NULL) &&
                         (s->v.Return.value->kind != Constant_kind));
-    if (c->u->u_ste->ste_type != FunctionBlock) {
+    if (!_PyST_IsFunctionLike(c->u->u_ste)) {
         return compiler_error(c, loc, "'return' outside function");
     }
     if (s->v.Return.value != NULL &&
@@ -3519,6 +3906,8 @@ compiler_visit_stmt(struct compiler *c, stmt_ty s)
         return compiler_function(c, s, 0);
     case ClassDef_kind:
         return compiler_class(c, s);
+    case TypeAlias_kind:
+        return compiler_typealias(c, s);
     case Return_kind:
         return compiler_return(c, s);
     case Delete_kind:
@@ -3725,12 +4114,12 @@ compiler_nameop(struct compiler *c, location loc,
         optype = OP_DEREF;
         break;
     case LOCAL:
-        if (c->u->u_ste->ste_type == FunctionBlock ||
+        if (_PyST_IsFunctionLike(c->u->u_ste) ||
                 (PyDict_GetItem(c->u->u_metadata.u_fasthidden, mangled) == Py_True))
             optype = OP_FAST;
         break;
     case GLOBAL_IMPLICIT:
-        if (c->u->u_ste->ste_type == FunctionBlock)
+        if (_PyST_IsFunctionLike(c->u->u_ste))
             optype = OP_GLOBAL;
         break;
     case GLOBAL_EXPLICIT:
@@ -3748,7 +4137,24 @@ compiler_nameop(struct compiler *c, location loc,
     case OP_DEREF:
         switch (ctx) {
         case Load:
-            op = (c->u->u_ste->ste_type == ClassBlock) ? LOAD_CLASSDEREF : LOAD_DEREF;
+            if (c->u->u_ste->ste_type == ClassBlock) {
+                op = LOAD_FROM_DICT_OR_DEREF;
+                // First load the locals
+                if (codegen_addop_noarg(INSTR_SEQUENCE(c), LOAD_LOCALS, loc) < 0) {
+                    return ERROR;
+                }
+            }
+            else if (c->u->u_ste->ste_can_see_class_scope) {
+                op = LOAD_FROM_DICT_OR_DEREF;
+                // First load the classdict
+                if (compiler_addop_o(c->u, loc, LOAD_DEREF,
+                                     c->u->u_metadata.u_freevars, &_Py_ID(__classdict__)) < 0) {
+                    return ERROR;
+                }
+            }
+            else {
+                op = LOAD_DEREF;
+            }
             break;
         case Store: op = STORE_DEREF; break;
         case Del: op = DELETE_DEREF; break;
@@ -3764,7 +4170,18 @@ compiler_nameop(struct compiler *c, location loc,
         return SUCCESS;
     case OP_GLOBAL:
         switch (ctx) {
-        case Load: op = LOAD_GLOBAL; break;
+        case Load:
+            if (c->u->u_ste->ste_can_see_class_scope && scope == GLOBAL_IMPLICIT) {
+                op = LOAD_FROM_DICT_OR_GLOBALS;
+                // First load the classdict
+                if (compiler_addop_o(c->u, loc, LOAD_DEREF,
+                                     c->u->u_metadata.u_freevars, &_Py_ID(__classdict__)) < 0) {
+                    return ERROR;
+                }
+            } else {
+                op = LOAD_GLOBAL;
+            }
+            break;
         case Store: op = STORE_GLOBAL; break;
         case Del: op = DELETE_GLOBAL; break;
         }
@@ -5008,7 +5425,7 @@ push_inlined_comprehension_state(struct compiler *c, location loc,
         // assignment expression to a nonlocal in the comprehension, these don't
         // need handling here since they shouldn't be isolated
         if (symbol & DEF_LOCAL && !(symbol & DEF_NONLOCAL)) {
-            if (c->u->u_ste->ste_type != FunctionBlock) {
+            if (!_PyST_IsFunctionLike(c->u->u_ste)) {
                 // non-function scope: override this name to use fast locals
                 PyObject *orig = PyDict_GetItem(c->u->u_metadata.u_fasthidden, k);
                 if (orig != Py_True) {
@@ -5604,7 +6021,7 @@ compiler_visit_expr1(struct compiler *c, expr_ty e)
     case DictComp_kind:
         return compiler_dictcomp(c, e);
     case Yield_kind:
-        if (c->u->u_ste->ste_type != FunctionBlock) {
+        if (!_PyST_IsFunctionLike(c->u->u_ste)) {
             return compiler_error(c, loc, "'yield' outside function");
         }
         if (e->v.Yield.value) {
@@ -5616,7 +6033,7 @@ compiler_visit_expr1(struct compiler *c, expr_ty e)
         ADDOP_YIELD(c, loc);
         break;
     case YieldFrom_kind:
-        if (c->u->u_ste->ste_type != FunctionBlock) {
+        if (!_PyST_IsFunctionLike(c->u->u_ste)) {
             return compiler_error(c, loc, "'yield' outside function");
         }
         if (c->u->u_scope_type == COMPILER_SCOPE_ASYNC_FUNCTION) {
@@ -5629,7 +6046,7 @@ compiler_visit_expr1(struct compiler *c, expr_ty e)
         break;
     case Await_kind:
         if (!IS_TOP_LEVEL_AWAIT(c)){
-            if (c->u->u_ste->ste_type != FunctionBlock){
+            if (!_PyST_IsFunctionLike(c->u->u_ste)) {
                 return compiler_error(c, loc, "'await' outside function");
             }
 
@@ -6916,7 +7333,7 @@ compute_code_flags(struct compiler *c)
 {
     PySTEntryObject *ste = c->u->u_ste;
     int flags = 0;
-    if (ste->ste_type == FunctionBlock) {
+    if (_PyST_IsFunctionLike(c->u->u_ste)) {
         flags |= CO_NEWLOCALS | CO_OPTIMIZED;
         if (ste->ste_nested)
             flags |= CO_NESTED;
@@ -7114,7 +7531,7 @@ fix_cell_offsets(_PyCompile_CodeUnitMetadata *umd, basicblock *entryblock, int *
                 case LOAD_DEREF:
                 case STORE_DEREF:
                 case DELETE_DEREF:
-                case LOAD_CLASSDEREF:
+                case LOAD_FROM_DICT_OR_DEREF:
                     assert(oldoffset >= 0);
                     assert(oldoffset < noffsets);
                     assert(fixedmap[oldoffset] >= 0);
diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h
index 014a69ff7e96..fa4ff5ccee78 100644
--- a/Python/generated_cases.c.h
+++ b/Python/generated_cases.c.h
@@ -8,7 +8,7 @@
         }
 
         TARGET(RESUME) {
-            #line 137 "Python/bytecodes.c"
+            #line 138 "Python/bytecodes.c"
             assert(tstate->cframe == &cframe);
             assert(frame == cframe.current_frame);
             /* Possibly combine this with eval breaker */
@@ -25,7 +25,7 @@
         }
 
         TARGET(INSTRUMENTED_RESUME) {
-            #line 151 "Python/bytecodes.c"
+            #line 152 "Python/bytecodes.c"
             /* Possible performance enhancement:
              *   We need to check the eval breaker anyway, can we
              * combine the instrument verison check and the eval breaker test?
@@ -57,7 +57,7 @@
 
         TARGET(LOAD_CLOSURE) {
             PyObject *value;
-            #line 179 "Python/bytecodes.c"
+            #line 180 "Python/bytecodes.c"
             /* We keep LOAD_CLOSURE so that the bytecode stays more readable. */
             value = GETLOCAL(oparg);
             if (value == NULL) goto unbound_local_error;
@@ -70,7 +70,7 @@
 
         TARGET(LOAD_FAST_CHECK) {
             PyObject *value;
-            #line 186 "Python/bytecodes.c"
+            #line 187 "Python/bytecodes.c"
             value = GETLOCAL(oparg);
             if (value == NULL) goto unbound_local_error;
             Py_INCREF(value);
@@ -82,7 +82,7 @@
 
         TARGET(LOAD_FAST) {
             PyObject *value;
-            #line 192 "Python/bytecodes.c"
+            #line 193 "Python/bytecodes.c"
             value = GETLOCAL(oparg);
             assert(value != NULL);
             Py_INCREF(value);
@@ -94,7 +94,7 @@
 
         TARGET(LOAD_FAST_AND_CLEAR) {
             PyObject *value;
-            #line 198 "Python/bytecodes.c"
+            #line 199 "Python/bytecodes.c"
             value = GETLOCAL(oparg);
             // do not use SETLOCAL here, it decrefs the old value
             GETLOCAL(oparg) = NULL;
@@ -107,7 +107,7 @@
         TARGET(LOAD_CONST) {
             PREDICTED(LOAD_CONST);
             PyObject *value;
-            #line 204 "Python/bytecodes.c"
+            #line 205 "Python/bytecodes.c"
             value = GETITEM(frame->f_code->co_consts, oparg);
             Py_INCREF(value);
             #line 114 "Python/generated_cases.c.h"
@@ -118,7 +118,7 @@
 
         TARGET(STORE_FAST) {
             PyObject *value = stack_pointer[-1];
-            #line 209 "Python/bytecodes.c"
+            #line 210 "Python/bytecodes.c"
             SETLOCAL(oparg, value);
             #line 124 "Python/generated_cases.c.h"
             STACK_SHRINK(1);
@@ -130,7 +130,7 @@
             PyObject *_tmp_2;
             {
                 PyObject *value;
-                #line 192 "Python/bytecodes.c"
+                #line 193 "Python/bytecodes.c"
                 value = GETLOCAL(oparg);
                 assert(value != NULL);
                 Py_INCREF(value);
@@ -140,7 +140,7 @@
             oparg = (next_instr++)->op.arg;
             {
                 PyObject *value;
-                #line 192 "Python/bytecodes.c"
+                #line 193 "Python/bytecodes.c"
                 value = GETLOCAL(oparg);
                 assert(value != NULL);
                 Py_INCREF(value);
@@ -158,7 +158,7 @@
             PyObject *_tmp_2;
             {
                 PyObject *value;
-                #line 192 "Python/bytecodes.c"
+                #line 193 "Python/bytecodes.c"
                 value = GETLOCAL(oparg);
                 assert(value != NULL);
                 Py_INCREF(value);
@@ -168,7 +168,7 @@
             oparg = (next_instr++)->op.arg;
             {
                 PyObject *value;
-                #line 204 "Python/bytecodes.c"
+                #line 205 "Python/bytecodes.c"
                 value = GETITEM(frame->f_code->co_consts, oparg);
                 Py_INCREF(value);
                 #line 175 "Python/generated_cases.c.h"
@@ -184,14 +184,14 @@
             PyObject *_tmp_1 = stack_pointer[-1];
             {
                 PyObject *value = _tmp_1;
-                #line 209 "Python/bytecodes.c"
+                #line 210 "Python/bytecodes.c"
                 SETLOCAL(oparg, value);
                 #line 190 "Python/generated_cases.c.h"
             }
             oparg = (next_instr++)->op.arg;
             {
                 PyObject *value;
-                #line 192 "Python/bytecodes.c"
+                #line 193 "Python/bytecodes.c"
                 value = GETLOCAL(oparg);
                 assert(value != NULL);
                 Py_INCREF(value);
@@ -207,14 +207,14 @@
             PyObject *_tmp_2 = stack_pointer[-2];
             {
                 PyObject *value = _tmp_1;
-                #line 209 "Python/bytecodes.c"
+                #line 210 "Python/bytecodes.c"
                 SETLOCAL(oparg, value);
                 #line 213 "Python/generated_cases.c.h"
             }
             oparg = (next_instr++)->op.arg;
             {
                 PyObject *value = _tmp_2;
-                #line 209 "Python/bytecodes.c"
+                #line 210 "Python/bytecodes.c"
                 SETLOCAL(oparg, value);
                 #line 220 "Python/generated_cases.c.h"
             }
@@ -227,7 +227,7 @@
             PyObject *_tmp_2;
             {
                 PyObject *value;
-                #line 204 "Python/bytecodes.c"
+                #line 205 "Python/bytecodes.c"
                 value = GETITEM(frame->f_code->co_consts, oparg);
                 Py_INCREF(value);
                 #line 234 "Python/generated_cases.c.h"
@@ -236,7 +236,7 @@
             oparg = (next_instr++)->op.arg;
             {
                 PyObject *value;
-                #line 192 "Python/bytecodes.c"
+                #line 193 "Python/bytecodes.c"
                 value = GETLOCAL(oparg);
                 assert(value != NULL);
                 Py_INCREF(value);
@@ -251,7 +251,7 @@
 
         TARGET(POP_TOP) {
             PyObject *value = stack_pointer[-1];
-            #line 219 "Python/bytecodes.c"
+            #line 220 "Python/bytecodes.c"
             #line 256 "Python/generated_cases.c.h"
             Py_DECREF(value);
             STACK_SHRINK(1);
@@ -260,7 +260,7 @@
 
         TARGET(PUSH_NULL) {
             PyObject *res;
-            #line 223 "Python/bytecodes.c"
+            #line 224 "Python/bytecodes.c"
             res = NULL;
             #line 266 "Python/generated_cases.c.h"
             STACK_GROW(1);
@@ -273,13 +273,13 @@
             PyObject *_tmp_2 = stack_pointer[-2];
             {
                 PyObject *value = _tmp_1;
-                #line 219 "Python/bytecodes.c"
+                #line 220 "Python/bytecodes.c"
                 #line 278 "Python/generated_cases.c.h"
                 Py_DECREF(value);
             }
             {
                 PyObject *value = _tmp_2;
-                #line 219 "Python/bytecodes.c"
+                #line 220 "Python/bytecodes.c"
                 #line 284 "Python/generated_cases.c.h"
                 Py_DECREF(value);
             }
@@ -290,7 +290,7 @@
         TARGET(INSTRUMENTED_END_FOR) {
             PyObject *value = stack_pointer[-1];
             PyObject *receiver = stack_pointer[-2];
-            #line 229 "Python/bytecodes.c"
+            #line 230 "Python/bytecodes.c"
             /* Need to create a fake StopIteration error here,
              * to conform to PEP 380 */
             if (PyGen_Check(receiver)) {
@@ -310,7 +310,7 @@
         TARGET(END_SEND) {
             PyObject *value = stack_pointer[-1];
             PyObject *receiver = stack_pointer[-2];
-            #line 242 "Python/bytecodes.c"
+            #line 243 "Python/bytecodes.c"
             Py_DECREF(receiver);
             #line 316 "Python/generated_cases.c.h"
             STACK_SHRINK(1);
@@ -321,7 +321,7 @@
         TARGET(INSTRUMENTED_END_SEND) {
             PyObject *value = stack_pointer[-1];
             PyObject *receiver = stack_pointer[-2];
-            #line 246 "Python/bytecodes.c"
+            #line 247 "Python/bytecodes.c"
             if (PyGen_Check(receiver) || PyCoro_CheckExact(receiver)) {
                 PyErr_SetObject(PyExc_StopIteration, value);
                 if (monitor_stop_iteration(tstate, frame, next_instr-1)) {
@@ -339,11 +339,11 @@
         TARGET(UNARY_NEGATIVE) {
             PyObject *value = stack_pointer[-1];
             PyObject *res;
-            #line 257 "Python/bytecodes.c"
+            #line 258 "Python/bytecodes.c"
             res = PyNumber_Negative(value);
             #line 345 "Python/generated_cases.c.h"
             Py_DECREF(value);
-            #line 259 "Python/bytecodes.c"
+            #line 260 "Python/bytecodes.c"
             if (res == NULL) goto pop_1_error;
             #line 349 "Python/generated_cases.c.h"
             stack_pointer[-1] = res;
@@ -353,11 +353,11 @@
         TARGET(UNARY_NOT) {
             PyObject *value = stack_pointer[-1];
             PyObject *res;
-            #line 263 "Python/bytecodes.c"
+            #line 264 "Python/bytecodes.c"
             int err = PyObject_IsTrue(value);
             #line 359 "Python/generated_cases.c.h"
             Py_DECREF(value);
-            #line 265 "Python/bytecodes.c"
+            #line 266 "Python/bytecodes.c"
             if (err < 0) goto pop_1_error;
             if (err == 0) {
                 res = Py_True;
@@ -374,11 +374,11 @@
         TARGET(UNARY_INVERT) {
             PyObject *value = stack_pointer[-1];
             PyObject *res;
-            #line 276 "Python/bytecodes.c"
+            #line 277 "Python/bytecodes.c"
             res = PyNumber_Invert(value);
             #line 380 "Python/generated_cases.c.h"
             Py_DECREF(value);
-            #line 278 "Python/bytecodes.c"
+            #line 279 "Python/bytecodes.c"
             if (res == NULL) goto pop_1_error;
             #line 384 "Python/generated_cases.c.h"
             stack_pointer[-1] = res;
@@ -389,7 +389,7 @@
             PyObject *right = stack_pointer[-1];
             PyObject *left = stack_pointer[-2];
             PyObject *prod;
-            #line 295 "Python/bytecodes.c"
+            #line 296 "Python/bytecodes.c"
             DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP);
             DEOPT_IF(!PyLong_CheckExact(right), BINARY_OP);
             STAT_INC(BINARY_OP, hit);
@@ -408,7 +408,7 @@
             PyObject *right = stack_pointer[-1];
             PyObject *left = stack_pointer[-2];
             PyObject *prod;
-            #line 305 "Python/bytecodes.c"
+            #line 306 "Python/bytecodes.c"
             DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP);
             DEOPT_IF(!PyFloat_CheckExact(right), BINARY_OP);
             STAT_INC(BINARY_OP, hit);
@@ -426,7 +426,7 @@
             PyObject *right = stack_pointer[-1];
             PyObject *left = stack_pointer[-2];
             PyObject *sub;
-            #line 314 "Python/bytecodes.c"
+            #line 315 "Python/bytecodes.c"
             DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP);
             DEOPT_IF(!PyLong_CheckExact(right), BINARY_OP);
             STAT_INC(BINARY_OP, hit);
@@ -445,7 +445,7 @@
             PyObject *right = stack_pointer[-1];
             PyObject *left = stack_pointer[-2];
             PyObject *sub;
-            #line 324 "Python/bytecodes.c"
+            #line 325 "Python/bytecodes.c"
             DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP);
             DEOPT_IF(!PyFloat_CheckExact(right), BINARY_OP);
             STAT_INC(BINARY_OP, hit);
@@ -462,7 +462,7 @@
             PyObject *right = stack_pointer[-1];
             PyObject *left = stack_pointer[-2];
             PyObject *res;
-            #line 332 "Python/bytecodes.c"
+            #line 333 "Python/bytecodes.c"
             DEOPT_IF(!PyUnicode_CheckExact(left), BINARY_OP);
             DEOPT_IF(Py_TYPE(right) != Py_TYPE(left), BINARY_OP);
             STAT_INC(BINARY_OP, hit);
@@ -480,7 +480,7 @@
         TARGET(BINARY_OP_INPLACE_ADD_UNICODE) {
             PyObject *right = stack_pointer[-1];
             PyObject *left = stack_pointer[-2];
-            #line 348 "Python/bytecodes.c"
+            #line 349 "Python/bytecodes.c"
             DEOPT_IF(!PyUnicode_CheckExact(left), BINARY_OP);
             DEOPT_IF(Py_TYPE(right) != Py_TYPE(left), BINARY_OP);
             _Py_CODEUNIT true_next = next_instr[INLINE_CACHE_ENTRIES_BINARY_OP];
@@ -516,7 +516,7 @@
             PyObject *right = stack_pointer[-1];
             PyObject *left = stack_pointer[-2];
             PyObject *sum;
-            #line 377 "Python/bytecodes.c"
+            #line 378 "Python/bytecodes.c"
             DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP);
             DEOPT_IF(Py_TYPE(right) != Py_TYPE(left), BINARY_OP);
             STAT_INC(BINARY_OP, hit);
@@ -534,7 +534,7 @@
             PyObject *right = stack_pointer[-1];
             PyObject *left = stack_pointer[-2];
             PyObject *sum;
-            #line 386 "Python/bytecodes.c"
+            #line 387 "Python/bytecodes.c"
             DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP);
             DEOPT_IF(Py_TYPE(right) != Py_TYPE(left), BINARY_OP);
             STAT_INC(BINARY_OP, hit);
@@ -555,7 +555,7 @@
             PyObject *sub = stack_pointer[-1];
             PyObject *container = stack_pointer[-2];
             PyObject *res;
-            #line 404 "Python/bytecodes.c"
+            #line 405 "Python/bytecodes.c"
             #if ENABLE_SPECIALIZATION
             _PyBinarySubscrCache *cache = (_PyBinarySubscrCache *)next_instr;
             if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
@@ -570,7 +570,7 @@
             #line 571 "Python/generated_cases.c.h"
             Py_DECREF(container);
             Py_DECREF(sub);
-            #line 416 "Python/bytecodes.c"
+            #line 417 "Python/bytecodes.c"
             if (res == NULL) goto pop_2_error;
             #line 576 "Python/generated_cases.c.h"
             STACK_SHRINK(1);
@@ -584,7 +584,7 @@
             PyObject *start = stack_pointer[-2];
             PyObject *container = stack_pointer[-3];
             PyObject *res;
-            #line 420 "Python/bytecodes.c"
+            #line 421 "Python/bytecodes.c"
             PyObject *slice = _PyBuildSlice_ConsumeRefs(start, stop);
             // Can't use ERROR_IF() here, because we haven't
             // DECREF'ed container yet, and we still own slice.
@@ -608,7 +608,7 @@
             PyObject *start = stack_pointer[-2];
             PyObject *container = stack_pointer[-3];
             PyObject *v = stack_pointer[-4];
-            #line 435 "Python/bytecodes.c"
+            #line 436 "Python/bytecodes.c"
             PyObject *slice = _PyBuildSlice_ConsumeRefs(start, stop);
             int err;
             if (slice == NULL) {
@@ -630,7 +630,7 @@
             PyObject *sub = stack_pointer[-1];
             PyObject *list = stack_pointer[-2];
             PyObject *res;
-            #line 450 "Python/bytecodes.c"
+            #line 451 "Python/bytecodes.c"
             DEOPT_IF(!PyLong_CheckExact(sub), BINARY_SUBSCR);
             DEOPT_IF(!PyList_CheckExact(list), BINARY_SUBSCR);
 
@@ -655,7 +655,7 @@
             PyObject *sub = stack_pointer[-1];
             PyObject *tuple = stack_pointer[-2];
             PyObject *res;
-            #line 466 "Python/bytecodes.c"
+            #line 467 "Python/bytecodes.c"
             DEOPT_IF(!PyLong_CheckExact(sub), BINARY_SUBSCR);
             DEOPT_IF(!PyTuple_CheckExact(tuple), BINARY_SUBSCR);
 
@@ -680,7 +680,7 @@
             PyObject *sub = stack_pointer[-1];
             PyObject *dict = stack_pointer[-2];
             PyObject *res;
-            #line 482 "Python/bytecodes.c"
+            #line 483 "Python/bytecodes.c"
             DEOPT_IF(!PyDict_CheckExact(dict), BINARY_SUBSCR);
             STAT_INC(BINARY_SUBSCR, hit);
             res = PyDict_GetItemWithError(dict, sub);
@@ -691,7 +691,7 @@
             #line 692 "Python/generated_cases.c.h"
                 Py_DECREF(dict);
                 Py_DECREF(sub);
-            #line 490 "Python/bytecodes.c"
+            #line 491 "Python/bytecodes.c"
                 if (true) goto pop_2_error;
             }
             Py_INCREF(res);  // Do this before DECREF'ing dict, sub
@@ -707,7 +707,7 @@
         TARGET(BINARY_SUBSCR_GETITEM) {
             PyObject *sub = stack_pointer[-1];
             PyObject *container = stack_pointer[-2];
-            #line 497 "Python/bytecodes.c"
+            #line 498 "Python/bytecodes.c"
             DEOPT_IF(tstate->interp->eval_frame, BINARY_SUBSCR);
             PyTypeObject *tp = Py_TYPE(container);
             DEOPT_IF(!PyType_HasFeature(tp, Py_TPFLAGS_HEAPTYPE), BINARY_SUBSCR);
@@ -736,7 +736,7 @@
         TARGET(LIST_APPEND) {
             PyObject *v = stack_pointer[-1];
             PyObject *list = stack_pointer[-(2 + (oparg-1))];
-            #line 522 "Python/bytecodes.c"
+            #line 523 "Python/bytecodes.c"
             if (_PyList_AppendTakeRef((PyListObject *)list, v) < 0) goto pop_1_error;
             #line 742 "Python/generated_cases.c.h"
             STACK_SHRINK(1);
@@ -747,11 +747,11 @@
         TARGET(SET_ADD) {
             PyObject *v = stack_pointer[-1];
             PyObject *set = stack_pointer[-(2 + (oparg-1))];
-            #line 527 "Python/bytecodes.c"
+            #line 528 "Python/bytecodes.c"
             int err = PySet_Add(set, v);
             #line 753 "Python/generated_cases.c.h"
             Py_DECREF(v);
-            #line 529 "Python/bytecodes.c"
+            #line 530 "Python/bytecodes.c"
             if (err) goto pop_1_error;
             #line 757 "Python/generated_cases.c.h"
             STACK_SHRINK(1);
@@ -766,7 +766,7 @@
             PyObject *container = stack_pointer[-2];
             PyObject *v = stack_pointer[-3];
             uint16_t counter = read_u16(&next_instr[0].cache);
-            #line 540 "Python/bytecodes.c"
+            #line 541 "Python/bytecodes.c"
             #if ENABLE_SPECIALIZATION
             if (ADAPTIVE_COUNTER_IS_ZERO(counter)) {
                 next_instr--;
@@ -785,7 +785,7 @@
             Py_DECREF(v);
             Py_DECREF(container);
             Py_DECREF(sub);
-            #line 555 "Python/bytecodes.c"
+            #line 556 "Python/bytecodes.c"
             if (err) goto pop_3_error;
             #line 791 "Python/generated_cases.c.h"
             STACK_SHRINK(3);
@@ -797,7 +797,7 @@
             PyObject *sub = stack_pointer[-1];
             PyObject *list = stack_pointer[-2];
             PyObject *value = stack_pointer[-3];
-            #line 559 "Python/bytecodes.c"
+            #line 560 "Python/bytecodes.c"
             DEOPT_IF(!PyLong_CheckExact(sub), STORE_SUBSCR);
             DEOPT_IF(!PyList_CheckExact(list), STORE_SUBSCR);
 
@@ -824,7 +824,7 @@
             PyObject *sub = stack_pointer[-1];
             PyObject *dict = stack_pointer[-2];
             PyObject *value = stack_pointer[-3];
-            #line 578 "Python/bytecodes.c"
+            #line 579 "Python/bytecodes.c"
             DEOPT_IF(!PyDict_CheckExact(dict), STORE_SUBSCR);
             STAT_INC(STORE_SUBSCR, hit);
             int err = _PyDict_SetItem_Take2((PyDictObject *)dict, sub, value);
@@ -839,13 +839,13 @@
         TARGET(DELETE_SUBSCR) {
             PyObject *sub = stack_pointer[-1];
             PyObject *container = stack_pointer[-2];
-            #line 586 "Python/bytecodes.c"
+            #line 587 "Python/bytecodes.c"
             /* del container[sub] */
             int err = PyObject_DelItem(container, sub);
             #line 846 "Python/generated_cases.c.h"
             Py_DECREF(container);
             Py_DECREF(sub);
-            #line 589 "Python/bytecodes.c"
+            #line 590 "Python/bytecodes.c"
             if (err) goto pop_2_error;
             #line 851 "Python/generated_cases.c.h"
             STACK_SHRINK(2);
@@ -855,12 +855,12 @@
         TARGET(CALL_INTRINSIC_1) {
             PyObject *value = stack_pointer[-1];
             PyObject *res;
-            #line 593 "Python/bytecodes.c"
+            #line 594 "Python/bytecodes.c"
             assert(oparg <= MAX_INTRINSIC_1);
             res = _PyIntrinsics_UnaryFunctions[oparg](tstate, value);
             #line 862 "Python/generated_cases.c.h"
             Py_DECREF(value);
-            #line 596 "Python/bytecodes.c"
+            #line 597 "Python/bytecodes.c"
             if (res == NULL) goto pop_1_error;
             #line 866 "Python/generated_cases.c.h"
             stack_pointer[-1] = res;
@@ -871,13 +871,13 @@
             PyObject *value1 = stack_pointer[-1];
             PyObject *value2 = stack_pointer[-2];
             PyObject *res;
-            #line 600 "Python/bytecodes.c"
+            #line 601 "Python/bytecodes.c"
             assert(oparg <= MAX_INTRINSIC_2);
             res = _PyIntrinsics_BinaryFunctions[oparg](tstate, value2, value1);
             #line 878 "Python/generated_cases.c.h"
             Py_DECREF(value2);
             Py_DECREF(value1);
-            #line 603 "Python/bytecodes.c"
+            #line 604 "Python/bytecodes.c"
             if (res == NULL) goto pop_2_error;
             #line 883 "Python/generated_cases.c.h"
             STACK_SHRINK(1);
@@ -887,7 +887,7 @@
 
         TARGET(RAISE_VARARGS) {
             PyObject **args = (stack_pointer - oparg);
-            #line 607 "Python/bytecodes.c"
+            #line 608 "Python/bytecodes.c"
             PyObject *cause = NULL, *exc = NULL;
             switch (oparg) {
             case 2:
@@ -910,7 +910,7 @@
 
         TARGET(INTERPRETER_EXIT) {
             PyObject *retval = stack_pointer[-1];
-            #line 627 "Python/bytecodes.c"
+            #line 628 "Python/bytecodes.c"
             assert(frame == &entry_frame);
             assert(_PyFrame_IsIncomplete(frame));
             STACK_SHRINK(1);  // Since we're not going to DISPATCH()
@@ -926,7 +926,7 @@
 
         TARGET(RETURN_VALUE) {
             PyObject *retval = stack_pointer[-1];
-            #line 640 "Python/bytecodes.c"
+            #line 641 "Python/bytecodes.c"
             STACK_SHRINK(1);
             assert(EMPTY());
             _PyFrame_SetStackPointer(frame, stack_pointer);
@@ -944,7 +944,7 @@
 
         TARGET(INSTRUMENTED_RETURN_VALUE) {
             PyObject *retval = stack_pointer[-1];
-            #line 655 "Python/bytecodes.c"
+            #line 656 "Python/bytecodes.c"
             int err = _Py_call_instrumentation_arg(
                     tstate, PY_MONITORING_EVENT_PY_RETURN,
                     frame, next_instr-1, retval);
@@ -965,7 +965,7 @@
         }
 
         TARGET(RETURN_CONST) {
-            #line 674 "Python/bytecodes.c"
+            #line 675 "Python/bytecodes.c"
             PyObject *retval = GETITEM(frame->f_code->co_consts, oparg);
             Py_INCREF(retval);
             assert(EMPTY());
@@ -983,7 +983,7 @@
         }
 
         TARGET(INSTRUMENTED_RETURN_CONST) {
-            #line 690 "Python/bytecodes.c"
+            #line 691 "Python/bytecodes.c"
             PyObject *retval = GETITEM(frame->f_code->co_consts, oparg);
             int err = _Py_call_instrumentation_arg(
                     tstate, PY_MONITORING_EVENT_PY_RETURN,
@@ -1007,7 +1007,7 @@
         TARGET(GET_AITER) {
             PyObject *obj = stack_pointer[-1];
             PyObject *iter;
-            #line 710 "Python/bytecodes.c"
+            #line 711 "Python/bytecodes.c"
             unaryfunc getter = NULL;
             PyTypeObject *type = Py_TYPE(obj);
 
@@ -1022,14 +1022,14 @@
                               type->tp_name);
             #line 1024 "Python/generated_cases.c.h"
                 Py_DECREF(obj);
-            #line 723 "Python/bytecodes.c"
+            #line 724 "Python/bytecodes.c"
                 if (true) goto pop_1_error;
             }
 
             iter = (*getter)(obj);
             #line 1031 "Python/generated_cases.c.h"
             Py_DECREF(obj);
-            #line 728 "Python/bytecodes.c"
+            #line 729 "Python/bytecodes.c"
             if (iter == NULL) goto pop_1_error;
 
             if (Py_TYPE(iter)->tp_as_async == NULL ||
@@ -1050,7 +1050,7 @@
         TARGET(GET_ANEXT) {
             PyObject *aiter = stack_pointer[-1];
             PyObject *awaitable;
-            #line 743 "Python/bytecodes.c"
+            #line 744 "Python/bytecodes.c"
             unaryfunc getter = NULL;
             PyObject *next_iter = NULL;
             PyTypeObject *type = Py_TYPE(aiter);
@@ -1105,7 +1105,7 @@
             PREDICTED(GET_AWAITABLE);
             PyObject *iterable = stack_pointer[-1];
             PyObject *iter;
-            #line 790 "Python/bytecodes.c"
+            #line 791 "Python/bytecodes.c"
             iter = _PyCoro_GetAwaitableIter(iterable);
 
             if (iter == NULL) {
@@ -1114,7 +1114,7 @@
 
             #line 1116 "Python/generated_cases.c.h"
             Py_DECREF(iterable);
-            #line 797 "Python/bytecodes.c"
+            #line 798 "Python/bytecodes.c"
 
             if (iter != NULL && PyCoro_CheckExact(iter)) {
                 PyObject *yf = _PyGen_yf((PyGenObject*)iter);
@@ -1144,7 +1144,7 @@
             PyObject *v = stack_pointer[-1];
             PyObject *receiver = stack_pointer[-2];
             PyObject *retval;
-            #line 823 "Python/bytecodes.c"
+            #line 824 "Python/bytecodes.c"
             #if ENABLE_SPECIALIZATION
             _PySendCache *cache = (_PySendCache *)next_instr;
             if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
@@ -1200,7 +1200,7 @@
         TARGET(SEND_GEN) {
             PyObject *v = stack_pointer[-1];
             PyObject *receiver = stack_pointer[-2];
-            #line 872 "Python/bytecodes.c"
+            #line 873 "Python/bytecodes.c"
             DEOPT_IF(tstate->interp->eval_frame, SEND);
             PyGenObject *gen = (PyGenObject *)receiver;
             DEOPT_IF(Py_TYPE(gen) != &PyGen_Type &&
@@ -1221,7 +1221,7 @@
 
         TARGET(INSTRUMENTED_YIELD_VALUE) {
             PyObject *retval = stack_pointer[-1];
-            #line 890 "Python/bytecodes.c"
+            #line 891 "Python/bytecodes.c"
             assert(frame != &entry_frame);
             PyGenObject *gen = _PyFrame_GetGenerator(frame);
             gen->gi_frame_state = FRAME_SUSPENDED;
@@ -1243,7 +1243,7 @@
 
         TARGET(YIELD_VALUE) {
             PyObject *retval = stack_pointer[-1];
-            #line 909 "Python/bytecodes.c"
+            #line 910 "Python/bytecodes.c"
             // NOTE: It's important that YIELD_VALUE never raises an exception!
             // The compiler treats any exception raised here as a failed close()
             // or throw() call.
@@ -1264,7 +1264,7 @@
 
         TARGET(POP_EXCEPT) {
             PyObject *exc_value = stack_pointer[-1];
-            #line 927 "Python/bytecodes.c"
+            #line 928 "Python/bytecodes.c"
             _PyErr_StackItem *exc_info = tstate->exc_info;
             Py_XSETREF(exc_info->exc_value, exc_value);
             #line 1271 "Python/generated_cases.c.h"
@@ -1275,7 +1275,7 @@
         TARGET(RERAISE) {
             PyObject *exc = stack_pointer[-1];
             PyObject **values = (stack_pointer - (1 + oparg));
-            #line 932 "Python/bytecodes.c"
+            #line 933 "Python/bytecodes.c"
             assert(oparg >= 0 && oparg <= 2);
             if (oparg) {
                 PyObject *lasti = values[0];
@@ -1299,13 +1299,13 @@
         TARGET(END_ASYNC_FOR) {
             PyObject *exc = stack_pointer[-1];
             PyObject *awaitable = stack_pointer[-2];
-            #line 952 "Python/bytecodes.c"
+            #line 953 "Python/bytecodes.c"
             assert(exc && PyExceptionInstance_Check(exc));
             if (PyErr_GivenExceptionMatches(exc, PyExc_StopAsyncIteration)) {
             #line 1306 "Python/generated_cases.c.h"
                 Py_DECREF(awaitable);
                 Py_DECREF(exc);
-            #line 955 "Python/bytecodes.c"
+            #line 956 "Python/bytecodes.c"
             }
             else {
                 Py_INCREF(exc);
@@ -1323,7 +1323,7 @@
             PyObject *sub_iter = stack_pointer[-3];
             PyObject *none;
             PyObject *value;
-            #line 964 "Python/bytecodes.c"
+            #line 965 "Python/bytecodes.c"
             assert(throwflag);
             assert(exc_value && PyExceptionInstance_Check(exc_value));
             if (PyErr_GivenExceptionMatches(exc_value, PyExc_StopIteration)) {
@@ -1332,7 +1332,7 @@
                 Py_DECREF(sub_iter);
                 Py_DECREF(last_sent_val);
                 Py_DECREF(exc_value);
-            #line 969 "Python/bytecodes.c"
+            #line 970 "Python/bytecodes.c"
                 none = Py_NewRef(Py_None);
             }
             else {
@@ -1348,7 +1348,7 @@
 
         TARGET(LOAD_ASSERTION_ERROR) {
             PyObject *value;
-            #line 978 "Python/bytecodes.c"
+            #line 979 "Python/bytecodes.c"
             value = Py_NewRef(PyExc_AssertionError);
             #line 1354 "Python/generated_cases.c.h"
             STACK_GROW(1);
@@ -1358,7 +1358,7 @@
 
         TARGET(LOAD_BUILD_CLASS) {
             PyObject *bc;
-            #line 982 "Python/bytecodes.c"
+            #line 983 "Python/bytecodes.c"
             if (PyDict_CheckExact(BUILTINS())) {
                 bc = _PyDict_GetItemWithError(BUILTINS(),
                                               &_Py_ID(__build_class__));
@@ -1388,7 +1388,7 @@
 
         TARGET(STORE_NAME) {
             PyObject *v = stack_pointer[-1];
-            #line 1006 "Python/bytecodes.c"
+            #line 1008 "Python/bytecodes.c"
             PyObject *name = GETITEM(frame->f_code->co_names, oparg);
             PyObject *ns = LOCALS();
             int err;
@@ -1397,7 +1397,7 @@
                               "no locals found when storing %R", name);
             #line 1399 "Python/generated_cases.c.h"
                 Py_DECREF(v);
-            #line 1013 "Python/bytecodes.c"
+            #line 1015 "Python/bytecodes.c"
                 if (true) goto pop_1_error;
             }
             if (PyDict_CheckExact(ns))
@@ -1406,7 +1406,7 @@
                 err = PyObject_SetItem(ns, name, v);
             #line 1408 "Python/generated_cases.c.h"
             Py_DECREF(v);
-            #line 1020 "Python/bytecodes.c"
+            #line 1022 "Python/bytecodes.c"
             if (err) goto pop_1_error;
             #line 1412 "Python/generated_cases.c.h"
             STACK_SHRINK(1);
@@ -1414,7 +1414,7 @@
         }
 
         TARGET(DELETE_NAME) {
-            #line 1024 "Python/bytecodes.c"
+            #line 1026 "Python/bytecodes.c"
             PyObject *name = GETITEM(frame->f_code->co_names, oparg);
             PyObject *ns = LOCALS();
             int err;
@@ -1439,7 +1439,7 @@
             PREDICTED(UNPACK_SEQUENCE);
             static_assert(INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE == 1, "incorrect cache size");
             PyObject *seq = stack_pointer[-1];
-            #line 1050 "Python/bytecodes.c"
+            #line 1052 "Python/bytecodes.c"
             #if ENABLE_SPECIALIZATION
             _PyUnpackSequenceCache *cache = (_PyUnpackSequenceCache *)next_instr;
             if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
@@ -1454,7 +1454,7 @@
             int res = unpack_iterable(tstate, seq, oparg, -1, top);
             #line 1456 "Python/generated_cases.c.h"
             Py_DECREF(seq);
-            #line 1063 "Python/bytecodes.c"
+            #line 1065 "Python/bytecodes.c"
             if (res == 0) goto pop_1_error;
             #line 1460 "Python/generated_cases.c.h"
             STACK_SHRINK(1);
@@ -1466,7 +1466,7 @@
         TARGET(UNPACK_SEQUENCE_TWO_TUPLE) {
             PyObject *seq = stack_pointer[-1];
             PyObject **values = stack_pointer - (1);
-            #line 1067 "Python/bytecodes.c"
+            #line 1069 "Python/bytecodes.c"
             DEOPT_IF(!PyTuple_CheckExact(seq), UNPACK_SEQUENCE);
             DEOPT_IF(PyTuple_GET_SIZE(seq) != 2, UNPACK_SEQUENCE);
             assert(oparg == 2);
@@ -1484,7 +1484,7 @@
         TARGET(UNPACK_SEQUENCE_TUPLE) {
             PyObject *seq = stack_pointer[-1];
             PyObject **values = stack_pointer - (1);
-            #line 1077 "Python/bytecodes.c"
+            #line 1079 "Python/bytecodes.c"
             DEOPT_IF(!PyTuple_CheckExact(seq), UNPACK_SEQUENCE);
             DEOPT_IF(PyTuple_GET_SIZE(seq) != oparg, UNPACK_SEQUENCE);
             STAT_INC(UNPACK_SEQUENCE, hit);
@@ -1503,7 +1503,7 @@
         TARGET(UNPACK_SEQUENCE_LIST) {
             PyObject *seq = stack_pointer[-1];
             PyObject **values = stack_pointer - (1);
-            #line 1088 "Python/bytecodes.c"
+            #line 1090 "Python/bytecodes.c"
             DEOPT_IF(!PyList_CheckExact(seq), UNPACK_SEQUENCE);
             DEOPT_IF(PyList_GET_SIZE(seq) != oparg, UNPACK_SEQUENCE);
             STAT_INC(UNPACK_SEQUENCE, hit);
@@ -1521,13 +1521,13 @@
 
         TARGET(UNPACK_EX) {
             PyObject *seq = stack_pointer[-1];
-            #line 1099 "Python/bytecodes.c"
+            #line 1101 "Python/bytecodes.c"
             int totalargs = 1 + (oparg & 0xFF) + (oparg >> 8);
             PyObject **top = stack_pointer + totalargs - 1;
             int res = unpack_iterable(tstate, seq, oparg & 0xFF, oparg >> 8, top);
             #line 1529 "Python/generated_cases.c.h"
             Py_DECREF(seq);
-            #line 1103 "Python/bytecodes.c"
+            #line 1105 "Python/bytecodes.c"
             if (res == 0) goto pop_1_error;
             #line 1533 "Python/generated_cases.c.h"
             STACK_GROW((oparg & 0xFF) + (oparg >> 8));
@@ -1540,7 +1540,7 @@
             PyObject *owner = stack_pointer[-1];
             PyObject *v = stack_pointer[-2];
             uint16_t counter = read_u16(&next_instr[0].cache);
-            #line 1114 "Python/bytecodes.c"
+            #line 1116 "Python/bytecodes.c"
             #if ENABLE_SPECIALIZATION
             if (ADAPTIVE_COUNTER_IS_ZERO(counter)) {
                 PyObject *name = GETITEM(frame->f_code->co_names, oparg);
@@ -1559,7 +1559,7 @@
             #line 1560 "Python/generated_cases.c.h"
             Py_DECREF(v);
             Py_DECREF(owner);
-            #line 1130 "Python/bytecodes.c"
+            #line 1132 "Python/bytecodes.c"
             if (err) goto pop_2_error;
             #line 1565 "Python/generated_cases.c.h"
             STACK_SHRINK(2);
@@ -1569,12 +1569,12 @@
 
         TARGET(DELETE_ATTR) {
             PyObject *owner = stack_pointer[-1];
-            #line 1134 "Python/bytecodes.c"
+            #line 1136 "Python/bytecodes.c"
             PyObject *name = GETITEM(frame->f_code->co_names, oparg);
             int err = PyObject_SetAttr(owner, name, (PyObject *)NULL);
             #line 1576 "Python/generated_cases.c.h"
             Py_DECREF(owner);
-            #line 1137 "Python/bytecodes.c"
+            #line 1139 "Python/bytecodes.c"
             if (err) goto pop_1_error;
             #line 1580 "Python/generated_cases.c.h"
             STACK_SHRINK(1);
@@ -1583,12 +1583,12 @@
 
         TARGET(STORE_GLOBAL) {
             PyObject *v = stack_pointer[-1];
-            #line 1141 "Python/bytecodes.c"
+            #line 1143 "Python/bytecodes.c"
             PyObject *name = GETITEM(frame->f_code->co_names, oparg);
             int err = PyDict_SetItem(GLOBALS(), name, v);
             #line 1590 "Python/generated_cases.c.h"
             Py_DECREF(v);
-            #line 1144 "Python/bytecodes.c"
+            #line 1146 "Python/bytecodes.c"
             if (err) goto pop_1_error;
             #line 1594 "Python/generated_cases.c.h"
             STACK_SHRINK(1);
@@ -1596,7 +1596,7 @@
         }
 
         TARGET(DELETE_GLOBAL) {
-            #line 1148 "Python/bytecodes.c"
+            #line 1150 "Python/bytecodes.c"
             PyObject *name = GETITEM(frame->f_code->co_names, oparg);
             int err;
             err = PyDict_DelItem(GLOBALS(), name);
@@ -1612,70 +1612,175 @@
             DISPATCH();
         }
 
+        TARGET(LOAD_LOCALS) {
+            PyObject *_tmp_1;
+            {
+                PyObject *locals;
+                #line 1164 "Python/bytecodes.c"
+                locals = LOCALS();
+                if (locals == NULL) {
+                    _PyErr_SetString(tstate, PyExc_SystemError,
+                                     "no locals found");
+                    if (true) goto error;
+                }
+                Py_INCREF(locals);
+                #line 1628 "Python/generated_cases.c.h"
+                _tmp_1 = locals;
+            }
+            STACK_GROW(1);
+            stack_pointer[-1] = _tmp_1;
+            DISPATCH();
+        }
+
         TARGET(LOAD_NAME) {
-            PyObject *v;
-            #line 1162 "Python/bytecodes.c"
-            PyObject *name = GETITEM(frame->f_code->co_names, oparg);
-            PyObject *locals = LOCALS();
-            if (locals == NULL) {
-                _PyErr_Format(tstate, PyExc_SystemError,
-                              "no locals when loading %R", name);
-                goto error;
+            PyObject *_tmp_1;
+            {
+                PyObject *locals;
+                #line 1164 "Python/bytecodes.c"
+                locals = LOCALS();
+                if (locals == NULL) {
+                    _PyErr_SetString(tstate, PyExc_SystemError,
+                                     "no locals found");
+                    if (true) goto error;
+                }
+                Py_INCREF(locals);
+                #line 1648 "Python/generated_cases.c.h"
+                _tmp_1 = locals;
             }
-            if (PyDict_CheckExact(locals)) {
-                v = PyDict_GetItemWithError(locals, name);
-                if (v != NULL) {
-                    Py_INCREF(v);
+            {
+                PyObject *mod_or_class_dict = _tmp_1;
+                PyObject *v;
+                #line 1176 "Python/bytecodes.c"
+                PyObject *name = GETITEM(frame->f_code->co_names, oparg);
+                if (PyDict_CheckExact(mod_or_class_dict)) {
+                    v = PyDict_GetItemWithError(mod_or_class_dict, name);
+                    if (v != NULL) {
+                        Py_INCREF(v);
+                    }
+                    else if (_PyErr_Occurred(tstate)) {
+                        Py_DECREF(mod_or_class_dict);
+                        goto error;
+                    }
                 }
-                else if (_PyErr_Occurred(tstate)) {
-                    goto error;
+                else {
+                    v = PyObject_GetItem(mod_or_class_dict, name);
+                    if (v == NULL) {
+                        if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) {
+                            Py_DECREF(mod_or_class_dict);
+                            goto error;
+                        }
+                        _PyErr_Clear(tstate);
+                    }
                 }
-            }
-            else {
-                v = PyObject_GetItem(locals, name);
+                Py_DECREF(mod_or_class_dict);
                 if (v == NULL) {
-                    if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError))
+                    v = PyDict_GetItemWithError(GLOBALS(), name);
+                    if (v != NULL) {
+                        Py_INCREF(v);
+                    }
+                    else if (_PyErr_Occurred(tstate)) {
                         goto error;
-                    _PyErr_Clear(tstate);
+                    }
+                    else {
+                        if (PyDict_CheckExact(BUILTINS())) {
+                            v = PyDict_GetItemWithError(BUILTINS(), name);
+                            if (v == NULL) {
+                                if (!_PyErr_Occurred(tstate)) {
+                                    format_exc_check_arg(
+                                            tstate, PyExc_NameError,
+                                            NAME_ERROR_MSG, name);
+                                }
+                                goto error;
+                            }
+                            Py_INCREF(v);
+                        }
+                        else {
+                            v = PyObject_GetItem(BUILTINS(), name);
+                            if (v == NULL) {
+                                if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) {
+                                    format_exc_check_arg(
+                                                tstate, PyExc_NameError,
+                                                NAME_ERROR_MSG, name);
+                                }
+                                goto error;
+                            }
+                        }
+                    }
                 }
+                #line 1711 "Python/generated_cases.c.h"
+                _tmp_1 = v;
             }
-            if (v == NULL) {
-                v = PyDict_GetItemWithError(GLOBALS(), name);
-                if (v != NULL) {
-                    Py_INCREF(v);
-                }
-                else if (_PyErr_Occurred(tstate)) {
-                    goto error;
+            STACK_GROW(1);
+            stack_pointer[-1] = _tmp_1;
+            DISPATCH();
+        }
+
+        TARGET(LOAD_FROM_DICT_OR_GLOBALS) {
+            PyObject *_tmp_1 = stack_pointer[-1];
+            {
+                PyObject *mod_or_class_dict = _tmp_1;
+                PyObject *v;
+                #line 1176 "Python/bytecodes.c"
+                PyObject *name = GETITEM(frame->f_code->co_names, oparg);
+                if (PyDict_CheckExact(mod_or_class_dict)) {
+                    v = PyDict_GetItemWithError(mod_or_class_dict, name);
+                    if (v != NULL) {
+                        Py_INCREF(v);
+                    }
+                    else if (_PyErr_Occurred(tstate)) {
+                        Py_DECREF(mod_or_class_dict);
+                        goto error;
+                    }
                 }
                 else {
-                    if (PyDict_CheckExact(BUILTINS())) {
-                        v = PyDict_GetItemWithError(BUILTINS(), name);
-                        if (v == NULL) {
-                            if (!_PyErr_Occurred(tstate)) {
-                                format_exc_check_arg(
-                                        tstate, PyExc_NameError,
-                                        NAME_ERROR_MSG, name);
-                            }
+                    v = PyObject_GetItem(mod_or_class_dict, name);
+                    if (v == NULL) {
+                        if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) {
+                            Py_DECREF(mod_or_class_dict);
                             goto error;
                         }
+                        _PyErr_Clear(tstate);
+                    }
+                }
+                Py_DECREF(mod_or_class_dict);
+                if (v == NULL) {
+                    v = PyDict_GetItemWithError(GLOBALS(), name);
+                    if (v != NULL) {
                         Py_INCREF(v);
                     }
+                    else if (_PyErr_Occurred(tstate)) {
+                        goto error;
+                    }
                     else {
-                        v = PyObject_GetItem(BUILTINS(), name);
-                        if (v == NULL) {
-                            if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) {
-                                format_exc_check_arg(
+                        if (PyDict_CheckExact(BUILTINS())) {
+                            v = PyDict_GetItemWithError(BUILTINS(), name);
+                            if (v == NULL) {
+                                if (!_PyErr_Occurred(tstate)) {
+                                    format_exc_check_arg(
                                             tstate, PyExc_NameError,
                                             NAME_ERROR_MSG, name);
+                                }
+                                goto error;
+                            }
+                            Py_INCREF(v);
+                        }
+                        else {
+                            v = PyObject_GetItem(BUILTINS(), name);
+                            if (v == NULL) {
+                                if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) {
+                                    format_exc_check_arg(
+                                                tstate, PyExc_NameError,
+                                                NAME_ERROR_MSG, name);
+                                }
+                                goto error;
                             }
-                            goto error;
                         }
                     }
                 }
+                #line 1781 "Python/generated_cases.c.h"
+                _tmp_1 = v;
             }
-            #line 1677 "Python/generated_cases.c.h"
-            STACK_GROW(1);
-            stack_pointer[-1] = v;
+            stack_pointer[-1] = _tmp_1;
             DISPATCH();
         }
 
@@ -1684,7 +1789,7 @@
             static_assert(INLINE_CACHE_ENTRIES_LOAD_GLOBAL == 4, "incorrect cache size");
             PyObject *null = NULL;
             PyObject *v;
-            #line 1229 "Python/bytecodes.c"
+            #line 1245 "Python/bytecodes.c"
             #if ENABLE_SPECIALIZATION
             _PyLoadGlobalCache *cache = (_PyLoadGlobalCache *)next_instr;
             if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
@@ -1736,7 +1841,7 @@
                 }
             }
             null = NULL;
-            #line 1740 "Python/generated_cases.c.h"
+            #line 1845 "Python/generated_cases.c.h"
             STACK_GROW(1);
             STACK_GROW(((oparg & 1) ? 1 : 0));
             stack_pointer[-1] = v;
@@ -1750,7 +1855,7 @@
             PyObject *res;
             uint16_t index = read_u16(&next_instr[1].cache);
             uint16_t version = read_u16(&next_instr[2].cache);
-            #line 1283 "Python/bytecodes.c"
+            #line 1299 "Python/bytecodes.c"
             DEOPT_IF(!PyDict_CheckExact(GLOBALS()), LOAD_GLOBAL);
             PyDictObject *dict = (PyDictObject *)GLOBALS();
             DEOPT_IF(dict->ma_keys->dk_version != version, LOAD_GLOBAL);
@@ -1761,7 +1866,7 @@
             Py_INCREF(res);
             STAT_INC(LOAD_GLOBAL, hit);
             null = NULL;
-            #line 1765 "Python/generated_cases.c.h"
+            #line 1870 "Python/generated_cases.c.h"
             STACK_GROW(1);
             STACK_GROW(((oparg & 1) ? 1 : 0));
             stack_pointer[-1] = res;
@@ -1776,7 +1881,7 @@
             uint16_t index = read_u16(&next_instr[1].cache);
             uint16_t mod_version = read_u16(&next_instr[2].cache);
             uint16_t bltn_version = read_u16(&next_instr[3].cache);
-            #line 1296 "Python/bytecodes.c"
+            #line 1312 "Python/bytecodes.c"
             DEOPT_IF(!PyDict_CheckExact(GLOBALS()), LOAD_GLOBAL);
             DEOPT_IF(!PyDict_CheckExact(BUILTINS()), LOAD_GLOBAL);
             PyDictObject *mdict = (PyDictObject *)GLOBALS();
@@ -1791,7 +1896,7 @@
             Py_INCREF(res);
             STAT_INC(LOAD_GLOBAL, hit);
             null = NULL;
-            #line 1795 "Python/generated_cases.c.h"
+            #line 1900 "Python/generated_cases.c.h"
             STACK_GROW(1);
             STACK_GROW(((oparg & 1) ? 1 : 0));
             stack_pointer[-1] = res;
@@ -1801,16 +1906,16 @@
         }
 
         TARGET(DELETE_FAST) {
-            #line 1313 "Python/bytecodes.c"
+            #line 1329 "Python/bytecodes.c"
             PyObject *v = GETLOCAL(oparg);
             if (v == NULL) goto unbound_local_error;
             SETLOCAL(oparg, NULL);
-            #line 1809 "Python/generated_cases.c.h"
+            #line 1914 "Python/generated_cases.c.h"
             DISPATCH();
         }
 
         TARGET(MAKE_CELL) {
-            #line 1319 "Python/bytecodes.c"
+            #line 1335 "Python/bytecodes.c"
             // "initial" is probably NULL but not if it's an arg (or set
             // via PyFrame_LocalsToFast() before MAKE_CELL has run).
             PyObject *initial = GETLOCAL(oparg);
@@ -1819,12 +1924,12 @@
                 goto resume_with_error;
             }
             SETLOCAL(oparg, cell);
-            #line 1823 "Python/generated_cases.c.h"
+            #line 1928 "Python/generated_cases.c.h"
             DISPATCH();
         }
 
         TARGET(DELETE_DEREF) {
-            #line 1330 "Python/bytecodes.c"
+            #line 1346 "Python/bytecodes.c"
             PyObject *cell = GETLOCAL(oparg);
             PyObject *oldobj = PyCell_GET(cell);
             // Can't use ERROR_IF here.
@@ -1835,35 +1940,39 @@
             }
             PyCell_SET(cell, NULL);
             Py_DECREF(oldobj);
-            #line 1839 "Python/generated_cases.c.h"
+            #line 1944 "Python/generated_cases.c.h"
             DISPATCH();
         }
 
-        TARGET(LOAD_CLASSDEREF) {
+        TARGET(LOAD_FROM_DICT_OR_DEREF) {
+            PyObject *class_dict = stack_pointer[-1];
             PyObject *value;
-            #line 1343 "Python/bytecodes.c"
-            PyObject *name, *locals = LOCALS();
-            assert(locals);
+            #line 1359 "Python/bytecodes.c"
+            PyObject *name;
+            assert(class_dict);
             assert(oparg >= 0 && oparg < frame->f_code->co_nlocalsplus);
             name = PyTuple_GET_ITEM(frame->f_code->co_localsplusnames, oparg);
-            if (PyDict_CheckExact(locals)) {
-                value = PyDict_GetItemWithError(locals, name);
+            if (PyDict_CheckExact(class_dict)) {
+                value = PyDict_GetItemWithError(class_dict, name);
                 if (value != NULL) {
                     Py_INCREF(value);
                 }
                 else if (_PyErr_Occurred(tstate)) {
+                    Py_DECREF(class_dict);
                     goto error;
                 }
             }
             else {
-                value = PyObject_GetItem(locals, name);
+                value = PyObject_GetItem(class_dict, name);
                 if (value == NULL) {
                     if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) {
+                        Py_DECREF(class_dict);
                         goto error;
                     }
                     _PyErr_Clear(tstate);
                 }
             }
+            Py_DECREF(class_dict);
             if (!value) {
                 PyObject *cell = GETLOCAL(oparg);
                 value = PyCell_GET(cell);
@@ -1873,15 +1982,14 @@
                 }
                 Py_INCREF(value);
             }
-            #line 1877 "Python/generated_cases.c.h"
-            STACK_GROW(1);
+            #line 1986 "Python/generated_cases.c.h"
             stack_pointer[-1] = value;
             DISPATCH();
         }
 
         TARGET(LOAD_DEREF) {
             PyObject *value;
-            #line 1377 "Python/bytecodes.c"
+            #line 1396 "Python/bytecodes.c"
             PyObject *cell = GETLOCAL(oparg);
             value = PyCell_GET(cell);
             if (value == NULL) {
@@ -1889,7 +1997,7 @@
                 if (true) goto error;
             }
             Py_INCREF(value);
-            #line 1893 "Python/generated_cases.c.h"
+            #line 2001 "Python/generated_cases.c.h"
             STACK_GROW(1);
             stack_pointer[-1] = value;
             DISPATCH();
@@ -1897,18 +2005,18 @@
 
         TARGET(STORE_DEREF) {
             PyObject *v = stack_pointer[-1];
-            #line 1387 "Python/bytecodes.c"
+            #line 1406 "Python/bytecodes.c"
             PyObject *cell = GETLOCAL(oparg);
             PyObject *oldobj = PyCell_GET(cell);
             PyCell_SET(cell, v);
             Py_XDECREF(oldobj);
-            #line 1906 "Python/generated_cases.c.h"
+            #line 2014 "Python/generated_cases.c.h"
             STACK_SHRINK(1);
             DISPATCH();
         }
 
         TARGET(COPY_FREE_VARS) {
-            #line 1394 "Python/bytecodes.c"
+            #line 1413 "Python/bytecodes.c"
             /* Copy closure variables to free variables */
             PyCodeObject *co = frame->f_code;
             assert(PyFunction_Check(frame->f_funcobj));
@@ -1919,22 +2027,22 @@
                 PyObject *o = PyTuple_GET_ITEM(closure, i);
                 frame->localsplus[offset + i] = Py_NewRef(o);
             }
-            #line 1923 "Python/generated_cases.c.h"
+            #line 2031 "Python/generated_cases.c.h"
             DISPATCH();
         }
 
         TARGET(BUILD_STRING) {
             PyObject **pieces = (stack_pointer - oparg);
             PyObject *str;
-            #line 1407 "Python/bytecodes.c"
+            #line 1426 "Python/bytecodes.c"
             str = _PyUnicode_JoinArray(&_Py_STR(empty), pieces, oparg);
-            #line 1932 "Python/generated_cases.c.h"
+            #line 2040 "Python/generated_cases.c.h"
             for (int _i = oparg; --_i >= 0;) {
                 Py_DECREF(pieces[_i]);
             }
-            #line 1409 "Python/bytecodes.c"
+            #line 1428 "Python/bytecodes.c"
             if (str == NULL) { STACK_SHRINK(oparg); goto error; }
-            #line 1938 "Python/generated_cases.c.h"
+            #line 2046 "Python/generated_cases.c.h"
             STACK_SHRINK(oparg);
             STACK_GROW(1);
             stack_pointer[-1] = str;
@@ -1944,10 +2052,10 @@
         TARGET(BUILD_TUPLE) {
             PyObject **values = (stack_pointer - oparg);
             PyObject *tup;
-            #line 1413 "Python/bytecodes.c"
+            #line 1432 "Python/bytecodes.c"
             tup = _PyTuple_FromArraySteal(values, oparg);
             if (tup == NULL) { STACK_SHRINK(oparg); goto error; }
-            #line 1951 "Python/generated_cases.c.h"
+            #line 2059 "Python/generated_cases.c.h"
             STACK_SHRINK(oparg);
             STACK_GROW(1);
             stack_pointer[-1] = tup;
@@ -1957,10 +2065,10 @@
         TARGET(BUILD_LIST) {
             PyObject **values = (stack_pointer - oparg);
             PyObject *list;
-            #line 1418 "Python/bytecodes.c"
+            #line 1437 "Python/bytecodes.c"
             list = _PyList_FromArraySteal(values, oparg);
             if (list == NULL) { STACK_SHRINK(oparg); goto error; }
-            #line 1964 "Python/generated_cases.c.h"
+            #line 2072 "Python/generated_cases.c.h"
             STACK_SHRINK(oparg);
             STACK_GROW(1);
             stack_pointer[-1] = list;
@@ -1970,7 +2078,7 @@
         TARGET(LIST_EXTEND) {
             PyObject *iterable = stack_pointer[-1];
             PyObject *list = stack_pointer[-(2 + (oparg-1))];
-            #line 1423 "Python/bytecodes.c"
+            #line 1442 "Python/bytecodes.c"
             PyObject *none_val = _PyList_Extend((PyListObject *)list, iterable);
             if (none_val == NULL) {
                 if (_PyErr_ExceptionMatches(tstate, PyExc_TypeError) &&
@@ -1981,13 +2089,13 @@
                           "Value after * must be an iterable, not %.200s",
                           Py_TYPE(iterable)->tp_name);
                 }
-            #line 1985 "Python/generated_cases.c.h"
+            #line 2093 "Python/generated_cases.c.h"
                 Py_DECREF(iterable);
-            #line 1434 "Python/bytecodes.c"
+            #line 1453 "Python/bytecodes.c"
                 if (true) goto pop_1_error;
             }
             Py_DECREF(none_val);
-            #line 1991 "Python/generated_cases.c.h"
+            #line 2099 "Python/generated_cases.c.h"
             Py_DECREF(iterable);
             STACK_SHRINK(1);
             DISPATCH();
@@ -1996,13 +2104,13 @@
         TARGET(SET_UPDATE) {
             PyObject *iterable = stack_pointer[-1];
             PyObject *set = stack_pointer[-(2 + (oparg-1))];
-            #line 1441 "Python/bytecodes.c"
+            #line 1460 "Python/bytecodes.c"
             int err = _PySet_Update(set, iterable);
-            #line 2002 "Python/generated_cases.c.h"
+            #line 2110 "Python/generated_cases.c.h"
             Py_DECREF(iterable);
-            #line 1443 "Python/bytecodes.c"
+            #line 1462 "Python/bytecodes.c"
             if (err < 0) goto pop_1_error;
-            #line 2006 "Python/generated_cases.c.h"
+            #line 2114 "Python/generated_cases.c.h"
             STACK_SHRINK(1);
             DISPATCH();
         }
@@ -2010,7 +2118,7 @@
         TARGET(BUILD_SET) {
             PyObject **values = (stack_pointer - oparg);
             PyObject *set;
-            #line 1447 "Python/bytecodes.c"
+            #line 1466 "Python/bytecodes.c"
             set = PySet_New(NULL);
             if (set == NULL)
                 goto error;
@@ -2025,7 +2133,7 @@
                 Py_DECREF(set);
                 if (true) { STACK_SHRINK(oparg); goto error; }
             }
-            #line 2029 "Python/generated_cases.c.h"
+            #line 2137 "Python/generated_cases.c.h"
             STACK_SHRINK(oparg);
             STACK_GROW(1);
             stack_pointer[-1] = set;
@@ -2035,7 +2143,7 @@
         TARGET(BUILD_MAP) {
             PyObject **values = (stack_pointer - oparg*2);
             PyObject *map;
-            #line 1464 "Python/bytecodes.c"
+            #line 1483 "Python/bytecodes.c"
             map = _PyDict_FromItems(
                     values, 2,
                     values+1, 2,
@@ -2043,13 +2151,13 @@
             if (map == NULL)
                 goto error;
 
-            #line 2047 "Python/generated_cases.c.h"
+            #line 2155 "Python/generated_cases.c.h"
             for (int _i = oparg*2; --_i >= 0;) {
                 Py_DECREF(values[_i]);
             }
-            #line 1472 "Python/bytecodes.c"
+            #line 1491 "Python/bytecodes.c"
             if (map == NULL) { STACK_SHRINK(oparg*2); goto error; }
-            #line 2053 "Python/generated_cases.c.h"
+            #line 2161 "Python/generated_cases.c.h"
             STACK_SHRINK(oparg*2);
             STACK_GROW(1);
             stack_pointer[-1] = map;
@@ -2057,7 +2165,7 @@
         }
 
         TARGET(SETUP_ANNOTATIONS) {
-            #line 1476 "Python/bytecodes.c"
+            #line 1495 "Python/bytecodes.c"
             int err;
             PyObject *ann_dict;
             if (LOCALS() == NULL) {
@@ -2097,7 +2205,7 @@
                     Py_DECREF(ann_dict);
                 }
             }
-            #line 2101 "Python/generated_cases.c.h"
+            #line 2209 "Python/generated_cases.c.h"
             DISPATCH();
         }
 
@@ -2105,7 +2213,7 @@
             PyObject *keys = stack_pointer[-1];
             PyObject **values = (stack_pointer - (1 + oparg));
             PyObject *map;
-            #line 1518 "Python/bytecodes.c"
+            #line 1537 "Python/bytecodes.c"
             if (!PyTuple_CheckExact(keys) ||
                 PyTuple_GET_SIZE(keys) != (Py_ssize_t)oparg) {
                 _PyErr_SetString(tstate, PyExc_SystemError,
@@ -2115,14 +2223,14 @@
             map = _PyDict_FromItems(
                     &PyTuple_GET_ITEM(keys, 0), 1,
                     values, 1, oparg);
-            #line 2119 "Python/generated_cases.c.h"
+            #line 2227 "Python/generated_cases.c.h"
             for (int _i = oparg; --_i >= 0;) {
                 Py_DECREF(values[_i]);
             }
             Py_DECREF(keys);
-            #line 1528 "Python/bytecodes.c"
+            #line 1547 "Python/bytecodes.c"
             if (map == NULL) { STACK_SHRINK(oparg); goto pop_1_error; }
-            #line 2126 "Python/generated_cases.c.h"
+            #line 2234 "Python/generated_cases.c.h"
             STACK_SHRINK(oparg);
             stack_pointer[-1] = map;
             DISPATCH();
@@ -2130,7 +2238,7 @@
 
         TARGET(DICT_UPDATE) {
             PyObject *update = stack_pointer[-1];
-            #line 1532 "Python/bytecodes.c"
+            #line 1551 "Python/bytecodes.c"
             PyObject *dict = PEEK(oparg + 1);  // update is still on the stack
             if (PyDict_Update(dict, update) < 0) {
                 if (_PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) {
@@ -2138,12 +2246,12 @@
                                     "'%.200s' object is not a mapping",
                                     Py_TYPE(update)->tp_name);
                 }
-            #line 2142 "Python/generated_cases.c.h"
+            #line 2250 "Python/generated_cases.c.h"
                 Py_DECREF(update);
-            #line 1540 "Python/bytecodes.c"
+            #line 1559 "Python/bytecodes.c"
                 if (true) goto pop_1_error;
             }
-            #line 2147 "Python/generated_cases.c.h"
+            #line 2255 "Python/generated_cases.c.h"
             Py_DECREF(update);
             STACK_SHRINK(1);
             DISPATCH();
@@ -2151,17 +2259,17 @@
 
         TARGET(DICT_MERGE) {
             PyObject *update = stack_pointer[-1];
-            #line 1546 "Python/bytecodes.c"
+            #line 1565 "Python/bytecodes.c"
             PyObject *dict = PEEK(oparg + 1);  // update is still on the stack
 
             if (_PyDict_MergeEx(dict, update, 2) < 0) {
                 format_kwargs_error(tstate, PEEK(3 + oparg), update);
-            #line 2160 "Python/generated_cases.c.h"
+            #line 2268 "Python/generated_cases.c.h"
                 Py_DECREF(update);
-            #line 1551 "Python/bytecodes.c"
+            #line 1570 "Python/bytecodes.c"
                 if (true) goto pop_1_error;
             }
-            #line 2165 "Python/generated_cases.c.h"
+            #line 2273 "Python/generated_cases.c.h"
             Py_DECREF(update);
             STACK_SHRINK(1);
             PREDICT(CALL_FUNCTION_EX);
@@ -2171,13 +2279,13 @@
         TARGET(MAP_ADD) {
             PyObject *value = stack_pointer[-1];
             PyObject *key = stack_pointer[-2];
-            #line 1558 "Python/bytecodes.c"
+            #line 1577 "Python/bytecodes.c"
             PyObject *dict = PEEK(oparg + 2);  // key, value are still on the stack
             assert(PyDict_CheckExact(dict));
             /* dict[key] = value */
             // Do not DECREF INPUTS because the function steals the references
             if (_PyDict_SetItem_Take2((PyDictObject *)dict, key, value) != 0) goto pop_2_error;
-            #line 2181 "Python/generated_cases.c.h"
+            #line 2289 "Python/generated_cases.c.h"
             STACK_SHRINK(2);
             PREDICT(JUMP_BACKWARD);
             DISPATCH();
@@ -2191,7 +2299,7 @@
             PyObject *global_super = stack_pointer[-3];
             PyObject *res2 = NULL;
             PyObject *res;
-            #line 1573 "Python/bytecodes.c"
+            #line 1592 "Python/bytecodes.c"
             PyObject *name = GETITEM(frame->f_code->co_names, oparg >> 2);
             int load_method = oparg & 1;
             #if ENABLE_SPECIALIZATION
@@ -2209,16 +2317,16 @@
             // handle any case whose performance we care about
             PyObject *stack[] = {class, self};
             PyObject *super = PyObject_Vectorcall(global_super, stack, oparg & 2, NULL);
-            #line 2213 "Python/generated_cases.c.h"
+            #line 2321 "Python/generated_cases.c.h"
             Py_DECREF(global_super);
             Py_DECREF(class);
             Py_DECREF(self);
-            #line 1591 "Python/bytecodes.c"
+            #line 1610 "Python/bytecodes.c"
             if (super == NULL) goto pop_3_error;
             res = PyObject_GetAttr(super, name);
             Py_DECREF(super);
             if (res == NULL) goto pop_3_error;
-            #line 2222 "Python/generated_cases.c.h"
+            #line 2330 "Python/generated_cases.c.h"
             STACK_SHRINK(2);
             STACK_GROW(((oparg & 1) ? 1 : 0));
             stack_pointer[-1] = res;
@@ -2233,20 +2341,20 @@
             PyObject *global_super = stack_pointer[-3];
             PyObject *res2 = NULL;
             PyObject *res;
-            #line 1598 "Python/bytecodes.c"
+            #line 1617 "Python/bytecodes.c"
             assert(!(oparg & 1));
             DEOPT_IF(global_super != (PyObject *)&PySuper_Type, LOAD_SUPER_ATTR);
             DEOPT_IF(!PyType_Check(class), LOAD_SUPER_ATTR);
             STAT_INC(LOAD_SUPER_ATTR, hit);
             PyObject *name = GETITEM(frame->f_code->co_names, oparg >> 2);
             res = _PySuper_Lookup((PyTypeObject *)class, self, name, NULL);
-            #line 2244 "Python/generated_cases.c.h"
+            #line 2352 "Python/generated_cases.c.h"
             Py_DECREF(global_super);
             Py_DECREF(class);
             Py_DECREF(self);
-            #line 1605 "Python/bytecodes.c"
+            #line 1624 "Python/bytecodes.c"
             if (res == NULL) goto pop_3_error;
-            #line 2250 "Python/generated_cases.c.h"
+            #line 2358 "Python/generated_cases.c.h"
             STACK_SHRINK(2);
             STACK_GROW(((oparg & 1) ? 1 : 0));
             stack_pointer[-1] = res;
@@ -2261,7 +2369,7 @@
             PyObject *global_super = stack_pointer[-3];
             PyObject *res2;
             PyObject *res;
-            #line 1609 "Python/bytecodes.c"
+            #line 1628 "Python/bytecodes.c"
             assert(oparg & 1);
             DEOPT_IF(global_super != (PyObject *)&PySuper_Type, LOAD_SUPER_ATTR);
             DEOPT_IF(!PyType_Check(class), LOAD_SUPER_ATTR);
@@ -2282,7 +2390,7 @@
                 res = res2;
                 res2 = NULL;
             }
-            #line 2286 "Python/generated_cases.c.h"
+            #line 2394 "Python/generated_cases.c.h"
             STACK_SHRINK(1);
             stack_pointer[-1] = res;
             stack_pointer[-2] = res2;
@@ -2296,7 +2404,7 @@
             PyObject *owner = stack_pointer[-1];
             PyObject *res2 = NULL;
             PyObject *res;
-            #line 1646 "Python/bytecodes.c"
+            #line 1665 "Python/bytecodes.c"
             #if ENABLE_SPECIALIZATION
             _PyAttrCache *cache = (_PyAttrCache *)next_instr;
             if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
@@ -2330,9 +2438,9 @@
 
                        NULL | meth | arg1 | ... | argN
                     */
-            #line 2334 "Python/generated_cases.c.h"
+            #line 2442 "Python/generated_cases.c.h"
                     Py_DECREF(owner);
-            #line 1680 "Python/bytecodes.c"
+            #line 1699 "Python/bytecodes.c"
                     if (meth == NULL) goto pop_1_error;
                     res2 = NULL;
                     res = meth;
@@ -2341,12 +2449,12 @@
             else {
                 /* Classic, pushes one value. */
                 res = PyObject_GetAttr(owner, name);
-            #line 2345 "Python/generated_cases.c.h"
+            #line 2453 "Python/generated_cases.c.h"
                 Py_DECREF(owner);
-            #line 1689 "Python/bytecodes.c"
+            #line 1708 "Python/bytecodes.c"
                 if (res == NULL) goto pop_1_error;
             }
-            #line 2350 "Python/generated_cases.c.h"
+            #line 2458 "Python/generated_cases.c.h"
             STACK_GROW(((oparg & 1) ? 1 : 0));
             stack_pointer[-1] = res;
             if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; }
@@ -2360,7 +2468,7 @@
             PyObject *res;
             uint32_t type_version = read_u32(&next_instr[1].cache);
             uint16_t index = read_u16(&next_instr[3].cache);
-            #line 1694 "Python/bytecodes.c"
+            #line 1713 "Python/bytecodes.c"
             PyTypeObject *tp = Py_TYPE(owner);
             assert(type_version != 0);
             DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR);
@@ -2373,7 +2481,7 @@
             STAT_INC(LOAD_ATTR, hit);
             Py_INCREF(res);
             res2 = NULL;
-            #line 2377 "Python/generated_cases.c.h"
+            #line 2485 "Python/generated_cases.c.h"
             Py_DECREF(owner);
             STACK_GROW(((oparg & 1) ? 1 : 0));
             stack_pointer[-1] = res;
@@ -2388,7 +2496,7 @@
             PyObject *res;
             uint32_t type_version = read_u32(&next_instr[1].cache);
             uint16_t index = read_u16(&next_instr[3].cache);
-            #line 1710 "Python/bytecodes.c"
+            #line 1729 "Python/bytecodes.c"
             DEOPT_IF(!PyModule_CheckExact(owner), LOAD_ATTR);
             PyDictObject *dict = (PyDictObject *)((PyModuleObject *)owner)->md_dict;
             assert(dict != NULL);
@@ -2401,7 +2509,7 @@
             STAT_INC(LOAD_ATTR, hit);
             Py_INCREF(res);
             res2 = NULL;
-            #line 2405 "Python/generated_cases.c.h"
+            #line 2513 "Python/generated_cases.c.h"
             Py_DECREF(owner);
             STACK_GROW(((oparg & 1) ? 1 : 0));
             stack_pointer[-1] = res;
@@ -2416,7 +2524,7 @@
             PyObject *res;
             uint32_t type_version = read_u32(&next_instr[1].cache);
             uint16_t index = read_u16(&next_instr[3].cache);
-            #line 1726 "Python/bytecodes.c"
+            #line 1745 "Python/bytecodes.c"
             PyTypeObject *tp = Py_TYPE(owner);
             assert(type_version != 0);
             DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR);
@@ -2443,7 +2551,7 @@
             STAT_INC(LOAD_ATTR, hit);
             Py_INCREF(res);
             res2 = NULL;
-            #line 2447 "Python/generated_cases.c.h"
+            #line 2555 "Python/generated_cases.c.h"
             Py_DECREF(owner);
             STACK_GROW(((oparg & 1) ? 1 : 0));
             stack_pointer[-1] = res;
@@ -2458,7 +2566,7 @@
             PyObject *res;
             uint32_t type_version = read_u32(&next_instr[1].cache);
             uint16_t index = read_u16(&next_instr[3].cache);
-            #line 1756 "Python/bytecodes.c"
+            #line 1775 "Python/bytecodes.c"
             PyTypeObject *tp = Py_TYPE(owner);
             assert(type_version != 0);
             DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR);
@@ -2468,7 +2576,7 @@
             STAT_INC(LOAD_ATTR, hit);
             Py_INCREF(res);
             res2 = NULL;
-            #line 2472 "Python/generated_cases.c.h"
+            #line 2580 "Python/generated_cases.c.h"
             Py_DECREF(owner);
             STACK_GROW(((oparg & 1) ? 1 : 0));
             stack_pointer[-1] = res;
@@ -2483,7 +2591,7 @@
             PyObject *res;
             uint32_t type_version = read_u32(&next_instr[1].cache);
             PyObject *descr = read_obj(&next_instr[5].cache);
-            #line 1769 "Python/bytecodes.c"
+            #line 1788 "Python/bytecodes.c"
 
             DEOPT_IF(!PyType_Check(cls), LOAD_ATTR);
             DEOPT_IF(((PyTypeObject *)cls)->tp_version_tag != type_version,
@@ -2495,7 +2603,7 @@
             res = descr;
             assert(res != NULL);
             Py_INCREF(res);
-            #line 2499 "Python/generated_cases.c.h"
+            #line 2607 "Python/generated_cases.c.h"
             Py_DECREF(cls);
             STACK_GROW(((oparg & 1) ? 1 : 0));
             stack_pointer[-1] = res;
@@ -2509,7 +2617,7 @@
             uint32_t type_version = read_u32(&next_instr[1].cache);
             uint32_t func_version = read_u32(&next_instr[3].cache);
             PyObject *fget = read_obj(&next_instr[5].cache);
-            #line 1784 "Python/bytecodes.c"
+            #line 1803 "Python/bytecodes.c"
             DEOPT_IF(tstate->interp->eval_frame, LOAD_ATTR);
 
             PyTypeObject *cls = Py_TYPE(owner);
@@ -2533,7 +2641,7 @@
             JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR);
             frame->return_offset = 0;
             DISPATCH_INLINED(new_frame);
-            #line 2537 "Python/generated_cases.c.h"
+            #line 2645 "Python/generated_cases.c.h"
         }
 
         TARGET(LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN) {
@@ -2541,7 +2649,7 @@
             uint32_t type_version = read_u32(&next_instr[1].cache);
             uint32_t func_version = read_u32(&next_instr[3].cache);
             PyObject *getattribute = read_obj(&next_instr[5].cache);
-            #line 1810 "Python/bytecodes.c"
+            #line 1829 "Python/bytecodes.c"
             DEOPT_IF(tstate->interp->eval_frame, LOAD_ATTR);
             PyTypeObject *cls = Py_TYPE(owner);
             DEOPT_IF(cls->tp_version_tag != type_version, LOAD_ATTR);
@@ -2567,7 +2675,7 @@
             JUMPBY(INLINE_CACHE_ENTRIES_LOAD_ATTR);
             frame->return_offset = 0;
             DISPATCH_INLINED(new_frame);
-            #line 2571 "Python/generated_cases.c.h"
+            #line 2679 "Python/generated_cases.c.h"
         }
 
         TARGET(STORE_ATTR_INSTANCE_VALUE) {
@@ -2575,7 +2683,7 @@
             PyObject *value = stack_pointer[-2];
             uint32_t type_version = read_u32(&next_instr[1].cache);
             uint16_t index = read_u16(&next_instr[3].cache);
-            #line 1838 "Python/bytecodes.c"
+            #line 1857 "Python/bytecodes.c"
             PyTypeObject *tp = Py_TYPE(owner);
             assert(type_version != 0);
             DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR);
@@ -2593,7 +2701,7 @@
                 Py_DECREF(old_value);
             }
             Py_DECREF(owner);
-            #line 2597 "Python/generated_cases.c.h"
+            #line 2705 "Python/generated_cases.c.h"
             STACK_SHRINK(2);
             next_instr += 4;
             DISPATCH();
@@ -2604,7 +2712,7 @@
             PyObject *value = stack_pointer[-2];
             uint32_t type_version = read_u32(&next_instr[1].cache);
             uint16_t hint = read_u16(&next_instr[3].cache);
-            #line 1858 "Python/bytecodes.c"
+            #line 1877 "Python/bytecodes.c"
             PyTypeObject *tp = Py_TYPE(owner);
             assert(type_version != 0);
             DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR);
@@ -2643,7 +2751,7 @@
             /* PEP 509 */
             dict->ma_version_tag = new_version;
             Py_DECREF(owner);
-            #line 2647 "Python/generated_cases.c.h"
+            #line 2755 "Python/generated_cases.c.h"
             STACK_SHRINK(2);
             next_instr += 4;
             DISPATCH();
@@ -2654,7 +2762,7 @@
             PyObject *value = stack_pointer[-2];
             uint32_t type_version = read_u32(&next_instr[1].cache);
             uint16_t index = read_u16(&next_instr[3].cache);
-            #line 1899 "Python/bytecodes.c"
+            #line 1918 "Python/bytecodes.c"
             PyTypeObject *tp = Py_TYPE(owner);
             assert(type_version != 0);
             DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR);
@@ -2664,7 +2772,7 @@
             *(PyObject **)addr = value;
             Py_XDECREF(old_value);
             Py_DECREF(owner);
-            #line 2668 "Python/generated_cases.c.h"
+            #line 2776 "Python/generated_cases.c.h"
             STACK_SHRINK(2);
             next_instr += 4;
             DISPATCH();
@@ -2676,7 +2784,7 @@
             PyObject *right = stack_pointer[-1];
             PyObject *left = stack_pointer[-2];
             PyObject *res;
-            #line 1918 "Python/bytecodes.c"
+            #line 1937 "Python/bytecodes.c"
             #if ENABLE_SPECIALIZATION
             _PyCompareOpCache *cache = (_PyCompareOpCache *)next_instr;
             if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
@@ -2689,12 +2797,12 @@
             #endif  /* ENABLE_SPECIALIZATION */
             assert((oparg >> 4) <= Py_GE);
             res = PyObject_RichCompare(left, right, oparg>>4);
-            #line 2693 "Python/generated_cases.c.h"
+            #line 2801 "Python/generated_cases.c.h"
             Py_DECREF(left);
             Py_DECREF(right);
-            #line 1931 "Python/bytecodes.c"
+            #line 1950 "Python/bytecodes.c"
             if (res == NULL) goto pop_2_error;
-            #line 2698 "Python/generated_cases.c.h"
+            #line 2806 "Python/generated_cases.c.h"
             STACK_SHRINK(1);
             stack_pointer[-1] = res;
             next_instr += 1;
@@ -2705,7 +2813,7 @@
             PyObject *right = stack_pointer[-1];
             PyObject *left = stack_pointer[-2];
             PyObject *res;
-            #line 1935 "Python/bytecodes.c"
+            #line 1954 "Python/bytecodes.c"
             DEOPT_IF(!PyFloat_CheckExact(left), COMPARE_OP);
             DEOPT_IF(!PyFloat_CheckExact(right), COMPARE_OP);
             STAT_INC(COMPARE_OP, hit);
@@ -2717,7 +2825,7 @@
             _Py_DECREF_SPECIALIZED(right, _PyFloat_ExactDealloc);
             res = (sign_ish & oparg) ? Py_True : Py_False;
             Py_INCREF(res);
-            #line 2721 "Python/generated_cases.c.h"
+            #line 2829 "Python/generated_cases.c.h"
             STACK_SHRINK(1);
             stack_pointer[-1] = res;
             next_instr += 1;
@@ -2728,7 +2836,7 @@
             PyObject *right = stack_pointer[-1];
             PyObject *left = stack_pointer[-2];
             PyObject *res;
-            #line 1950 "Python/bytecodes.c"
+            #line 1969 "Python/bytecodes.c"
             DEOPT_IF(!PyLong_CheckExact(left), COMPARE_OP);
             DEOPT_IF(!PyLong_CheckExact(right), COMPARE_OP);
             DEOPT_IF(!_PyLong_IsCompact((PyLongObject *)left), COMPARE_OP);
@@ -2744,7 +2852,7 @@
             _Py_DECREF_SPECIALIZED(right, (destructor)PyObject_Free);
             res = (sign_ish & oparg) ? Py_True : Py_False;
             Py_INCREF(res);
-            #line 2748 "Python/generated_cases.c.h"
+            #line 2856 "Python/generated_cases.c.h"
             STACK_SHRINK(1);
             stack_pointer[-1] = res;
             next_instr += 1;
@@ -2755,7 +2863,7 @@
             PyObject *right = stack_pointer[-1];
             PyObject *left = stack_pointer[-2];
             PyObject *res;
-            #line 1969 "Python/bytecodes.c"
+            #line 1988 "Python/bytecodes.c"
             DEOPT_IF(!PyUnicode_CheckExact(left), COMPARE_OP);
             DEOPT_IF(!PyUnicode_CheckExact(right), COMPARE_OP);
             STAT_INC(COMPARE_OP, hit);
@@ -2768,7 +2876,7 @@
             assert(COMPARISON_NOT_EQUALS + 1 == COMPARISON_EQUALS);
             res = ((COMPARISON_NOT_EQUALS + eq) & oparg) ? Py_True : Py_False;
             Py_INCREF(res);
-            #line 2772 "Python/generated_cases.c.h"
+            #line 2880 "Python/generated_cases.c.h"
             STACK_SHRINK(1);
             stack_pointer[-1] = res;
             next_instr += 1;
@@ -2779,14 +2887,14 @@
             PyObject *right = stack_pointer[-1];
             PyObject *left = stack_pointer[-2];
             PyObject *b;
-            #line 1984 "Python/bytecodes.c"
+            #line 2003 "Python/bytecodes.c"
             int res = Py_Is(left, right) ^ oparg;
-            #line 2785 "Python/generated_cases.c.h"
+            #line 2893 "Python/generated_cases.c.h"
             Py_DECREF(left);
             Py_DECREF(right);
-            #line 1986 "Python/bytecodes.c"
+            #line 2005 "Python/bytecodes.c"
             b = Py_NewRef(res ? Py_True : Py_False);
-            #line 2790 "Python/generated_cases.c.h"
+            #line 2898 "Python/generated_cases.c.h"
             STACK_SHRINK(1);
             stack_pointer[-1] = b;
             DISPATCH();
@@ -2796,15 +2904,15 @@
             PyObject *right = stack_pointer[-1];
             PyObject *left = stack_pointer[-2];
             PyObject *b;
-            #line 1990 "Python/bytecodes.c"
+            #line 2009 "Python/bytecodes.c"
             int res = PySequence_Contains(right, left);
-            #line 2802 "Python/generated_cases.c.h"
+            #line 2910 "Python/generated_cases.c.h"
             Py_DECREF(left);
             Py_DECREF(right);
-            #line 1992 "Python/bytecodes.c"
+            #line 2011 "Python/bytecodes.c"
             if (res < 0) goto pop_2_error;
             b = Py_NewRef((res^oparg) ? Py_True : Py_False);
-            #line 2808 "Python/generated_cases.c.h"
+            #line 2916 "Python/generated_cases.c.h"
             STACK_SHRINK(1);
             stack_pointer[-1] = b;
             DISPATCH();
@@ -2815,12 +2923,12 @@
             PyObject *exc_value = stack_pointer[-2];
             PyObject *rest;
             PyObject *match;
-            #line 1997 "Python/bytecodes.c"
+            #line 2016 "Python/bytecodes.c"
             if (check_except_star_type_valid(tstate, match_type) < 0) {
-            #line 2821 "Python/generated_cases.c.h"
+            #line 2929 "Python/generated_cases.c.h"
                 Py_DECREF(exc_value);
                 Py_DECREF(match_type);
-            #line 1999 "Python/bytecodes.c"
+            #line 2018 "Python/bytecodes.c"
                 if (true) goto pop_2_error;
             }
 
@@ -2828,10 +2936,10 @@
             rest = NULL;
             int res = exception_group_match(exc_value, match_type,
                                             &match, &rest);
-            #line 2832 "Python/generated_cases.c.h"
+            #line 2940 "Python/generated_cases.c.h"
             Py_DECREF(exc_value);
             Py_DECREF(match_type);
-            #line 2007 "Python/bytecodes.c"
+            #line 2026 "Python/bytecodes.c"
             if (res < 0) goto pop_2_error;
 
             assert((match == NULL) == (rest == NULL));
@@ -2840,7 +2948,7 @@
             if (!Py_IsNone(match)) {
                 PyErr_SetHandledException(match);
             }
-            #line 2844 "Python/generated_cases.c.h"
+            #line 2952 "Python/generated_cases.c.h"
             stack_pointer[-1] = match;
             stack_pointer[-2] = rest;
             DISPATCH();
@@ -2850,21 +2958,21 @@
             PyObject *right = stack_pointer[-1];
             PyObject *left = stack_pointer[-2];
             PyObject *b;
-            #line 2018 "Python/bytecodes.c"
+            #line 2037 "Python/bytecodes.c"
             assert(PyExceptionInstance_Check(left));
             if (check_except_type_valid(tstate, right) < 0) {
-            #line 2857 "Python/generated_cases.c.h"
+            #line 2965 "Python/generated_cases.c.h"
                  Py_DECREF(right);
-            #line 2021 "Python/bytecodes.c"
+            #line 2040 "Python/bytecodes.c"
                  if (true) goto pop_1_error;
             }
 
             int res = PyErr_GivenExceptionMatches(left, right);
-            #line 2864 "Python/generated_cases.c.h"
+            #line 2972 "Python/generated_cases.c.h"
             Py_DECREF(right);
-            #line 2026 "Python/bytecodes.c"
+            #line 2045 "Python/bytecodes.c"
             b = Py_NewRef(res ? Py_True : Py_False);
-            #line 2868 "Python/generated_cases.c.h"
+            #line 2976 "Python/generated_cases.c.h"
             stack_pointer[-1] = b;
             DISPATCH();
         }
@@ -2873,15 +2981,15 @@
             PyObject *fromlist = stack_pointer[-1];
             PyObject *level = stack_pointer[-2];
             PyObject *res;
-            #line 2030 "Python/bytecodes.c"
+            #line 2049 "Python/bytecodes.c"
             PyObject *name = GETITEM(frame->f_code->co_names, oparg);
             res = import_name(tstate, frame, name, fromlist, level);
-            #line 2880 "Python/generated_cases.c.h"
+            #line 2988 "Python/generated_cases.c.h"
             Py_DECREF(level);
             Py_DECREF(fromlist);
-            #line 2033 "Python/bytecodes.c"
+            #line 2052 "Python/bytecodes.c"
             if (res == NULL) goto pop_2_error;
-            #line 2885 "Python/generated_cases.c.h"
+            #line 2993 "Python/generated_cases.c.h"
             STACK_SHRINK(1);
             stack_pointer[-1] = res;
             DISPATCH();
@@ -2890,29 +2998,29 @@
         TARGET(IMPORT_FROM) {
             PyObject *from = stack_pointer[-1];
             PyObject *res;
-            #line 2037 "Python/bytecodes.c"
+            #line 2056 "Python/bytecodes.c"
             PyObject *name = GETITEM(frame->f_code->co_names, oparg);
             res = import_from(tstate, from, name);
             if (res == NULL) goto error;
-            #line 2898 "Python/generated_cases.c.h"
+            #line 3006 "Python/generated_cases.c.h"
             STACK_GROW(1);
             stack_pointer[-1] = res;
             DISPATCH();
         }
 
         TARGET(JUMP_FORWARD) {
-            #line 2043 "Python/bytecodes.c"
+            #line 2062 "Python/bytecodes.c"
             JUMPBY(oparg);
-            #line 2907 "Python/generated_cases.c.h"
+            #line 3015 "Python/generated_cases.c.h"
             DISPATCH();
         }
 
         TARGET(JUMP_BACKWARD) {
             PREDICTED(JUMP_BACKWARD);
-            #line 2047 "Python/bytecodes.c"
+            #line 2066 "Python/bytecodes.c"
             assert(oparg < INSTR_OFFSET());
             JUMPBY(-oparg);
-            #line 2916 "Python/generated_cases.c.h"
+            #line 3024 "Python/generated_cases.c.h"
             CHECK_EVAL_BREAKER();
             DISPATCH();
         }
@@ -2920,7 +3028,7 @@
         TARGET(POP_JUMP_IF_FALSE) {
             PREDICTED(POP_JUMP_IF_FALSE);
             PyObject *cond = stack_pointer[-1];
-            #line 2053 "Python/bytecodes.c"
+            #line 2072 "Python/bytecodes.c"
             if (Py_IsTrue(cond)) {
                 _Py_DECREF_NO_DEALLOC(cond);
             }
@@ -2930,9 +3038,9 @@
             }
             else {
                 int err = PyObject_IsTrue(cond);
-            #line 2934 "Python/generated_cases.c.h"
+            #line 3042 "Python/generated_cases.c.h"
                 Py_DECREF(cond);
-            #line 2063 "Python/bytecodes.c"
+            #line 2082 "Python/bytecodes.c"
                 if (err == 0) {
                     JUMPBY(oparg);
                 }
@@ -2940,14 +3048,14 @@
                     if (err < 0) goto pop_1_error;
                 }
             }
-            #line 2944 "Python/generated_cases.c.h"
+            #line 3052 "Python/generated_cases.c.h"
             STACK_SHRINK(1);
             DISPATCH();
         }
 
         TARGET(POP_JUMP_IF_TRUE) {
             PyObject *cond = stack_pointer[-1];
-            #line 2073 "Python/bytecodes.c"
+            #line 2092 "Python/bytecodes.c"
             if (Py_IsFalse(cond)) {
                 _Py_DECREF_NO_DEALLOC(cond);
             }
@@ -2957,9 +3065,9 @@
             }
             else {
                 int err = PyObject_IsTrue(cond);
-            #line 2961 "Python/generated_cases.c.h"
+            #line 3069 "Python/generated_cases.c.h"
                 Py_DECREF(cond);
-            #line 2083 "Python/bytecodes.c"
+            #line 2102 "Python/bytecodes.c"
                 if (err > 0) {
                     JUMPBY(oparg);
                 }
@@ -2967,67 +3075,67 @@
                     if (err < 0) goto pop_1_error;
                 }
             }
-            #line 2971 "Python/generated_cases.c.h"
+            #line 3079 "Python/generated_cases.c.h"
             STACK_SHRINK(1);
             DISPATCH();
         }
 
         TARGET(POP_JUMP_IF_NOT_NONE) {
             PyObject *value = stack_pointer[-1];
-            #line 2093 "Python/bytecodes.c"
+            #line 2112 "Python/bytecodes.c"
             if (!Py_IsNone(value)) {
-            #line 2980 "Python/generated_cases.c.h"
+            #line 3088 "Python/generated_cases.c.h"
                 Py_DECREF(value);
-            #line 2095 "Python/bytecodes.c"
+            #line 2114 "Python/bytecodes.c"
                 JUMPBY(oparg);
             }
             else {
                 _Py_DECREF_NO_DEALLOC(value);
             }
-            #line 2988 "Python/generated_cases.c.h"
+            #line 3096 "Python/generated_cases.c.h"
             STACK_SHRINK(1);
             DISPATCH();
         }
 
         TARGET(POP_JUMP_IF_NONE) {
             PyObject *value = stack_pointer[-1];
-            #line 2103 "Python/bytecodes.c"
+            #line 2122 "Python/bytecodes.c"
             if (Py_IsNone(value)) {
                 _Py_DECREF_NO_DEALLOC(value);
                 JUMPBY(oparg);
             }
             else {
-            #line 3001 "Python/generated_cases.c.h"
+            #line 3109 "Python/generated_cases.c.h"
                 Py_DECREF(value);
-            #line 2109 "Python/bytecodes.c"
+            #line 2128 "Python/bytecodes.c"
             }
-            #line 3005 "Python/generated_cases.c.h"
+            #line 3113 "Python/generated_cases.c.h"
             STACK_SHRINK(1);
             DISPATCH();
         }
 
         TARGET(JUMP_BACKWARD_NO_INTERRUPT) {
-            #line 2113 "Python/bytecodes.c"
+            #line 2132 "Python/bytecodes.c"
             /* This bytecode is used in the `yield from` or `await` loop.
              * If there is an interrupt, we want it handled in the innermost
              * generator or coroutine, so we deliberately do not check it here.
              * (see bpo-30039).
              */
             JUMPBY(-oparg);
-            #line 3018 "Python/generated_cases.c.h"
+            #line 3126 "Python/generated_cases.c.h"
             DISPATCH();
         }
 
         TARGET(GET_LEN) {
             PyObject *obj = stack_pointer[-1];
             PyObject *len_o;
-            #line 2122 "Python/bytecodes.c"
+            #line 2141 "Python/bytecodes.c"
             // PUSH(len(TOS))
             Py_ssize_t len_i = PyObject_Length(obj);
             if (len_i < 0) goto error;
             len_o = PyLong_FromSsize_t(len_i);
             if (len_o == NULL) goto error;
-            #line 3031 "Python/generated_cases.c.h"
+            #line 3139 "Python/generated_cases.c.h"
             STACK_GROW(1);
             stack_pointer[-1] = len_o;
             DISPATCH();
@@ -3038,16 +3146,16 @@
             PyObject *type = stack_pointer[-2];
             PyObject *subject = stack_pointer[-3];
             PyObject *attrs;
-            #line 2130 "Python/bytecodes.c"
+            #line 2149 "Python/bytecodes.c"
             // Pop TOS and TOS1. Set TOS to a tuple of attributes on success, or
             // None on failure.
             assert(PyTuple_CheckExact(names));
             attrs = match_class(tstate, subject, type, oparg, names);
-            #line 3047 "Python/generated_cases.c.h"
+            #line 3155 "Python/generated_cases.c.h"
             Py_DECREF(subject);
             Py_DECREF(type);
             Py_DECREF(names);
-            #line 2135 "Python/bytecodes.c"
+            #line 2154 "Python/bytecodes.c"
             if (attrs) {
                 assert(PyTuple_CheckExact(attrs));  // Success!
             }
@@ -3055,7 +3163,7 @@
                 if (_PyErr_Occurred(tstate)) goto pop_3_error;
                 attrs = Py_NewRef(Py_None);  // Failure!
             }
-            #line 3059 "Python/generated_cases.c.h"
+            #line 3167 "Python/generated_cases.c.h"
             STACK_SHRINK(2);
             stack_pointer[-1] = attrs;
             DISPATCH();
@@ -3064,10 +3172,10 @@
         TARGET(MATCH_MAPPING) {
             PyObject *subject = stack_pointer[-1];
             PyObject *res;
-            #line 2145 "Python/bytecodes.c"
+            #line 2164 "Python/bytecodes.c"
             int match = Py_TYPE(subject)->tp_flags & Py_TPFLAGS_MAPPING;
             res = Py_NewRef(match ? Py_True : Py_False);
-            #line 3071 "Python/generated_cases.c.h"
+            #line 3179 "Python/generated_cases.c.h"
             STACK_GROW(1);
             stack_pointer[-1] = res;
             PREDICT(POP_JUMP_IF_FALSE);
@@ -3077,10 +3185,10 @@
         TARGET(MATCH_SEQUENCE) {
             PyObject *subject = stack_pointer[-1];
             PyObject *res;
-            #line 2151 "Python/bytecodes.c"
+            #line 2170 "Python/bytecodes.c"
             int match = Py_TYPE(subject)->tp_flags & Py_TPFLAGS_SEQUENCE;
             res = Py_NewRef(match ? Py_True : Py_False);
-            #line 3084 "Python/generated_cases.c.h"
+            #line 3192 "Python/generated_cases.c.h"
             STACK_GROW(1);
             stack_pointer[-1] = res;
             PREDICT(POP_JUMP_IF_FALSE);
@@ -3091,11 +3199,11 @@
             PyObject *keys = stack_pointer[-1];
             PyObject *subject = stack_pointer[-2];
             PyObject *values_or_none;
-            #line 2157 "Python/bytecodes.c"
+            #line 2176 "Python/bytecodes.c"
             // On successful match, PUSH(values). Otherwise, PUSH(None).
             values_or_none = match_keys(tstate, subject, keys);
             if (values_or_none == NULL) goto error;
-            #line 3099 "Python/generated_cases.c.h"
+            #line 3207 "Python/generated_cases.c.h"
             STACK_GROW(1);
             stack_pointer[-1] = values_or_none;
             DISPATCH();
@@ -3104,14 +3212,14 @@
         TARGET(GET_ITER) {
             PyObject *iterable = stack_pointer[-1];
             PyObject *iter;
-            #line 2163 "Python/bytecodes.c"
+            #line 2182 "Python/bytecodes.c"
             /* before: [obj]; after [getiter(obj)] */
             iter = PyObject_GetIter(iterable);
-            #line 3111 "Python/generated_cases.c.h"
+            #line 3219 "Python/generated_cases.c.h"
             Py_DECREF(iterable);
-            #line 2166 "Python/bytecodes.c"
+            #line 2185 "Python/bytecodes.c"
             if (iter == NULL) goto pop_1_error;
-            #line 3115 "Python/generated_cases.c.h"
+            #line 3223 "Python/generated_cases.c.h"
             stack_pointer[-1] = iter;
             DISPATCH();
         }
@@ -3119,7 +3227,7 @@
         TARGET(GET_YIELD_FROM_ITER) {
             PyObject *iterable = stack_pointer[-1];
             PyObject *iter;
-            #line 2170 "Python/bytecodes.c"
+            #line 2189 "Python/bytecodes.c"
             /* before: [obj]; after [getiter(obj)] */
             if (PyCoro_CheckExact(iterable)) {
                 /* `iterable` is a coroutine */
@@ -3142,11 +3250,11 @@
                 if (iter == NULL) {
                     goto error;
                 }
-            #line 3146 "Python/generated_cases.c.h"
+            #line 3254 "Python/generated_cases.c.h"
                 Py_DECREF(iterable);
-            #line 2193 "Python/bytecodes.c"
+            #line 2212 "Python/bytecodes.c"
             }
-            #line 3150 "Python/generated_cases.c.h"
+            #line 3258 "Python/generated_cases.c.h"
             stack_pointer[-1] = iter;
             PREDICT(LOAD_CONST);
             DISPATCH();
@@ -3157,7 +3265,7 @@
             static_assert(INLINE_CACHE_ENTRIES_FOR_ITER == 1, "incorrect cache size");
             PyObject *iter = stack_pointer[-1];
             PyObject *next;
-            #line 2212 "Python/bytecodes.c"
+            #line 2231 "Python/bytecodes.c"
             #if ENABLE_SPECIALIZATION
             _PyForIterCache *cache = (_PyForIterCache *)next_instr;
             if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
@@ -3188,7 +3296,7 @@
                 DISPATCH();
             }
             // Common case: no jump, leave it to the code generator
-            #line 3192 "Python/generated_cases.c.h"
+            #line 3300 "Python/generated_cases.c.h"
             STACK_GROW(1);
             stack_pointer[-1] = next;
             next_instr += 1;
@@ -3196,7 +3304,7 @@
         }
 
         TARGET(INSTRUMENTED_FOR_ITER) {
-            #line 2245 "Python/bytecodes.c"
+            #line 2264 "Python/bytecodes.c"
             _Py_CODEUNIT *here = next_instr-1;
             _Py_CODEUNIT *target;
             PyObject *iter = TOP();
@@ -3222,14 +3330,14 @@
                 target = next_instr + INLINE_CACHE_ENTRIES_FOR_ITER + oparg + 1;
             }
             INSTRUMENTED_JUMP(here, target, PY_MONITORING_EVENT_BRANCH);
-            #line 3226 "Python/generated_cases.c.h"
+            #line 3334 "Python/generated_cases.c.h"
             DISPATCH();
         }
 
         TARGET(FOR_ITER_LIST) {
             PyObject *iter = stack_pointer[-1];
             PyObject *next;
-            #line 2273 "Python/bytecodes.c"
+            #line 2292 "Python/bytecodes.c"
             DEOPT_IF(Py_TYPE(iter) != &PyListIter_Type, FOR_ITER);
             _PyListIterObject *it = (_PyListIterObject *)iter;
             STAT_INC(FOR_ITER, hit);
@@ -3249,7 +3357,7 @@
             DISPATCH();
         end_for_iter_list:
             // Common case: no jump, leave it to the code generator
-            #line 3253 "Python/generated_cases.c.h"
+            #line 3361 "Python/generated_cases.c.h"
             STACK_GROW(1);
             stack_pointer[-1] = next;
             next_instr += 1;
@@ -3259,7 +3367,7 @@
         TARGET(FOR_ITER_TUPLE) {
             PyObject *iter = stack_pointer[-1];
             PyObject *next;
-            #line 2295 "Python/bytecodes.c"
+            #line 2314 "Python/bytecodes.c"
             _PyTupleIterObject *it = (_PyTupleIterObject *)iter;
             DEOPT_IF(Py_TYPE(it) != &PyTupleIter_Type, FOR_ITER);
             STAT_INC(FOR_ITER, hit);
@@ -3279,7 +3387,7 @@
             DISPATCH();
         end_for_iter_tuple:
             // Common case: no jump, leave it to the code generator
-            #line 3283 "Python/generated_cases.c.h"
+            #line 3391 "Python/generated_cases.c.h"
             STACK_GROW(1);
             stack_pointer[-1] = next;
             next_instr += 1;
@@ -3289,7 +3397,7 @@
         TARGET(FOR_ITER_RANGE) {
             PyObject *iter = stack_pointer[-1];
             PyObject *next;
-            #line 2317 "Python/bytecodes.c"
+            #line 2336 "Python/bytecodes.c"
             _PyRangeIterObject *r = (_PyRangeIterObject *)iter;
             DEOPT_IF(Py_TYPE(r) != &PyRangeIter_Type, FOR_ITER);
             STAT_INC(FOR_ITER, hit);
@@ -3307,7 +3415,7 @@
             if (next == NULL) {
                 goto error;
             }
-            #line 3311 "Python/generated_cases.c.h"
+            #line 3419 "Python/generated_cases.c.h"
             STACK_GROW(1);
             stack_pointer[-1] = next;
             next_instr += 1;
@@ -3316,7 +3424,7 @@
 
         TARGET(FOR_ITER_GEN) {
             PyObject *iter = stack_pointer[-1];
-            #line 2337 "Python/bytecodes.c"
+            #line 2356 "Python/bytecodes.c"
             DEOPT_IF(tstate->interp->eval_frame, FOR_ITER);
             PyGenObject *gen = (PyGenObject *)iter;
             DEOPT_IF(Py_TYPE(gen) != &PyGen_Type, FOR_ITER);
@@ -3332,14 +3440,14 @@
             assert(next_instr[oparg].op.code == END_FOR ||
                    next_instr[oparg].op.code == INSTRUMENTED_END_FOR);
             DISPATCH_INLINED(gen_frame);
-            #line 3336 "Python/generated_cases.c.h"
+            #line 3444 "Python/generated_cases.c.h"
         }
 
         TARGET(BEFORE_ASYNC_WITH) {
             PyObject *mgr = stack_pointer[-1];
             PyObject *exit;
             PyObject *res;
-            #line 2355 "Python/bytecodes.c"
+            #line 2374 "Python/bytecodes.c"
             PyObject *enter = _PyObject_LookupSpecial(mgr, &_Py_ID(__aenter__));
             if (enter == NULL) {
                 if (!_PyErr_Occurred(tstate)) {
@@ -3362,16 +3470,16 @@
                 Py_DECREF(enter);
                 goto error;
             }
-            #line 3366 "Python/generated_cases.c.h"
+            #line 3474 "Python/generated_cases.c.h"
             Py_DECREF(mgr);
-            #line 2378 "Python/bytecodes.c"
+            #line 2397 "Python/bytecodes.c"
             res = _PyObject_CallNoArgs(enter);
             Py_DECREF(enter);
             if (res == NULL) {
                 Py_DECREF(exit);
                 if (true) goto pop_1_error;
             }
-            #line 3375 "Python/generated_cases.c.h"
+            #line 3483 "Python/generated_cases.c.h"
             STACK_GROW(1);
             stack_pointer[-1] = res;
             stack_pointer[-2] = exit;
@@ -3383,7 +3491,7 @@
             PyObject *mgr = stack_pointer[-1];
             PyObject *exit;
             PyObject *res;
-            #line 2388 "Python/bytecodes.c"
+            #line 2407 "Python/bytecodes.c"
             /* pop the context manager, push its __exit__ and the
              * value returned from calling its __enter__
              */
@@ -3409,16 +3517,16 @@
                 Py_DECREF(enter);
                 goto error;
             }
-            #line 3413 "Python/generated_cases.c.h"
+            #line 3521 "Python/generated_cases.c.h"
             Py_DECREF(mgr);
-            #line 2414 "Python/bytecodes.c"
+            #line 2433 "Python/bytecodes.c"
             res = _PyObject_CallNoArgs(enter);
             Py_DECREF(enter);
             if (res == NULL) {
                 Py_DECREF(exit);
                 if (true) goto pop_1_error;
             }
-            #line 3422 "Python/generated_cases.c.h"
+            #line 3530 "Python/generated_cases.c.h"
             STACK_GROW(1);
             stack_pointer[-1] = res;
             stack_pointer[-2] = exit;
@@ -3430,7 +3538,7 @@
             PyObject *lasti = stack_pointer[-3];
             PyObject *exit_func = stack_pointer[-4];
             PyObject *res;
-            #line 2423 "Python/bytecodes.c"
+            #line 2442 "Python/bytecodes.c"
             /* At the top of the stack are 4 values:
                - val: TOP = exc_info()
                - unused: SECOND = previous exception
@@ -3451,7 +3559,7 @@
             res = PyObject_Vectorcall(exit_func, stack + 1,
                     3 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL);
             if (res == NULL) goto error;
-            #line 3455 "Python/generated_cases.c.h"
+            #line 3563 "Python/generated_cases.c.h"
             STACK_GROW(1);
             stack_pointer[-1] = res;
             DISPATCH();
@@ -3460,7 +3568,7 @@
         TARGET(PUSH_EXC_INFO) {
             PyObject *new_exc = stack_pointer[-1];
             PyObject *prev_exc;
-            #line 2446 "Python/bytecodes.c"
+            #line 2465 "Python/bytecodes.c"
             _PyErr_StackItem *exc_info = tstate->exc_info;
             if (exc_info->exc_value != NULL) {
                 prev_exc = exc_info->exc_value;
@@ -3470,7 +3578,7 @@
             }
             assert(PyExceptionInstance_Check(new_exc));
             exc_info->exc_value = Py_NewRef(new_exc);
-            #line 3474 "Python/generated_cases.c.h"
+            #line 3582 "Python/generated_cases.c.h"
             STACK_GROW(1);
             stack_pointer[-1] = new_exc;
             stack_pointer[-2] = prev_exc;
@@ -3484,7 +3592,7 @@
             uint32_t type_version = read_u32(&next_instr[1].cache);
             uint32_t keys_version = read_u32(&next_instr[3].cache);
             PyObject *descr = read_obj(&next_instr[5].cache);
-            #line 2458 "Python/bytecodes.c"
+            #line 2477 "Python/bytecodes.c"
             /* Cached method object */
             PyTypeObject *self_cls = Py_TYPE(self);
             assert(type_version != 0);
@@ -3501,7 +3609,7 @@
             assert(_PyType_HasFeature(Py_TYPE(res2), Py_TPFLAGS_METHOD_DESCRIPTOR));
             res = self;
             assert(oparg & 1);
-            #line 3505 "Python/generated_cases.c.h"
+            #line 3613 "Python/generated_cases.c.h"
             STACK_GROW(((oparg & 1) ? 1 : 0));
             stack_pointer[-1] = res;
             if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; }
@@ -3515,7 +3623,7 @@
             PyObject *res;
             uint32_t type_version = read_u32(&next_instr[1].cache);
             PyObject *descr = read_obj(&next_instr[5].cache);
-            #line 2477 "Python/bytecodes.c"
+            #line 2496 "Python/bytecodes.c"
             PyTypeObject *self_cls = Py_TYPE(self);
             DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_ATTR);
             assert(self_cls->tp_dictoffset == 0);
@@ -3525,7 +3633,7 @@
             res2 = Py_NewRef(descr);
             res = self;
             assert(oparg & 1);
-            #line 3529 "Python/generated_cases.c.h"
+            #line 3637 "Python/generated_cases.c.h"
             STACK_GROW(((oparg & 1) ? 1 : 0));
             stack_pointer[-1] = res;
             if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; }
@@ -3539,7 +3647,7 @@
             PyObject *res;
             uint32_t type_version = read_u32(&next_instr[1].cache);
             PyObject *descr = read_obj(&next_instr[5].cache);
-            #line 2489 "Python/bytecodes.c"
+            #line 2508 "Python/bytecodes.c"
             PyTypeObject *self_cls = Py_TYPE(self);
             DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_ATTR);
             Py_ssize_t dictoffset = self_cls->tp_dictoffset;
@@ -3553,7 +3661,7 @@
             res2 = Py_NewRef(descr);
             res = self;
             assert(oparg & 1);
-            #line 3557 "Python/generated_cases.c.h"
+            #line 3665 "Python/generated_cases.c.h"
             STACK_GROW(((oparg & 1) ? 1 : 0));
             stack_pointer[-1] = res;
             if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; }
@@ -3562,16 +3670,16 @@
         }
 
         TARGET(KW_NAMES) {
-            #line 2505 "Python/bytecodes.c"
+            #line 2524 "Python/bytecodes.c"
             assert(kwnames == NULL);
             assert(oparg < PyTuple_GET_SIZE(frame->f_code->co_consts));
             kwnames = GETITEM(frame->f_code->co_consts, oparg);
-            #line 3570 "Python/generated_cases.c.h"
+            #line 3678 "Python/generated_cases.c.h"
             DISPATCH();
         }
 
         TARGET(INSTRUMENTED_CALL) {
-            #line 2511 "Python/bytecodes.c"
+            #line 2530 "Python/bytecodes.c"
             int is_meth = PEEK(oparg+2) != NULL;
             int total_args = oparg + is_meth;
             PyObject *function = PEEK(total_args + 1);
@@ -3584,7 +3692,7 @@
             _PyCallCache *cache = (_PyCallCache *)next_instr;
             INCREMENT_ADAPTIVE_COUNTER(cache->counter);
             GO_TO_INSTRUCTION(CALL);
-            #line 3588 "Python/generated_cases.c.h"
+            #line 3696 "Python/generated_cases.c.h"
         }
 
         TARGET(CALL) {
@@ -3594,7 +3702,7 @@
             PyObject *callable = stack_pointer[-(1 + oparg)];
             PyObject *method = stack_pointer[-(2 + oparg)];
             PyObject *res;
-            #line 2556 "Python/bytecodes.c"
+            #line 2575 "Python/bytecodes.c"
             int is_meth = method != NULL;
             int total_args = oparg;
             if (is_meth) {
@@ -3676,7 +3784,7 @@
                 Py_DECREF(args[i]);
             }
             if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; }
-            #line 3680 "Python/generated_cases.c.h"
+            #line 3788 "Python/generated_cases.c.h"
             STACK_SHRINK(oparg);
             STACK_SHRINK(1);
             stack_pointer[-1] = res;
@@ -3688,7 +3796,7 @@
         TARGET(CALL_BOUND_METHOD_EXACT_ARGS) {
             PyObject *callable = stack_pointer[-(1 + oparg)];
             PyObject *method = stack_pointer[-(2 + oparg)];
-            #line 2644 "Python/bytecodes.c"
+            #line 2663 "Python/bytecodes.c"
             DEOPT_IF(method != NULL, CALL);
             DEOPT_IF(Py_TYPE(callable) != &PyMethod_Type, CALL);
             STAT_INC(CALL, hit);
@@ -3698,7 +3806,7 @@
             PEEK(oparg + 2) = Py_NewRef(meth);  // method
             Py_DECREF(callable);
             GO_TO_INSTRUCTION(CALL_PY_EXACT_ARGS);
-            #line 3702 "Python/generated_cases.c.h"
+            #line 3810 "Python/generated_cases.c.h"
         }
 
         TARGET(CALL_PY_EXACT_ARGS) {
@@ -3707,7 +3815,7 @@
             PyObject *callable = stack_pointer[-(1 + oparg)];
             PyObject *method = stack_pointer[-(2 + oparg)];
             uint32_t func_version = read_u32(&next_instr[1].cache);
-            #line 2656 "Python/bytecodes.c"
+            #line 2675 "Python/bytecodes.c"
             assert(kwnames == NULL);
             DEOPT_IF(tstate->interp->eval_frame, CALL);
             int is_meth = method != NULL;
@@ -3733,7 +3841,7 @@
             JUMPBY(INLINE_CACHE_ENTRIES_CALL);
             frame->return_offset = 0;
             DISPATCH_INLINED(new_frame);
-            #line 3737 "Python/generated_cases.c.h"
+            #line 3845 "Python/generated_cases.c.h"
         }
 
         TARGET(CALL_PY_WITH_DEFAULTS) {
@@ -3741,7 +3849,7 @@
             PyObject *callable = stack_pointer[-(1 + oparg)];
             PyObject *method = stack_pointer[-(2 + oparg)];
             uint32_t func_version = read_u32(&next_instr[1].cache);
-            #line 2684 "Python/bytecodes.c"
+            #line 2703 "Python/bytecodes.c"
             assert(kwnames == NULL);
             DEOPT_IF(tstate->interp->eval_frame, CALL);
             int is_meth = method != NULL;
@@ -3777,7 +3885,7 @@
             JUMPBY(INLINE_CACHE_ENTRIES_CALL);
             frame->return_offset = 0;
             DISPATCH_INLINED(new_frame);
-            #line 3781 "Python/generated_cases.c.h"
+            #line 3889 "Python/generated_cases.c.h"
         }
 
         TARGET(CALL_NO_KW_TYPE_1) {
@@ -3785,7 +3893,7 @@
             PyObject *callable = stack_pointer[-(1 + oparg)];
             PyObject *null = stack_pointer[-(2 + oparg)];
             PyObject *res;
-            #line 2722 "Python/bytecodes.c"
+            #line 2741 "Python/bytecodes.c"
             assert(kwnames == NULL);
             assert(oparg == 1);
             DEOPT_IF(null != NULL, CALL);
@@ -3795,7 +3903,7 @@
             res = Py_NewRef(Py_TYPE(obj));
             Py_DECREF(obj);
             Py_DECREF(&PyType_Type);  // I.e., callable
-            #line 3799 "Python/generated_cases.c.h"
+            #line 3907 "Python/generated_cases.c.h"
             STACK_SHRINK(oparg);
             STACK_SHRINK(1);
             stack_pointer[-1] = res;
@@ -3808,7 +3916,7 @@
             PyObject *callable = stack_pointer[-(1 + oparg)];
             PyObject *null = stack_pointer[-(2 + oparg)];
             PyObject *res;
-            #line 2734 "Python/bytecodes.c"
+            #line 2753 "Python/bytecodes.c"
             assert(kwnames == NULL);
             assert(oparg == 1);
             DEOPT_IF(null != NULL, CALL);
@@ -3819,7 +3927,7 @@
             Py_DECREF(arg);
             Py_DECREF(&PyUnicode_Type);  // I.e., callable
             if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; }
-            #line 3823 "Python/generated_cases.c.h"
+            #line 3931 "Python/generated_cases.c.h"
             STACK_SHRINK(oparg);
             STACK_SHRINK(1);
             stack_pointer[-1] = res;
@@ -3833,7 +3941,7 @@
             PyObject *callable = stack_pointer[-(1 + oparg)];
             PyObject *null = stack_pointer[-(2 + oparg)];
             PyObject *res;
-            #line 2748 "Python/bytecodes.c"
+            #line 2767 "Python/bytecodes.c"
             assert(kwnames == NULL);
             assert(oparg == 1);
             DEOPT_IF(null != NULL, CALL);
@@ -3844,7 +3952,7 @@
             Py_DECREF(arg);
             Py_DECREF(&PyTuple_Type);  // I.e., tuple
             if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; }
-            #line 3848 "Python/generated_cases.c.h"
+            #line 3956 "Python/generated_cases.c.h"
             STACK_SHRINK(oparg);
             STACK_SHRINK(1);
             stack_pointer[-1] = res;
@@ -3858,7 +3966,7 @@
             PyObject *callable = stack_pointer[-(1 + oparg)];
             PyObject *method = stack_pointer[-(2 + oparg)];
             PyObject *res;
-            #line 2762 "Python/bytecodes.c"
+            #line 2781 "Python/bytecodes.c"
             int is_meth = method != NULL;
             int total_args = oparg;
             if (is_meth) {
@@ -3880,7 +3988,7 @@
             }
             Py_DECREF(tp);
             if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; }
-            #line 3884 "Python/generated_cases.c.h"
+            #line 3992 "Python/generated_cases.c.h"
             STACK_SHRINK(oparg);
             STACK_SHRINK(1);
             stack_pointer[-1] = res;
@@ -3894,7 +4002,7 @@
             PyObject *callable = stack_pointer[-(1 + oparg)];
             PyObject *method = stack_pointer[-(2 + oparg)];
             PyObject *res;
-            #line 2787 "Python/bytecodes.c"
+            #line 2806 "Python/bytecodes.c"
             /* Builtin METH_O functions */
             assert(kwnames == NULL);
             int is_meth = method != NULL;
@@ -3922,7 +4030,7 @@
             Py_DECREF(arg);
             Py_DECREF(callable);
             if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; }
-            #line 3926 "Python/generated_cases.c.h"
+            #line 4034 "Python/generated_cases.c.h"
             STACK_SHRINK(oparg);
             STACK_SHRINK(1);
             stack_pointer[-1] = res;
@@ -3936,7 +4044,7 @@
             PyObject *callable = stack_pointer[-(1 + oparg)];
             PyObject *method = stack_pointer[-(2 + oparg)];
             PyObject *res;
-            #line 2818 "Python/bytecodes.c"
+            #line 2837 "Python/bytecodes.c"
             /* Builtin METH_FASTCALL functions, without keywords */
             assert(kwnames == NULL);
             int is_meth = method != NULL;
@@ -3968,7 +4076,7 @@
                    'invalid'). In those cases an exception is set, so we must
                    handle it.
                 */
-            #line 3972 "Python/generated_cases.c.h"
+            #line 4080 "Python/generated_cases.c.h"
             STACK_SHRINK(oparg);
             STACK_SHRINK(1);
             stack_pointer[-1] = res;
@@ -3982,7 +4090,7 @@
             PyObject *callable = stack_pointer[-(1 + oparg)];
             PyObject *method = stack_pointer[-(2 + oparg)];
             PyObject *res;
-            #line 2853 "Python/bytecodes.c"
+            #line 2872 "Python/bytecodes.c"
             /* Builtin METH_FASTCALL | METH_KEYWORDS functions */
             int is_meth = method != NULL;
             int total_args = oparg;
@@ -4014,7 +4122,7 @@
             }
             Py_DECREF(callable);
             if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; }
-            #line 4018 "Python/generated_cases.c.h"
+            #line 4126 "Python/generated_cases.c.h"
             STACK_SHRINK(oparg);
             STACK_SHRINK(1);
             stack_pointer[-1] = res;
@@ -4028,7 +4136,7 @@
             PyObject *callable = stack_pointer[-(1 + oparg)];
             PyObject *method = stack_pointer[-(2 + oparg)];
             PyObject *res;
-            #line 2888 "Python/bytecodes.c"
+            #line 2907 "Python/bytecodes.c"
             assert(kwnames == NULL);
             /* len(o) */
             int is_meth = method != NULL;
@@ -4053,7 +4161,7 @@
             Py_DECREF(callable);
             Py_DECREF(arg);
             if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; }
-            #line 4057 "Python/generated_cases.c.h"
+            #line 4165 "Python/generated_cases.c.h"
             STACK_SHRINK(oparg);
             STACK_SHRINK(1);
             stack_pointer[-1] = res;
@@ -4066,7 +4174,7 @@
             PyObject *callable = stack_pointer[-(1 + oparg)];
             PyObject *method = stack_pointer[-(2 + oparg)];
             PyObject *res;
-            #line 2915 "Python/bytecodes.c"
+            #line 2934 "Python/bytecodes.c"
             assert(kwnames == NULL);
             /* isinstance(o, o2) */
             int is_meth = method != NULL;
@@ -4093,7 +4201,7 @@
             Py_DECREF(cls);
             Py_DECREF(callable);
             if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; }
-            #line 4097 "Python/generated_cases.c.h"
+            #line 4205 "Python/generated_cases.c.h"
             STACK_SHRINK(oparg);
             STACK_SHRINK(1);
             stack_pointer[-1] = res;
@@ -4105,7 +4213,7 @@
             PyObject **args = (stack_pointer - oparg);
             PyObject *self = stack_pointer[-(1 + oparg)];
             PyObject *method = stack_pointer[-(2 + oparg)];
-            #line 2945 "Python/bytecodes.c"
+            #line 2964 "Python/bytecodes.c"
             assert(kwnames == NULL);
             assert(oparg == 1);
             assert(method != NULL);
@@ -4123,14 +4231,14 @@
             JUMPBY(INLINE_CACHE_ENTRIES_CALL + 1);
             assert(next_instr[-1].op.code == POP_TOP);
             DISPATCH();
-            #line 4127 "Python/generated_cases.c.h"
+            #line 4235 "Python/generated_cases.c.h"
         }
 
         TARGET(CALL_NO_KW_METHOD_DESCRIPTOR_O) {
             PyObject **args = (stack_pointer - oparg);
             PyObject *method = stack_pointer[-(2 + oparg)];
             PyObject *res;
-            #line 2965 "Python/bytecodes.c"
+            #line 2984 "Python/bytecodes.c"
             assert(kwnames == NULL);
             int is_meth = method != NULL;
             int total_args = oparg;
@@ -4161,7 +4269,7 @@
             Py_DECREF(arg);
             Py_DECREF(callable);
             if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; }
-            #line 4165 "Python/generated_cases.c.h"
+            #line 4273 "Python/generated_cases.c.h"
             STACK_SHRINK(oparg);
             STACK_SHRINK(1);
             stack_pointer[-1] = res;
@@ -4174,7 +4282,7 @@
             PyObject **args = (stack_pointer - oparg);
             PyObject *method = stack_pointer[-(2 + oparg)];
             PyObject *res;
-            #line 2999 "Python/bytecodes.c"
+            #line 3018 "Python/bytecodes.c"
             int is_meth = method != NULL;
             int total_args = oparg;
             if (is_meth) {
@@ -4203,7 +4311,7 @@
             }
             Py_DECREF(callable);
             if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; }
-            #line 4207 "Python/generated_cases.c.h"
+            #line 4315 "Python/generated_cases.c.h"
             STACK_SHRINK(oparg);
             STACK_SHRINK(1);
             stack_pointer[-1] = res;
@@ -4216,7 +4324,7 @@
             PyObject **args = (stack_pointer - oparg);
             PyObject *method = stack_pointer[-(2 + oparg)];
             PyObject *res;
-            #line 3031 "Python/bytecodes.c"
+            #line 3050 "Python/bytecodes.c"
             assert(kwnames == NULL);
             assert(oparg == 0 || oparg == 1);
             int is_meth = method != NULL;
@@ -4245,7 +4353,7 @@
             Py_DECREF(self);
             Py_DECREF(callable);
             if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; }
-            #line 4249 "Python/generated_cases.c.h"
+            #line 4357 "Python/generated_cases.c.h"
             STACK_SHRINK(oparg);
             STACK_SHRINK(1);
             stack_pointer[-1] = res;
@@ -4258,7 +4366,7 @@
             PyObject **args = (stack_pointer - oparg);
             PyObject *method = stack_pointer[-(2 + oparg)];
             PyObject *res;
-            #line 3063 "Python/bytecodes.c"
+            #line 3082 "Python/bytecodes.c"
             assert(kwnames == NULL);
             int is_meth = method != NULL;
             int total_args = oparg;
@@ -4286,7 +4394,7 @@
             }
             Py_DECREF(callable);
             if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; }
-            #line 4290 "Python/generated_cases.c.h"
+            #line 4398 "Python/generated_cases.c.h"
             STACK_SHRINK(oparg);
             STACK_SHRINK(1);
             stack_pointer[-1] = res;
@@ -4296,9 +4404,9 @@
         }
 
         TARGET(INSTRUMENTED_CALL_FUNCTION_EX) {
-            #line 3094 "Python/bytecodes.c"
+            #line 3113 "Python/bytecodes.c"
             GO_TO_INSTRUCTION(CALL_FUNCTION_EX);
-            #line 4302 "Python/generated_cases.c.h"
+            #line 4410 "Python/generated_cases.c.h"
         }
 
         TARGET(CALL_FUNCTION_EX) {
@@ -4307,7 +4415,7 @@
             PyObject *callargs = stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))];
             PyObject *func = stack_pointer[-(2 + ((oparg & 1) ? 1 : 0))];
             PyObject *result;
-            #line 3098 "Python/bytecodes.c"
+            #line 3117 "Python/bytecodes.c"
             // DICT_MERGE is called before this opcode if there are kwargs.
             // It converts all dict subtypes in kwargs into regular dicts.
             assert(kwargs == NULL || PyDict_CheckExact(kwargs));
@@ -4369,14 +4477,14 @@
                 }
                 result = PyObject_Call(func, callargs, kwargs);
             }
-            #line 4373 "Python/generated_cases.c.h"
+            #line 4481 "Python/generated_cases.c.h"
             Py_DECREF(func);
             Py_DECREF(callargs);
             Py_XDECREF(kwargs);
-            #line 3160 "Python/bytecodes.c"
+            #line 3179 "Python/bytecodes.c"
             assert(PEEK(3 + (oparg & 1)) == NULL);
             if (result == NULL) { STACK_SHRINK(((oparg & 1) ? 1 : 0)); goto pop_3_error; }
-            #line 4380 "Python/generated_cases.c.h"
+            #line 4488 "Python/generated_cases.c.h"
             STACK_SHRINK(((oparg & 1) ? 1 : 0));
             STACK_SHRINK(2);
             stack_pointer[-1] = result;
@@ -4391,7 +4499,7 @@
             PyObject *kwdefaults = (oparg & 0x02) ? stack_pointer[-(1 + ((oparg & 0x08) ? 1 : 0) + ((oparg & 0x04) ? 1 : 0) + ((oparg & 0x02) ? 1 : 0))] : NULL;
             PyObject *defaults = (oparg & 0x01) ? stack_pointer[-(1 + ((oparg & 0x08) ? 1 : 0) + ((oparg & 0x04) ? 1 : 0) + ((oparg & 0x02) ? 1 : 0) + ((oparg & 0x01) ? 1 : 0))] : NULL;
             PyObject *func;
-            #line 3170 "Python/bytecodes.c"
+            #line 3189 "Python/bytecodes.c"
 
             PyFunctionObject *func_obj = (PyFunctionObject *)
                 PyFunction_New(codeobj, GLOBALS());
@@ -4420,14 +4528,14 @@
 
             func_obj->func_version = ((PyCodeObject *)codeobj)->co_version;
             func = (PyObject *)func_obj;
-            #line 4424 "Python/generated_cases.c.h"
+            #line 4532 "Python/generated_cases.c.h"
             STACK_SHRINK(((oparg & 0x01) ? 1 : 0) + ((oparg & 0x02) ? 1 : 0) + ((oparg & 0x04) ? 1 : 0) + ((oparg & 0x08) ? 1 : 0));
             stack_pointer[-1] = func;
             DISPATCH();
         }
 
         TARGET(RETURN_GENERATOR) {
-            #line 3201 "Python/bytecodes.c"
+            #line 3220 "Python/bytecodes.c"
             assert(PyFunction_Check(frame->f_funcobj));
             PyFunctionObject *func = (PyFunctionObject *)frame->f_funcobj;
             PyGenObject *gen = (PyGenObject *)_Py_MakeCoro(func);
@@ -4448,7 +4556,7 @@
             frame = cframe.current_frame = prev;
             _PyFrame_StackPush(frame, (PyObject *)gen);
             goto resume_frame;
-            #line 4452 "Python/generated_cases.c.h"
+            #line 4560 "Python/generated_cases.c.h"
         }
 
         TARGET(BUILD_SLICE) {
@@ -4456,15 +4564,15 @@
             PyObject *stop = stack_pointer[-(1 + ((oparg == 3) ? 1 : 0))];
             PyObject *start = stack_pointer[-(2 + ((oparg == 3) ? 1 : 0))];
             PyObject *slice;
-            #line 3224 "Python/bytecodes.c"
+            #line 3243 "Python/bytecodes.c"
             slice = PySlice_New(start, stop, step);
-            #line 4462 "Python/generated_cases.c.h"
+            #line 4570 "Python/generated_cases.c.h"
             Py_DECREF(start);
             Py_DECREF(stop);
             Py_XDECREF(step);
-            #line 3226 "Python/bytecodes.c"
+            #line 3245 "Python/bytecodes.c"
             if (slice == NULL) { STACK_SHRINK(((oparg == 3) ? 1 : 0)); goto pop_2_error; }
-            #line 4468 "Python/generated_cases.c.h"
+            #line 4576 "Python/generated_cases.c.h"
             STACK_SHRINK(((oparg == 3) ? 1 : 0));
             STACK_SHRINK(1);
             stack_pointer[-1] = slice;
@@ -4475,7 +4583,7 @@
             PyObject *fmt_spec = ((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? stack_pointer[-((((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? 1 : 0))] : NULL;
             PyObject *value = stack_pointer[-(1 + (((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? 1 : 0))];
             PyObject *result;
-            #line 3230 "Python/bytecodes.c"
+            #line 3249 "Python/bytecodes.c"
             /* Handles f-string value formatting. */
             PyObject *(*conv_fn)(PyObject *);
             int which_conversion = oparg & FVC_MASK;
@@ -4510,7 +4618,7 @@
             Py_DECREF(value);
             Py_XDECREF(fmt_spec);
             if (result == NULL) { STACK_SHRINK((((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? 1 : 0)); goto pop_1_error; }
-            #line 4514 "Python/generated_cases.c.h"
+            #line 4622 "Python/generated_cases.c.h"
             STACK_SHRINK((((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? 1 : 0));
             stack_pointer[-1] = result;
             DISPATCH();
@@ -4519,10 +4627,10 @@
         TARGET(COPY) {
             PyObject *bottom = stack_pointer[-(1 + (oparg-1))];
             PyObject *top;
-            #line 3267 "Python/bytecodes.c"
+            #line 3286 "Python/bytecodes.c"
             assert(oparg > 0);
             top = Py_NewRef(bottom);
-            #line 4526 "Python/generated_cases.c.h"
+            #line 4634 "Python/generated_cases.c.h"
             STACK_GROW(1);
             stack_pointer[-1] = top;
             DISPATCH();
@@ -4534,7 +4642,7 @@
             PyObject *rhs = stack_pointer[-1];
             PyObject *lhs = stack_pointer[-2];
             PyObject *res;
-            #line 3272 "Python/bytecodes.c"
+            #line 3291 "Python/bytecodes.c"
             #if ENABLE_SPECIALIZATION
             _PyBinaryOpCache *cache = (_PyBinaryOpCache *)next_instr;
             if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
@@ -4549,12 +4657,12 @@
             assert((unsigned)oparg < Py_ARRAY_LENGTH(binary_ops));
             assert(binary_ops[oparg]);
             res = binary_ops[oparg](lhs, rhs);
-            #line 4553 "Python/generated_cases.c.h"
+            #line 4661 "Python/generated_cases.c.h"
             Py_DECREF(lhs);
             Py_DECREF(rhs);
-            #line 3287 "Python/bytecodes.c"
+            #line 3306 "Python/bytecodes.c"
             if (res == NULL) goto pop_2_error;
-            #line 4558 "Python/generated_cases.c.h"
+            #line 4666 "Python/generated_cases.c.h"
             STACK_SHRINK(1);
             stack_pointer[-1] = res;
             next_instr += 1;
@@ -4564,16 +4672,16 @@
         TARGET(SWAP) {
             PyObject *top = stack_pointer[-1];
             PyObject *bottom = stack_pointer[-(2 + (oparg-2))];
-            #line 3292 "Python/bytecodes.c"
+            #line 3311 "Python/bytecodes.c"
             assert(oparg >= 2);
-            #line 4570 "Python/generated_cases.c.h"
+            #line 4678 "Python/generated_cases.c.h"
             stack_pointer[-1] = bottom;
             stack_pointer[-(2 + (oparg-2))] = top;
             DISPATCH();
         }
 
         TARGET(INSTRUMENTED_INSTRUCTION) {
-            #line 3296 "Python/bytecodes.c"
+            #line 3315 "Python/bytecodes.c"
             int next_opcode = _Py_call_instrumentation_instruction(
                 tstate, frame, next_instr-1);
             if (next_opcode < 0) goto error;
@@ -4585,26 +4693,26 @@
             assert(next_opcode > 0 && next_opcode < 256);
             opcode = next_opcode;
             DISPATCH_GOTO();
-            #line 4589 "Python/generated_cases.c.h"
+            #line 4697 "Python/generated_cases.c.h"
         }
 
         TARGET(INSTRUMENTED_JUMP_FORWARD) {
-            #line 3310 "Python/bytecodes.c"
+            #line 3329 "Python/bytecodes.c"
             INSTRUMENTED_JUMP(next_instr-1, next_instr+oparg, PY_MONITORING_EVENT_JUMP);
-            #line 4595 "Python/generated_cases.c.h"
+            #line 4703 "Python/generated_cases.c.h"
             DISPATCH();
         }
 
         TARGET(INSTRUMENTED_JUMP_BACKWARD) {
-            #line 3314 "Python/bytecodes.c"
+            #line 3333 "Python/bytecodes.c"
             INSTRUMENTED_JUMP(next_instr-1, next_instr-oparg, PY_MONITORING_EVENT_JUMP);
-            #line 4602 "Python/generated_cases.c.h"
+            #line 4710 "Python/generated_cases.c.h"
             CHECK_EVAL_BREAKER();
             DISPATCH();
         }
 
         TARGET(INSTRUMENTED_POP_JUMP_IF_TRUE) {
-            #line 3319 "Python/bytecodes.c"
+            #line 3338 "Python/bytecodes.c"
             PyObject *cond = POP();
             int err = PyObject_IsTrue(cond);
             Py_DECREF(cond);
@@ -4613,12 +4721,12 @@
             assert(err == 0 || err == 1);
             int offset = err*oparg;
             INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH);
-            #line 4617 "Python/generated_cases.c.h"
+            #line 4725 "Python/generated_cases.c.h"
             DISPATCH();
         }
 
         TARGET(INSTRUMENTED_POP_JUMP_IF_FALSE) {
-            #line 3330 "Python/bytecodes.c"
+            #line 3349 "Python/bytecodes.c"
             PyObject *cond = POP();
             int err = PyObject_IsTrue(cond);
             Py_DECREF(cond);
@@ -4627,12 +4735,12 @@
             assert(err == 0 || err == 1);
             int offset = (1-err)*oparg;
             INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH);
-            #line 4631 "Python/generated_cases.c.h"
+            #line 4739 "Python/generated_cases.c.h"
             DISPATCH();
         }
 
         TARGET(INSTRUMENTED_POP_JUMP_IF_NONE) {
-            #line 3341 "Python/bytecodes.c"
+            #line 3360 "Python/bytecodes.c"
             PyObject *value = POP();
             _Py_CODEUNIT *here = next_instr-1;
             int offset;
@@ -4645,12 +4753,12 @@
                 offset = 0;
             }
             INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH);
-            #line 4649 "Python/generated_cases.c.h"
+            #line 4757 "Python/generated_cases.c.h"
             DISPATCH();
         }
 
         TARGET(INSTRUMENTED_POP_JUMP_IF_NOT_NONE) {
-            #line 3356 "Python/bytecodes.c"
+            #line 3375 "Python/bytecodes.c"
             PyObject *value = POP();
             _Py_CODEUNIT *here = next_instr-1;
             int offset;
@@ -4663,30 +4771,30 @@
                  offset = oparg;
             }
             INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH);
-            #line 4667 "Python/generated_cases.c.h"
+            #line 4775 "Python/generated_cases.c.h"
             DISPATCH();
         }
 
         TARGET(EXTENDED_ARG) {
-            #line 3371 "Python/bytecodes.c"
+            #line 3390 "Python/bytecodes.c"
             assert(oparg);
             opcode = next_instr->op.code;
             oparg = oparg << 8 | next_instr->op.arg;
             PRE_DISPATCH_GOTO();
             DISPATCH_GOTO();
-            #line 4678 "Python/generated_cases.c.h"
+            #line 4786 "Python/generated_cases.c.h"
         }
 
         TARGET(CACHE) {
-            #line 3379 "Python/bytecodes.c"
+            #line 3398 "Python/bytecodes.c"
             assert(0 && "Executing a cache.");
             Py_UNREACHABLE();
-            #line 4685 "Python/generated_cases.c.h"
+            #line 4793 "Python/generated_cases.c.h"
         }
 
         TARGET(RESERVED) {
-            #line 3384 "Python/bytecodes.c"
+            #line 3403 "Python/bytecodes.c"
             assert(0 && "Executing RESERVED instruction.");
             Py_UNREACHABLE();
-            #line 4692 "Python/generated_cases.c.h"
+            #line 4800 "Python/generated_cases.c.h"
         }
diff --git a/Python/intrinsics.c b/Python/intrinsics.c
index cca29d859902..c6f5ac5402d6 100644
--- a/Python/intrinsics.c
+++ b/Python/intrinsics.c
@@ -3,10 +3,12 @@
 
 #include "Python.h"
 #include "pycore_frame.h"
+#include "pycore_function.h"
 #include "pycore_runtime.h"
 #include "pycore_global_objects.h"
 #include "pycore_intrinsics.h"
 #include "pycore_pyerrors.h"
+#include "pycore_typevarobject.h"
 
 
 /******** Unary functions ********/
@@ -199,6 +201,13 @@ list_to_tuple(PyThreadState* unused, PyObject *v)
     return _PyTuple_FromArray(((PyListObject *)v)->ob_item, Py_SIZE(v));
 }
 
+static PyObject *
+make_typevar(PyThreadState* Py_UNUSED(ignored), PyObject *v)
+{
+    assert(PyUnicode_Check(v));
+    return _Py_make_typevar(v, NULL, NULL);
+}
+
 const instrinsic_func1
 _PyIntrinsics_UnaryFunctions[] = {
     [0] = no_intrinsic,
@@ -208,6 +217,11 @@ _PyIntrinsics_UnaryFunctions[] = {
     [INTRINSIC_ASYNC_GEN_WRAP] = _PyAsyncGenValueWrapperNew,
     [INTRINSIC_UNARY_POSITIVE] = unary_pos,
     [INTRINSIC_LIST_TO_TUPLE] = list_to_tuple,
+    [INTRINSIC_TYPEVAR] = make_typevar,
+    [INTRINSIC_PARAMSPEC] = _Py_make_paramspec,
+    [INTRINSIC_TYPEVARTUPLE] = _Py_make_typevartuple,
+    [INTRINSIC_SUBSCRIPT_GENERIC] = _Py_subscript_generic,
+    [INTRINSIC_TYPEALIAS] = _Py_make_typealias,
 };
 
 
@@ -221,8 +235,26 @@ prep_reraise_star(PyThreadState* unused, PyObject *orig, PyObject *excs)
     return _PyExc_PrepReraiseStar(orig, excs);
 }
 
+static PyObject *
+make_typevar_with_bound(PyThreadState* Py_UNUSED(ignored), PyObject *name,
+                        PyObject *evaluate_bound)
+{
+    assert(PyUnicode_Check(name));
+    return _Py_make_typevar(name, evaluate_bound, NULL);
+}
+
+static PyObject *
+make_typevar_with_constraints(PyThreadState* Py_UNUSED(ignored), PyObject *name,
+                              PyObject *evaluate_constraints)
+{
+    assert(PyUnicode_Check(name));
+    return _Py_make_typevar(name, NULL, evaluate_constraints);
+}
+
 const instrinsic_func2
 _PyIntrinsics_BinaryFunctions[] = {
     [INTRINSIC_PREP_RERAISE_STAR] = prep_reraise_star,
+    [INTRINSIC_TYPEVAR_WITH_BOUND] = make_typevar_with_bound,
+    [INTRINSIC_TYPEVAR_WITH_CONSTRAINTS] = make_typevar_with_constraints,
+    [INTRINSIC_SET_FUNCTION_TYPE_PARAMS] = _Py_set_function_type_params,
 };
-
diff --git a/Python/opcode_metadata.h b/Python/opcode_metadata.h
index ae68e045a611..601ad3874b79 100644
--- a/Python/opcode_metadata.h
+++ b/Python/opcode_metadata.h
@@ -161,8 +161,12 @@ _PyOpcode_num_popped(int opcode, int oparg, bool jump) {
             return 1;
         case DELETE_GLOBAL:
             return 0;
-        case LOAD_NAME:
+        case LOAD_LOCALS:
             return 0;
+        case LOAD_NAME:
+            return 0+1;
+        case LOAD_FROM_DICT_OR_GLOBALS:
+            return 1;
         case LOAD_GLOBAL:
             return 0;
         case LOAD_GLOBAL_MODULE:
@@ -175,8 +179,8 @@ _PyOpcode_num_popped(int opcode, int oparg, bool jump) {
             return 0;
         case DELETE_DEREF:
             return 0;
-        case LOAD_CLASSDEREF:
-            return 0;
+        case LOAD_FROM_DICT_OR_DEREF:
+            return 1;
         case LOAD_DEREF:
             return 0;
         case STORE_DEREF:
@@ -551,7 +555,11 @@ _PyOpcode_num_pushed(int opcode, int oparg, bool jump) {
             return 0;
         case DELETE_GLOBAL:
             return 0;
+        case LOAD_LOCALS:
+            return 1;
         case LOAD_NAME:
+            return 1+1;
+        case LOAD_FROM_DICT_OR_GLOBALS:
             return 1;
         case LOAD_GLOBAL:
             return ((oparg & 1) ? 1 : 0) + 1;
@@ -565,7 +573,7 @@ _PyOpcode_num_pushed(int opcode, int oparg, bool jump) {
             return 0;
         case DELETE_DEREF:
             return 0;
-        case LOAD_CLASSDEREF:
+        case LOAD_FROM_DICT_OR_DEREF:
             return 1;
         case LOAD_DEREF:
             return 1;
@@ -869,14 +877,16 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[256] = {
     [DELETE_ATTR] = { true, INSTR_FMT_IB },
     [STORE_GLOBAL] = { true, INSTR_FMT_IB },
     [DELETE_GLOBAL] = { true, INSTR_FMT_IB },
+    [LOAD_LOCALS] = { true, INSTR_FMT_IB },
     [LOAD_NAME] = { true, INSTR_FMT_IB },
+    [LOAD_FROM_DICT_OR_GLOBALS] = { true, INSTR_FMT_IB },
     [LOAD_GLOBAL] = { true, INSTR_FMT_IBC000 },
     [LOAD_GLOBAL_MODULE] = { true, INSTR_FMT_IBC000 },
     [LOAD_GLOBAL_BUILTIN] = { true, INSTR_FMT_IBC000 },
     [DELETE_FAST] = { true, INSTR_FMT_IB },
     [MAKE_CELL] = { true, INSTR_FMT_IB },
     [DELETE_DEREF] = { true, INSTR_FMT_IB },
-    [LOAD_CLASSDEREF] = { true, INSTR_FMT_IB },
+    [LOAD_FROM_DICT_OR_DEREF] = { true, INSTR_FMT_IB },
     [LOAD_DEREF] = { true, INSTR_FMT_IB },
     [STORE_DEREF] = { true, INSTR_FMT_IB },
     [COPY_FREE_VARS] = { true, INSTR_FMT_IB },
diff --git a/Python/opcode_targets.h b/Python/opcode_targets.h
index f2742f4ad1f2..af05a33058f3 100644
--- a/Python/opcode_targets.h
+++ b/Python/opcode_targets.h
@@ -86,8 +86,8 @@ static void *opcode_targets[256] = {
     &&TARGET_LOAD_CONST__LOAD_FAST,
     &&TARGET_SETUP_ANNOTATIONS,
     &&TARGET_LOAD_FAST__LOAD_CONST,
+    &&TARGET_LOAD_LOCALS,
     &&TARGET_LOAD_FAST__LOAD_FAST,
-    &&TARGET_LOAD_GLOBAL_BUILTIN,
     &&TARGET_POP_EXCEPT,
     &&TARGET_STORE_NAME,
     &&TARGET_DELETE_NAME,
@@ -110,9 +110,9 @@ static void *opcode_targets[256] = {
     &&TARGET_IMPORT_NAME,
     &&TARGET_IMPORT_FROM,
     &&TARGET_JUMP_FORWARD,
+    &&TARGET_LOAD_GLOBAL_BUILTIN,
     &&TARGET_LOAD_GLOBAL_MODULE,
     &&TARGET_STORE_ATTR_INSTANCE_VALUE,
-    &&TARGET_STORE_ATTR_SLOT,
     &&TARGET_POP_JUMP_IF_FALSE,
     &&TARGET_POP_JUMP_IF_TRUE,
     &&TARGET_LOAD_GLOBAL,
@@ -147,7 +147,7 @@ static void *opcode_targets[256] = {
     &&TARGET_LIST_APPEND,
     &&TARGET_SET_ADD,
     &&TARGET_MAP_ADD,
-    &&TARGET_LOAD_CLASSDEREF,
+    &&TARGET_STORE_ATTR_SLOT,
     &&TARGET_COPY_FREE_VARS,
     &&TARGET_YIELD_VALUE,
     &&TARGET_RESUME,
@@ -174,8 +174,8 @@ static void *opcode_targets[256] = {
     &&TARGET_KW_NAMES,
     &&TARGET_CALL_INTRINSIC_1,
     &&TARGET_CALL_INTRINSIC_2,
-    &&_unknown_opcode,
-    &&_unknown_opcode,
+    &&TARGET_LOAD_FROM_DICT_OR_GLOBALS,
+    &&TARGET_LOAD_FROM_DICT_OR_DEREF,
     &&_unknown_opcode,
     &&_unknown_opcode,
     &&_unknown_opcode,
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
index cb87f2c08601..740901f53d2d 100644
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -26,6 +26,7 @@
 #include "pycore_sysmodule.h"     // _PySys_ClearAuditHooks()
 #include "pycore_traceback.h"     // _Py_DumpTracebackThreads()
 #include "pycore_typeobject.h"    // _PyTypes_InitTypes()
+#include "pycore_typevarobject.h" // _Py_clear_generic_types()
 #include "pycore_unicodeobject.h" // _PyUnicode_InitTypes()
 #include "opcode.h"
 
@@ -1698,6 +1699,7 @@ finalize_interp_clear(PyThreadState *tstate)
     int is_main_interp = _Py_IsMainInterpreter(tstate->interp);
 
     _PyExc_ClearExceptionGroupType(tstate->interp);
+    _Py_clear_generic_types(tstate->interp);
 
     /* Clear interpreter state and all thread states */
     _PyInterpreterState_Clear(tstate);
diff --git a/Python/symtable.c b/Python/symtable.c
index 2c29f6084135..3451f6c7bffb 100644
--- a/Python/symtable.c
+++ b/Python/symtable.c
@@ -47,6 +47,18 @@
 #define ANNOTATION_NOT_ALLOWED \
 "'%s' can not be used within an annotation"
 
+#define TYPEVAR_BOUND_NOT_ALLOWED \
+"'%s' can not be used within a TypeVar bound"
+
+#define TYPEALIAS_NOT_ALLOWED \
+"'%s' can not be used within a type alias"
+
+#define TYPEPARAM_NOT_ALLOWED \
+"'%s' can not be used within the definition of a generic"
+
+#define DUPLICATE_TYPE_PARAM \
+"duplicate type parameter '%U'"
+
 
 #define LOCATION(x) \
  (x)->lineno, (x)->col_offset, (x)->end_lineno, (x)->end_col_offset
@@ -95,7 +107,7 @@ ste_new(struct symtable *st, identifier name, _Py_block_ty block,
 
     if (st->st_cur != NULL &&
         (st->st_cur->ste_nested ||
-         st->st_cur->ste_type == FunctionBlock))
+         _PyST_IsFunctionLike(st->st_cur)))
         ste->ste_nested = 1;
     ste->ste_child_free = 0;
     ste->ste_generator = 0;
@@ -105,7 +117,9 @@ ste_new(struct symtable *st, identifier name, _Py_block_ty block,
     ste->ste_needs_class_closure = 0;
     ste->ste_comp_inlined = 0;
     ste->ste_comp_iter_target = 0;
+    ste->ste_can_see_class_scope = 0;
     ste->ste_comp_iter_expr = 0;
+    ste->ste_needs_classdict = 0;
 
     ste->ste_symbols = PyDict_New();
     ste->ste_varnames = PyList_New(0);
@@ -208,6 +222,7 @@ static int symtable_enter_block(struct symtable *st, identifier name,
 static int symtable_exit_block(struct symtable *st);
 static int symtable_visit_stmt(struct symtable *st, stmt_ty s);
 static int symtable_visit_expr(struct symtable *st, expr_ty s);
+static int symtable_visit_typeparam(struct symtable *st, typeparam_ty s);
 static int symtable_visit_genexp(struct symtable *st, expr_ty s);
 static int symtable_visit_listcomp(struct symtable *st, expr_ty s);
 static int symtable_visit_setcomp(struct symtable *st, expr_ty s);
@@ -403,6 +418,15 @@ _PyST_GetScope(PySTEntryObject *ste, PyObject *name)
     return (symbol >> SCOPE_OFFSET) & SCOPE_MASK;
 }
 
+int
+_PyST_IsFunctionLike(PySTEntryObject *ste)
+{
+    return ste->ste_type == FunctionBlock
+        || ste->ste_type == TypeVarBoundBlock
+        || ste->ste_type == TypeAliasBlock
+        || ste->ste_type == TypeParamBlock;
+}
+
 static int
 error_at_directive(PySTEntryObject *ste, PyObject *name)
 {
@@ -495,7 +519,7 @@ error_at_directive(PySTEntryObject *ste, PyObject *name)
 static int
 analyze_name(PySTEntryObject *ste, PyObject *scopes, PyObject *name, long flags,
              PyObject *bound, PyObject *local, PyObject *free,
-             PyObject *global)
+             PyObject *global, PyObject *typeparams, PySTEntryObject *class_entry)
 {
     if (flags & DEF_GLOBAL) {
         if (flags & DEF_NONLOCAL) {
@@ -524,6 +548,12 @@ analyze_name(PySTEntryObject *ste, PyObject *scopes, PyObject *name, long flags,
 
             return error_at_directive(ste, name);
         }
+        if (PySet_Contains(typeparams, name)) {
+            PyErr_Format(PyExc_SyntaxError,
+                         "nonlocal binding not allowed for type parameter '%U'",
+                         name);
+            return error_at_directive(ste, name);
+        }
         SET_SCOPE(scopes, name, FREE);
         ste->ste_free = 1;
         return PySet_Add(free, name) >= 0;
@@ -534,8 +564,34 @@ analyze_name(PySTEntryObject *ste, PyObject *scopes, PyObject *name, long flags,
             return 0;
         if (PySet_Discard(global, name) < 0)
             return 0;
+        if (flags & DEF_TYPE_PARAM) {
+            if (PySet_Add(typeparams, name) < 0)
+                return 0;
+        }
+        else {
+            if (PySet_Discard(typeparams, name) < 0)
+                return 0;
+        }
         return 1;
     }
+    // If we were passed class_entry (i.e., we're in an ste_can_see_class_scope scope)
+    // and the bound name is in that set, then the name is potentially bound both by
+    // the immediately enclosing class namespace, and also by an outer function namespace.
+    // In that case, we want the runtime name resolution to look at only the class
+    // namespace and the globals (not the namespace providing the bound).
+    // Similarly, if the name is explicitly global in the class namespace (through the
+    // global statement), we want to also treat it as a global in this scope.
+    if (class_entry != NULL) {
+        long class_flags = _PyST_GetSymbol(class_entry, name);
+        if (class_flags & DEF_GLOBAL) {
+            SET_SCOPE(scopes, name, GLOBAL_EXPLICIT);
+            return 1;
+        }
+        else if (class_flags & DEF_BOUND && !(class_flags & DEF_NONLOCAL)) {
+            SET_SCOPE(scopes, name, GLOBAL_IMPLICIT);
+            return 1;
+        }
+    }
     /* If an enclosing block has a binding for this name, it
        is a free variable rather than a global variable.
        Note that having a non-NULL bound implies that the block
@@ -611,7 +667,7 @@ inline_comprehension(PySTEntryObject *ste, PySTEntryObject *comp,
             if (PyLong_AsLong(existing) & DEF_BOUND) {
                 // cell vars in comprehension that are locals in outer scope
                 // must be promoted to cell so u_cellvars isn't wrong
-                if (scope == CELL && ste->ste_type == FunctionBlock) {
+                if (scope == CELL && _PyST_IsFunctionLike(ste)) {
                     if (PySet_Add(promote_to_cell, k) < 0) {
                         return 0;
                     }
@@ -682,6 +738,11 @@ drop_class_free(PySTEntryObject *ste, PyObject *free)
         return 0;
     if (res)
         ste->ste_needs_class_closure = 1;
+    res = PySet_Discard(free, &_Py_ID(__classdict__));
+    if (res < 0)
+        return 0;
+    if (res)
+        ste->ste_needs_classdict = 1;
     return 1;
 }
 
@@ -799,11 +860,13 @@ update_symbols(PyObject *symbols, PyObject *scopes,
 
 static int
 analyze_child_block(PySTEntryObject *entry, PyObject *bound, PyObject *free,
-                    PyObject *global, PyObject **child_free);
+                    PyObject *global, PyObject *typeparams,
+                    PySTEntryObject *class_entry, PyObject **child_free);
 
 static int
 analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free,
-              PyObject *global)
+              PyObject *global, PyObject *typeparams,
+              PySTEntryObject *class_entry)
 {
     PyObject *name, *v, *local = NULL, *scopes = NULL, *newbound = NULL;
     PyObject *newglobal = NULL, *newfree = NULL, *promote_to_cell = NULL;
@@ -865,14 +928,14 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free,
     while (PyDict_Next(ste->ste_symbols, &pos, &name, &v)) {
         long flags = PyLong_AS_LONG(v);
         if (!analyze_name(ste, scopes, name, flags,
-                          bound, local, free, global))
+                          bound, local, free, global, typeparams, class_entry))
             goto error;
     }
 
     /* Populate global and bound sets to be passed to children. */
     if (ste->ste_type != ClassBlock) {
         /* Add function locals to bound set */
-        if (ste->ste_type == FunctionBlock) {
+        if (_PyST_IsFunctionLike(ste)) {
             temp = PyNumber_InPlaceOr(newbound, local);
             if (!temp)
                 goto error;
@@ -892,9 +955,11 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free,
         Py_DECREF(temp);
     }
     else {
-        /* Special-case __class__ */
+        /* Special-case __class__ and __classdict__ */
         if (PySet_Add(newbound, &_Py_ID(__class__)) < 0)
             goto error;
+        if (PySet_Add(newbound, &_Py_ID(__classdict__)) < 0)
+            goto error;
     }
 
     /* Recursively call analyze_child_block() on each child block.
@@ -910,13 +975,23 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free,
         assert(c && PySTEntry_Check(c));
         entry = (PySTEntryObject*)c;
 
+        PySTEntryObject *new_class_entry = NULL;
+        if (entry->ste_can_see_class_scope) {
+            if (ste->ste_type == ClassBlock) {
+                new_class_entry = ste;
+            }
+            else if (class_entry) {
+                new_class_entry = class_entry;
+            }
+        }
+
         // we inline all non-generator-expression comprehensions
         int inline_comp =
             entry->ste_comprehension &&
             !entry->ste_generator;
 
         if (!analyze_child_block(entry, newbound, newfree, newglobal,
-                                 &child_free))
+                                 typeparams, new_class_entry, &child_free))
         {
             goto error;
         }
@@ -952,7 +1027,7 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free,
     }
 
     /* Check if any local variables must be converted to cell variables */
-    if (ste->ste_type == FunctionBlock && !analyze_cells(scopes, newfree, promote_to_cell))
+    if (_PyST_IsFunctionLike(ste) && !analyze_cells(scopes, newfree, promote_to_cell))
         goto error;
     else if (ste->ste_type == ClassBlock && !drop_class_free(ste, newfree))
         goto error;
@@ -980,9 +1055,11 @@ analyze_block(PySTEntryObject *ste, PyObject *bound, PyObject *free,
 
 static int
 analyze_child_block(PySTEntryObject *entry, PyObject *bound, PyObject *free,
-                    PyObject *global, PyObject** child_free)
+                    PyObject *global, PyObject *typeparams,
+                    PySTEntryObject *class_entry, PyObject** child_free)
 {
     PyObject *temp_bound = NULL, *temp_global = NULL, *temp_free = NULL;
+    PyObject *temp_typeparams = NULL;
 
     /* Copy the bound/global/free sets.
 
@@ -1000,24 +1077,30 @@ analyze_child_block(PySTEntryObject *entry, PyObject *bound, PyObject *free,
     temp_global = PySet_New(global);
     if (!temp_global)
         goto error;
+    temp_typeparams = PySet_New(typeparams);
+    if (!temp_typeparams)
+        goto error;
 
-    if (!analyze_block(entry, temp_bound, temp_free, temp_global))
+    if (!analyze_block(entry, temp_bound, temp_free, temp_global,
+                       temp_typeparams, class_entry))
         goto error;
     *child_free = temp_free;
     Py_DECREF(temp_bound);
     Py_DECREF(temp_global);
+    Py_DECREF(temp_typeparams);
     return 1;
  error:
     Py_XDECREF(temp_bound);
     Py_XDECREF(temp_free);
     Py_XDECREF(temp_global);
+    Py_XDECREF(temp_typeparams);
     return 0;
 }
 
 static int
 symtable_analyze(struct symtable *st)
 {
-    PyObject *free, *global;
+    PyObject *free, *global, *typeparams;
     int r;
 
     free = PySet_New(NULL);
@@ -1028,9 +1111,16 @@ symtable_analyze(struct symtable *st)
         Py_DECREF(free);
         return 0;
     }
-    r = analyze_block(st->st_top, NULL, free, global);
+    typeparams = PySet_New(NULL);
+    if (!typeparams) {
+        Py_DECREF(free);
+        Py_DECREF(global);
+        return 0;
+    }
+    r = analyze_block(st->st_top, NULL, free, global, typeparams, NULL);
     Py_DECREF(free);
     Py_DECREF(global);
+    Py_DECREF(typeparams);
     return r;
 }
 
@@ -1133,6 +1223,13 @@ symtable_add_def_helper(struct symtable *st, PyObject *name, int flag, struct _s
                                              end_lineno, end_col_offset + 1);
             goto error;
         }
+        if ((flag & DEF_TYPE_PARAM) && (val & DEF_TYPE_PARAM)) {
+            PyErr_Format(PyExc_SyntaxError, DUPLICATE_TYPE_PARAM, name);
+            PyErr_RangedSyntaxLocationObject(st->st_filename,
+                                             lineno, col_offset + 1,
+                                             end_lineno, end_col_offset + 1);
+            goto error;
+        }
         val |= flag;
     }
     else if (PyErr_Occurred()) {
@@ -1204,6 +1301,65 @@ symtable_add_def(struct symtable *st, PyObject *name, int flag,
                         lineno, col_offset, end_lineno, end_col_offset);
 }
 
+static int
+symtable_enter_typeparam_block(struct symtable *st, identifier name,
+                               void *ast, int has_defaults, int has_kwdefaults,
+                               enum _stmt_kind kind,
+                               int lineno, int col_offset,
+                               int end_lineno, int end_col_offset)
+{
+    _Py_block_ty current_type = st->st_cur->ste_type;
+    if(!symtable_enter_block(st, name, TypeParamBlock, ast, lineno,
+                             col_offset, end_lineno, end_col_offset)) {
+        return 0;
+    }
+    if (current_type == ClassBlock) {
+        st->st_cur->ste_can_see_class_scope = 1;
+        if (!symtable_add_def(st, &_Py_ID(__classdict__), USE, lineno, col_offset, end_lineno, end_col_offset)) {
+            return 0;
+        }
+    }
+    if (kind == ClassDef_kind) {
+        _Py_DECLARE_STR(type_params, ".type_params");
+        // It gets "set" when we create the type params tuple and
+        // "used" when we build up the bases.
+        if (!symtable_add_def(st, &_Py_STR(type_params), DEF_LOCAL,
+                              lineno, col_offset, end_lineno, end_col_offset)) {
+            return 0;
+        }
+        if (!symtable_add_def(st, &_Py_STR(type_params), USE,
+                              lineno, col_offset, end_lineno, end_col_offset)) {
+            return 0;
+        }
+        st->st_private = name;
+        // This is used for setting the generic base
+        _Py_DECLARE_STR(generic_base, ".generic_base");
+        if (!symtable_add_def(st, &_Py_STR(generic_base), DEF_LOCAL,
+                              lineno, col_offset, end_lineno, end_col_offset)) {
+            return 0;
+        }
+        if (!symtable_add_def(st, &_Py_STR(generic_base), USE,
+                              lineno, col_offset, end_lineno, end_col_offset)) {
+            return 0;
+        }
+    }
+    if (has_defaults) {
+        _Py_DECLARE_STR(defaults, ".defaults");
+        if (!symtable_add_def(st, &_Py_STR(defaults), DEF_PARAM,
+                              lineno, col_offset, end_lineno, end_col_offset)) {
+            return 0;
+        }
+    }
+    if (has_kwdefaults) {
+        _Py_DECLARE_STR(kwdefaults, ".kwdefaults");
+        if (!symtable_add_def(st, &_Py_STR(kwdefaults), DEF_PARAM,
+                              lineno, col_offset, end_lineno, end_col_offset)) {
+            return 0;
+        }
+    }
+    return 1;
+}
+
 /* VISIT, VISIT_SEQ and VIST_SEQ_TAIL take an ASDL type as their second argument.
    They use the ASDL name to synthesize the name of the C type and the visit
    function.
@@ -1275,6 +1431,17 @@ symtable_record_directive(struct symtable *st, identifier name, int lineno,
     return res == 0;
 }
 
+static int
+has_kwonlydefaults(asdl_arg_seq *kwonlyargs, asdl_expr_seq *kw_defaults)
+{
+    for (int i = 0; i < asdl_seq_LEN(kwonlyargs); i++) {
+        expr_ty default_ = asdl_seq_GET(kw_defaults, i);
+        if (default_) {
+            return 1;
+        }
+    }
+    return 0;
+}
 
 static int
 symtable_visit_stmt(struct symtable *st, stmt_ty s)
@@ -1292,11 +1459,24 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
             VISIT_SEQ(st, expr, s->v.FunctionDef.args->defaults);
         if (s->v.FunctionDef.args->kw_defaults)
             VISIT_SEQ_WITH_NULL(st, expr, s->v.FunctionDef.args->kw_defaults);
+        if (s->v.FunctionDef.decorator_list)
+            VISIT_SEQ(st, expr, s->v.FunctionDef.decorator_list);
+        if (asdl_seq_LEN(s->v.FunctionDef.typeparams) > 0) {
+            if (!symtable_enter_typeparam_block(
+                    st, s->v.FunctionDef.name,
+                    (void *)s->v.FunctionDef.typeparams,
+                    s->v.FunctionDef.args->defaults != NULL,
+                    has_kwonlydefaults(s->v.FunctionDef.args->kwonlyargs,
+                                       s->v.FunctionDef.args->kw_defaults),
+                    s->kind,
+                    LOCATION(s))) {
+                VISIT_QUIT(st, 0);
+            }
+            VISIT_SEQ(st, typeparam, s->v.FunctionDef.typeparams);
+        }
         if (!symtable_visit_annotations(st, s, s->v.FunctionDef.args,
                                         s->v.FunctionDef.returns))
             VISIT_QUIT(st, 0);
-        if (s->v.FunctionDef.decorator_list)
-            VISIT_SEQ(st, expr, s->v.FunctionDef.decorator_list);
         if (!symtable_enter_block(st, s->v.FunctionDef.name,
                                   FunctionBlock, (void *)s,
                                   LOCATION(s)))
@@ -1305,25 +1485,85 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
         VISIT_SEQ(st, stmt, s->v.FunctionDef.body);
         if (!symtable_exit_block(st))
             VISIT_QUIT(st, 0);
+        if (asdl_seq_LEN(s->v.FunctionDef.typeparams) > 0) {
+            if (!symtable_exit_block(st))
+                VISIT_QUIT(st, 0);
+        }
         break;
     case ClassDef_kind: {
         PyObject *tmp;
         if (!symtable_add_def(st, s->v.ClassDef.name, DEF_LOCAL, LOCATION(s)))
             VISIT_QUIT(st, 0);
-        VISIT_SEQ(st, expr, s->v.ClassDef.bases);
-        VISIT_SEQ(st, keyword, s->v.ClassDef.keywords);
         if (s->v.ClassDef.decorator_list)
             VISIT_SEQ(st, expr, s->v.ClassDef.decorator_list);
+        if (asdl_seq_LEN(s->v.ClassDef.typeparams) > 0) {
+            if (!symtable_enter_typeparam_block(st, s->v.ClassDef.name,
+                                                (void *)s->v.ClassDef.typeparams,
+                                                false, false, s->kind,
+                                                LOCATION(s))) {
+                VISIT_QUIT(st, 0);
+            }
+            VISIT_SEQ(st, typeparam, s->v.ClassDef.typeparams);
+        }
+        VISIT_SEQ(st, expr, s->v.ClassDef.bases);
+        VISIT_SEQ(st, keyword, s->v.ClassDef.keywords);
         if (!symtable_enter_block(st, s->v.ClassDef.name, ClassBlock,
                                   (void *)s, s->lineno, s->col_offset,
                                   s->end_lineno, s->end_col_offset))
             VISIT_QUIT(st, 0);
         tmp = st->st_private;
         st->st_private = s->v.ClassDef.name;
+        if (asdl_seq_LEN(s->v.ClassDef.typeparams) > 0) {
+            if (!symtable_add_def(st, &_Py_ID(__type_params__),
+                                  DEF_LOCAL, LOCATION(s))) {
+                VISIT_QUIT(st, 0);
+            }
+            _Py_DECLARE_STR(type_params, ".type_params");
+            if (!symtable_add_def(st, &_Py_STR(type_params),
+                                  USE, LOCATION(s))) {
+                VISIT_QUIT(st, 0);
+            }
+        }
         VISIT_SEQ(st, stmt, s->v.ClassDef.body);
         st->st_private = tmp;
         if (!symtable_exit_block(st))
             VISIT_QUIT(st, 0);
+        if (asdl_seq_LEN(s->v.ClassDef.typeparams) > 0) {
+            if (!symtable_exit_block(st))
+                VISIT_QUIT(st, 0);
+        }
+        break;
+    }
+    case TypeAlias_kind: {
+        VISIT(st, expr, s->v.TypeAlias.name);
+        assert(s->v.TypeAlias.name->kind == Name_kind);
+        PyObject *name = s->v.TypeAlias.name->v.Name.id;
+        int is_in_class = st->st_cur->ste_type == ClassBlock;
+        int is_generic = asdl_seq_LEN(s->v.TypeAlias.typeparams) > 0;
+        if (is_generic) {
+            if (!symtable_enter_typeparam_block(
+                    st, name,
+                    (void *)s->v.TypeAlias.typeparams,
+                    false, false, s->kind,
+                    LOCATION(s))) {
+                VISIT_QUIT(st, 0);
+            }
+            VISIT_SEQ(st, typeparam, s->v.TypeAlias.typeparams);
+        }
+        if (!symtable_enter_block(st, name, TypeAliasBlock,
+                                  (void *)s, LOCATION(s)))
+            VISIT_QUIT(st, 0);
+        st->st_cur->ste_can_see_class_scope = is_in_class;
+        if (is_in_class && !symtable_add_def(st, &_Py_ID(__classdict__), USE, LOCATION(s->v.TypeAlias.value))) {
+            VISIT_QUIT(st, 0);
+        }
+        VISIT(st, expr, s->v.TypeAlias.value);
+        if (!symtable_exit_block(st))
+            VISIT_QUIT(st, 0);
+        if (is_generic) {
+            if (!symtable_exit_block(st))
+                VISIT_QUIT(st, 0);
+        }
         break;
     }
     case Return_kind:
@@ -1532,11 +1772,24 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
         if (s->v.AsyncFunctionDef.args->kw_defaults)
             VISIT_SEQ_WITH_NULL(st, expr,
                                 s->v.AsyncFunctionDef.args->kw_defaults);
+        if (s->v.AsyncFunctionDef.decorator_list)
+            VISIT_SEQ(st, expr, s->v.AsyncFunctionDef.decorator_list);
+        if (asdl_seq_LEN(s->v.AsyncFunctionDef.typeparams) > 0) {
+            if (!symtable_enter_typeparam_block(
+                    st, s->v.AsyncFunctionDef.name,
+                    (void *)s->v.AsyncFunctionDef.typeparams,
+                    s->v.AsyncFunctionDef.args->defaults != NULL,
+                    has_kwonlydefaults(s->v.AsyncFunctionDef.args->kwonlyargs,
+                                       s->v.AsyncFunctionDef.args->kw_defaults),
+                    s->kind,
+                    LOCATION(s))) {
+                VISIT_QUIT(st, 0);
+            }
+            VISIT_SEQ(st, typeparam, s->v.AsyncFunctionDef.typeparams);
+        }
         if (!symtable_visit_annotations(st, s, s->v.AsyncFunctionDef.args,
                                         s->v.AsyncFunctionDef.returns))
             VISIT_QUIT(st, 0);
-        if (s->v.AsyncFunctionDef.decorator_list)
-            VISIT_SEQ(st, expr, s->v.AsyncFunctionDef.decorator_list);
         if (!symtable_enter_block(st, s->v.AsyncFunctionDef.name,
                                   FunctionBlock, (void *)s,
                                   s->lineno, s->col_offset,
@@ -1547,6 +1800,10 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s)
         VISIT_SEQ(st, stmt, s->v.AsyncFunctionDef.body);
         if (!symtable_exit_block(st))
             VISIT_QUIT(st, 0);
+        if (asdl_seq_LEN(s->v.AsyncFunctionDef.typeparams) > 0) {
+            if (!symtable_exit_block(st))
+                VISIT_QUIT(st, 0);
+        }
         break;
     case AsyncWith_kind:
         VISIT_SEQ(st, withitem, s->v.AsyncWith.items);
@@ -1598,7 +1855,7 @@ symtable_extend_namedexpr_scope(struct symtable *st, expr_ty e)
         }
 
         /* If we find a FunctionBlock entry, add as GLOBAL/LOCAL or NONLOCAL/LOCAL */
-        if (ste->ste_type == FunctionBlock) {
+        if (_PyST_IsFunctionLike(ste)) {
             long target_in_scope = _PyST_GetSymbol(ste, target_name);
             if (target_in_scope & DEF_GLOBAL) {
                 if (!symtable_add_def(st, target_name, DEF_GLOBAL, LOCATION(e)))
@@ -1633,7 +1890,7 @@ symtable_extend_namedexpr_scope(struct symtable *st, expr_ty e)
         }
     }
 
-    /* We should always find either a FunctionBlock, ModuleBlock or ClassBlock
+    /* We should always find either a function-like block, ModuleBlock or ClassBlock
        and should never fall to this case
     */
     Py_UNREACHABLE();
@@ -1806,7 +2063,7 @@ symtable_visit_expr(struct symtable *st, expr_ty e)
             VISIT_QUIT(st, 0);
         /* Special-case super: it counts as a use of __class__ */
         if (e->v.Name.ctx == Load &&
-            st->st_cur->ste_type == FunctionBlock &&
+            _PyST_IsFunctionLike(st->st_cur) &&
             _PyUnicode_EqualToASCIIString(e->v.Name.id, "super")) {
             if (!symtable_add_def(st, &_Py_ID(__class__), USE, LOCATION(e)))
                 VISIT_QUIT(st, 0);
@@ -1823,6 +2080,45 @@ symtable_visit_expr(struct symtable *st, expr_ty e)
     VISIT_QUIT(st, 1);
 }
 
+static int
+symtable_visit_typeparam(struct symtable *st, typeparam_ty tp)
+{
+    if (++st->recursion_depth > st->recursion_limit) {
+        PyErr_SetString(PyExc_RecursionError,
+                        "maximum recursion depth exceeded during compilation");
+        VISIT_QUIT(st, 0);
+    }
+    switch(tp->kind) {
+    case TypeVar_kind:
+        if (!symtable_add_def(st, tp->v.TypeVar.name, DEF_TYPE_PARAM | DEF_LOCAL, LOCATION(tp)))
+            VISIT_QUIT(st, 0);
+        if (tp->v.TypeVar.bound) {
+            int is_in_class = st->st_cur->ste_can_see_class_scope;
+            if (!symtable_enter_block(st, tp->v.TypeVar.name,
+                                      TypeVarBoundBlock, (void *)tp,
+                                      LOCATION(tp)))
+                VISIT_QUIT(st, 0);
+            st->st_cur->ste_can_see_class_scope = is_in_class;
+            if (is_in_class && !symtable_add_def(st, &_Py_ID(__classdict__), USE, LOCATION(tp->v.TypeVar.bound))) {
+                VISIT_QUIT(st, 0);
+            }
+            VISIT(st, expr, tp->v.TypeVar.bound);
+            if (!symtable_exit_block(st))
+                VISIT_QUIT(st, 0);
+        }
+        break;
+    case TypeVarTuple_kind:
+        if (!symtable_add_def(st, tp->v.TypeVarTuple.name, DEF_TYPE_PARAM | DEF_LOCAL, LOCATION(tp)))
+            VISIT_QUIT(st, 0);
+        break;
+    case ParamSpec_kind:
+        if (!symtable_add_def(st, tp->v.ParamSpec.name, DEF_TYPE_PARAM | DEF_LOCAL, LOCATION(tp)))
+            VISIT_QUIT(st, 0);
+        break;
+    }
+    VISIT_QUIT(st, 1);
+}
+
 static int
 symtable_visit_pattern(struct symtable *st, pattern_ty p)
 {
@@ -2194,11 +2490,18 @@ symtable_visit_dictcomp(struct symtable *st, expr_ty e)
 static int
 symtable_raise_if_annotation_block(struct symtable *st, const char *name, expr_ty e)
 {
-    if (st->st_cur->ste_type != AnnotationBlock) {
+    enum _block_type type = st->st_cur->ste_type;
+    if (type == AnnotationBlock)
+        PyErr_Format(PyExc_SyntaxError, ANNOTATION_NOT_ALLOWED, name);
+    else if (type == TypeVarBoundBlock)
+        PyErr_Format(PyExc_SyntaxError, TYPEVAR_BOUND_NOT_ALLOWED, name);
+    else if (type == TypeAliasBlock)
+        PyErr_Format(PyExc_SyntaxError, TYPEALIAS_NOT_ALLOWED, name);
+    else if (type == TypeParamBlock)
+        PyErr_Format(PyExc_SyntaxError, TYPEPARAM_NOT_ALLOWED, name);
+    else
         return 1;
-    }
 
-    PyErr_Format(PyExc_SyntaxError, ANNOTATION_NOT_ALLOWED, name);
     PyErr_RangedSyntaxLocationObject(st->st_filename,
                                      e->lineno,
                                      e->col_offset + 1,



More information about the Python-checkins mailing list