diff options
author | Brandt Bucher <brandtbucher@gmail.com> | 2021-02-26 22:51:55 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-02-26 22:51:55 (GMT) |
commit | 145bf269df3530176f6ebeab1324890ef7070bf8 (patch) | |
tree | 4c4928d6250785372171a52be0b7269aa444511b /Include | |
parent | cc02b4f2e810ab524d845daa18bc94df5b092dd8 (diff) | |
download | cpython-145bf269df3530176f6ebeab1324890ef7070bf8.zip cpython-145bf269df3530176f6ebeab1324890ef7070bf8.tar.gz cpython-145bf269df3530176f6ebeab1324890ef7070bf8.tar.bz2 |
bpo-42128: Structural Pattern Matching (PEP 634) (GH-22917)
Co-authored-by: Guido van Rossum <guido@python.org>
Co-authored-by: Talin <viridia@gmail.com>
Co-authored-by: Pablo Galindo <pablogsal@gmail.com>
Diffstat (limited to 'Include')
-rw-r--r-- | Include/Python-ast.h | 55 | ||||
-rw-r--r-- | Include/internal/pycore_ast.h | 10 | ||||
-rw-r--r-- | Include/internal/pycore_interp.h | 5 | ||||
-rw-r--r-- | Include/object.h | 5 | ||||
-rw-r--r-- | Include/opcode.h | 6 | ||||
-rw-r--r-- | Include/symtable.h | 1 |
6 files changed, 76 insertions, 6 deletions
diff --git a/Include/Python-ast.h b/Include/Python-ast.h index fc9f65c..bd127ca 100644 --- a/Include/Python-ast.h +++ b/Include/Python-ast.h @@ -44,6 +44,8 @@ typedef struct _alias *alias_ty; typedef struct _withitem *withitem_ty; +typedef struct _match_case *match_case_ty; + typedef struct _type_ignore *type_ignore_ty; @@ -121,6 +123,14 @@ asdl_withitem_seq *_Py_asdl_withitem_seq_new(Py_ssize_t size, PyArena *arena); typedef struct { _ASDL_SEQ_HEAD + match_case_ty typed_elements[1]; +} asdl_match_case_seq; + +asdl_match_case_seq *_Py_asdl_match_case_seq_new(Py_ssize_t size, PyArena + *arena); + +typedef struct { + _ASDL_SEQ_HEAD type_ignore_ty typed_elements[1]; } asdl_type_ignore_seq; @@ -158,10 +168,10 @@ 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, Raise_kind=15, Try_kind=16, - Assert_kind=17, Import_kind=18, ImportFrom_kind=19, - Global_kind=20, Nonlocal_kind=21, Expr_kind=22, Pass_kind=23, - Break_kind=24, Continue_kind=25}; + AsyncWith_kind=14, Match_kind=15, Raise_kind=16, Try_kind=17, + Assert_kind=18, Import_kind=19, ImportFrom_kind=20, + Global_kind=21, Nonlocal_kind=22, Expr_kind=23, Pass_kind=24, + Break_kind=25, Continue_kind=26}; struct _stmt { enum _stmt_kind kind; union { @@ -259,6 +269,11 @@ struct _stmt { } AsyncWith; struct { + expr_ty subject; + asdl_match_case_seq *cases; + } Match; + + struct { expr_ty exc; expr_ty cause; } Raise; @@ -311,7 +326,8 @@ enum _expr_kind {BoolOp_kind=1, NamedExpr_kind=2, BinOp_kind=3, UnaryOp_kind=4, YieldFrom_kind=15, Compare_kind=16, Call_kind=17, FormattedValue_kind=18, JoinedStr_kind=19, Constant_kind=20, Attribute_kind=21, Subscript_kind=22, Starred_kind=23, - Name_kind=24, List_kind=25, Tuple_kind=26, Slice_kind=27}; + Name_kind=24, List_kind=25, Tuple_kind=26, Slice_kind=27, + MatchAs_kind=28, MatchOr_kind=29}; struct _expr { enum _expr_kind kind; union { @@ -454,6 +470,15 @@ struct _expr { expr_ty step; } Slice; + struct { + expr_ty pattern; + identifier name; + } MatchAs; + + struct { + asdl_expr_seq *patterns; + } MatchOr; + } v; int lineno; int col_offset; @@ -524,6 +549,12 @@ struct _withitem { expr_ty optional_vars; }; +struct _match_case { + expr_ty pattern; + expr_ty guard; + asdl_stmt_seq *body; +}; + enum _type_ignore_kind {TypeIgnore_kind=1}; struct _type_ignore { enum _type_ignore_kind kind; @@ -607,6 +638,10 @@ stmt_ty _Py_With(asdl_withitem_seq * items, asdl_stmt_seq * body, string stmt_ty _Py_AsyncWith(asdl_withitem_seq * items, asdl_stmt_seq * body, string type_comment, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena); +#define Match(a0, a1, a2, a3, a4, a5, a6) _Py_Match(a0, a1, a2, a3, a4, a5, a6) +stmt_ty _Py_Match(expr_ty subject, asdl_match_case_seq * cases, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena + *arena); #define Raise(a0, a1, a2, a3, a4, a5, a6) _Py_Raise(a0, a1, a2, a3, a4, a5, a6) stmt_ty _Py_Raise(expr_ty exc, expr_ty cause, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena); @@ -743,6 +778,13 @@ expr_ty _Py_Tuple(asdl_expr_seq * elts, expr_context_ty ctx, int lineno, int expr_ty _Py_Slice(expr_ty lower, expr_ty upper, expr_ty step, int lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena); +#define MatchAs(a0, a1, a2, a3, a4, a5, a6) _Py_MatchAs(a0, a1, a2, a3, a4, a5, a6) +expr_ty _Py_MatchAs(expr_ty pattern, identifier name, int lineno, int + col_offset, int end_lineno, int end_col_offset, PyArena + *arena); +#define MatchOr(a0, a1, a2, a3, a4, a5) _Py_MatchOr(a0, a1, a2, a3, a4, a5) +expr_ty _Py_MatchOr(asdl_expr_seq * patterns, int lineno, int col_offset, int + end_lineno, int end_col_offset, PyArena *arena); #define comprehension(a0, a1, a2, a3, a4) _Py_comprehension(a0, a1, a2, a3, a4) comprehension_ty _Py_comprehension(expr_ty target, expr_ty iter, asdl_expr_seq * ifs, int is_async, PyArena *arena); @@ -769,6 +811,9 @@ alias_ty _Py_alias(identifier name, identifier asname, PyArena *arena); #define withitem(a0, a1, a2) _Py_withitem(a0, a1, a2) withitem_ty _Py_withitem(expr_ty context_expr, expr_ty optional_vars, PyArena *arena); +#define match_case(a0, a1, a2, a3) _Py_match_case(a0, a1, a2, a3) +match_case_ty _Py_match_case(expr_ty pattern, expr_ty guard, asdl_stmt_seq * + body, PyArena *arena); #define TypeIgnore(a0, a1, a2) _Py_TypeIgnore(a0, a1, a2) type_ignore_ty _Py_TypeIgnore(int lineno, string tag, PyArena *arena); diff --git a/Include/internal/pycore_ast.h b/Include/internal/pycore_ast.h index 058fbc0..2d0c5fb 100644 --- a/Include/internal/pycore_ast.h +++ b/Include/internal/pycore_ast.h @@ -91,6 +91,9 @@ struct ast_state { PyObject *Lt_type; PyObject *MatMult_singleton; PyObject *MatMult_type; + PyObject *MatchAs_type; + PyObject *MatchOr_type; + PyObject *Match_type; PyObject *Mod_singleton; PyObject *Mod_type; PyObject *Module_type; @@ -137,6 +140,7 @@ struct ast_state { PyObject *Yield_type; PyObject *__dict__; PyObject *__doc__; + PyObject *__match_args__; PyObject *__module__; PyObject *_attributes; PyObject *_fields; @@ -153,6 +157,7 @@ struct ast_state { PyObject *bases; PyObject *body; PyObject *boolop_type; + PyObject *cases; PyObject *cause; PyObject *cmpop_type; PyObject *col_offset; @@ -175,6 +180,7 @@ struct ast_state { PyObject *format_spec; PyObject *func; PyObject *generators; + PyObject *guard; PyObject *handlers; PyObject *id; PyObject *ifs; @@ -193,6 +199,7 @@ struct ast_state { PyObject *level; PyObject *lineno; PyObject *lower; + PyObject *match_case_type; PyObject *mod_type; PyObject *module; PyObject *msg; @@ -204,6 +211,8 @@ struct ast_state { PyObject *ops; PyObject *optional_vars; PyObject *orelse; + PyObject *pattern; + PyObject *patterns; PyObject *posonlyargs; PyObject *returns; PyObject *right; @@ -211,6 +220,7 @@ struct ast_state { PyObject *slice; PyObject *step; PyObject *stmt_type; + PyObject *subject; PyObject *tag; PyObject *target; PyObject *targets; diff --git a/Include/internal/pycore_interp.h b/Include/internal/pycore_interp.h index 58b1126..477cbf0 100644 --- a/Include/internal/pycore_interp.h +++ b/Include/internal/pycore_interp.h @@ -253,6 +253,10 @@ struct _is { // importlib module PyObject *importlib; + // Kept handy for pattern matching: + PyObject *map_abc; // _collections_abc.Mapping + PyObject *seq_abc; // _collections_abc.Sequence + /* Used in Modules/_threadmodule.c. */ long num_threads; /* Support for runtime thread stack size tuning. @@ -347,4 +351,3 @@ PyAPI_FUNC(void) _PyInterpreterState_IDDecref(struct _is *); } #endif #endif /* !Py_INTERNAL_INTERP_H */ - diff --git a/Include/object.h b/Include/object.h index 0870e4c..1454583 100644 --- a/Include/object.h +++ b/Include/object.h @@ -359,6 +359,11 @@ given type object has a specified feature. #define Py_TPFLAGS_HAVE_AM_SEND (1UL << 21) #endif +// This undocumented flag gives certain built-ins their unique pattern-matching +// behavior, which allows a single positional subpattern to match against the +// subject itself (rather than a mapped attribute on it): +#define _Py_TPFLAGS_MATCH_SELF (1UL << 22) + /* These flags are used to determine if a type is a subclass. */ #define Py_TPFLAGS_LONG_SUBCLASS (1UL << 24) #define Py_TPFLAGS_LIST_SUBCLASS (1UL << 25) diff --git a/Include/opcode.h b/Include/opcode.h index 998a5ce..ea484c5 100644 --- a/Include/opcode.h +++ b/Include/opcode.h @@ -30,6 +30,11 @@ extern "C" { #define BINARY_TRUE_DIVIDE 27 #define INPLACE_FLOOR_DIVIDE 28 #define INPLACE_TRUE_DIVIDE 29 +#define GET_LEN 30 +#define MATCH_MAPPING 31 +#define MATCH_SEQUENCE 32 +#define MATCH_KEYS 33 +#define COPY_DICT_WITHOUT_KEYS 34 #define WITH_EXCEPT_START 49 #define GET_AITER 50 #define GET_ANEXT 51 @@ -117,6 +122,7 @@ extern "C" { #define SET_ADD 146 #define MAP_ADD 147 #define LOAD_CLASSDEREF 148 +#define MATCH_CLASS 152 #define SETUP_ASYNC_WITH 154 #define FORMAT_VALUE 155 #define BUILD_CONST_KEY_MAP 156 diff --git a/Include/symtable.h b/Include/symtable.h index abd19a7..6f0b7cb 100644 --- a/Include/symtable.h +++ b/Include/symtable.h @@ -33,6 +33,7 @@ struct symtable { the symbol table */ int recursion_depth; /* current recursion depth */ int recursion_limit; /* recursion limit */ + int in_pattern; /* whether we are currently in a pattern */ }; typedef struct _symtable_entry { |