mirror of https://github.com/python/cpython
bpo-35766: Merge typed_ast back into CPython (GH-11645)
This commit is contained in:
parent
d97daebfa6
commit
dcfcd146f8
|
@ -126,16 +126,33 @@ The abstract grammar is currently defined as follows:
|
|||
Apart from the node classes, the :mod:`ast` module defines these utility functions
|
||||
and classes for traversing abstract syntax trees:
|
||||
|
||||
.. function:: parse(source, filename='<unknown>', mode='exec')
|
||||
.. function:: parse(source, filename='<unknown>', mode='exec', *, type_comments=False)
|
||||
|
||||
Parse the source into an AST node. Equivalent to ``compile(source,
|
||||
filename, mode, ast.PyCF_ONLY_AST)``.
|
||||
|
||||
If ``type_comments=True`` is given, the parser is modified to check
|
||||
and return type comments as specified by :pep:`484` and :pep:`526`.
|
||||
This is equivalent to adding :data:`ast.PyCF_TYPE_COMMENTS` to the
|
||||
flags passed to :func:`compile()`. This will report syntax errors
|
||||
for misplaced type comments. Without this flag, type comments will
|
||||
be ignored, and the ``type_comment`` field on selected AST nodes
|
||||
will always be ``None``. In addition, the locations of ``# type:
|
||||
ignore`` comments will be returned as the ``type_ignores``
|
||||
attribute of :class:`Module` (otherwise it is always an empty list).
|
||||
|
||||
In addition, if ``mode`` is ``'func_type'``, the input syntax is
|
||||
modified to correspond to :pep:`484` "signature type comments",
|
||||
e.g. ``(str, int) -> List[str]``.
|
||||
|
||||
.. warning::
|
||||
It is possible to crash the Python interpreter with a
|
||||
sufficiently large/complex string due to stack depth limitations
|
||||
in Python's AST compiler.
|
||||
|
||||
.. versionchanged:: 3.8
|
||||
Added ``type_comments=True`` and ``mode='func_type'``.
|
||||
|
||||
|
||||
.. function:: literal_eval(node_or_string)
|
||||
|
||||
|
|
|
@ -203,6 +203,10 @@
|
|||
|
||||
.. data:: OP
|
||||
|
||||
.. data:: TYPE_IGNORE
|
||||
|
||||
.. data:: TYPE_COMMENT
|
||||
|
||||
.. data:: ERRORTOKEN
|
||||
|
||||
.. data:: N_TOKENS
|
||||
|
|
|
@ -69,6 +69,13 @@ the :mod:`tokenize` module.
|
|||
always be an ``ENCODING`` token.
|
||||
|
||||
|
||||
.. data:: TYPE_COMMENT
|
||||
|
||||
Token value indicating that a type comment was recognized. Such
|
||||
tokens are only produced when :func:`ast.parse()` is invoked with
|
||||
``type_comments=True``.
|
||||
|
||||
|
||||
.. versionchanged:: 3.5
|
||||
Added :data:`AWAIT` and :data:`ASYNC` tokens.
|
||||
|
||||
|
@ -78,3 +85,6 @@ the :mod:`tokenize` module.
|
|||
.. versionchanged:: 3.7
|
||||
Removed :data:`AWAIT` and :data:`ASYNC` tokens. "async" and "await" are
|
||||
now tokenized as :data:`NAME` tokens.
|
||||
|
||||
.. versionchanged:: 3.8
|
||||
Added :data:`TYPE_COMMENT`.
|
||||
|
|
|
@ -7,7 +7,9 @@
|
|||
# single_input is a single interactive statement;
|
||||
# file_input is a module or sequence of commands read from an input file;
|
||||
# eval_input is the input for the eval() functions.
|
||||
# func_type_input is a PEP 484 Python 2 function type comment
|
||||
# NB: compound_stmt in single_input is followed by extra NEWLINE!
|
||||
# NB: due to the way TYPE_COMMENT is tokenized it will always be followed by a NEWLINE
|
||||
single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE
|
||||
file_input: (NEWLINE | stmt)* ENDMARKER
|
||||
eval_input: testlist NEWLINE* ENDMARKER
|
||||
|
@ -17,14 +19,14 @@ decorators: decorator+
|
|||
decorated: decorators (classdef | funcdef | async_funcdef)
|
||||
|
||||
async_funcdef: 'async' funcdef
|
||||
funcdef: 'def' NAME parameters ['->' test] ':' suite
|
||||
funcdef: 'def' NAME parameters ['->' test] ':' [TYPE_COMMENT] func_body_suite
|
||||
|
||||
parameters: '(' [typedargslist] ')'
|
||||
typedargslist: (tfpdef ['=' test] (',' tfpdef ['=' test])* [',' [
|
||||
'*' [tfpdef] (',' tfpdef ['=' test])* [',' ['**' tfpdef [',']]]
|
||||
| '**' tfpdef [',']]]
|
||||
| '*' [tfpdef] (',' tfpdef ['=' test])* [',' ['**' tfpdef [',']]]
|
||||
| '**' tfpdef [','])
|
||||
typedargslist: (tfpdef ['=' test] (',' [TYPE_COMMENT] tfpdef ['=' test])* (TYPE_COMMENT | [',' [TYPE_COMMENT] [
|
||||
'*' [tfpdef] (',' [TYPE_COMMENT] tfpdef ['=' test])* (TYPE_COMMENT | [',' [TYPE_COMMENT] ['**' tfpdef [','] [TYPE_COMMENT]]])
|
||||
| '**' tfpdef [','] [TYPE_COMMENT]]])
|
||||
| '*' [tfpdef] (',' [TYPE_COMMENT] tfpdef ['=' test])* (TYPE_COMMENT | [',' [TYPE_COMMENT] ['**' tfpdef [','] [TYPE_COMMENT]]])
|
||||
| '**' tfpdef [','] [TYPE_COMMENT])
|
||||
tfpdef: NAME [':' test]
|
||||
varargslist: (vfpdef ['=' test] (',' vfpdef ['=' test])* [',' [
|
||||
'*' [vfpdef] (',' vfpdef ['=' test])* [',' ['**' vfpdef [',']]]
|
||||
|
@ -39,7 +41,7 @@ simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
|
|||
small_stmt: (expr_stmt | del_stmt | pass_stmt | flow_stmt |
|
||||
import_stmt | global_stmt | nonlocal_stmt | assert_stmt)
|
||||
expr_stmt: testlist_star_expr (annassign | augassign (yield_expr|testlist) |
|
||||
('=' (yield_expr|testlist_star_expr))*)
|
||||
[('=' (yield_expr|testlist_star_expr))+ [TYPE_COMMENT]] )
|
||||
annassign: ':' test ['=' (yield_expr|testlist)]
|
||||
testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
|
||||
augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' |
|
||||
|
@ -71,13 +73,13 @@ compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | with_stmt | funcdef
|
|||
async_stmt: 'async' (funcdef | with_stmt | for_stmt)
|
||||
if_stmt: 'if' namedexpr_test ':' suite ('elif' namedexpr_test ':' suite)* ['else' ':' suite]
|
||||
while_stmt: 'while' test ':' suite ['else' ':' suite]
|
||||
for_stmt: 'for' exprlist 'in' testlist ':' suite ['else' ':' suite]
|
||||
for_stmt: 'for' exprlist 'in' testlist ':' [TYPE_COMMENT] suite ['else' ':' suite]
|
||||
try_stmt: ('try' ':' suite
|
||||
((except_clause ':' suite)+
|
||||
['else' ':' suite]
|
||||
['finally' ':' suite] |
|
||||
'finally' ':' suite))
|
||||
with_stmt: 'with' with_item (',' with_item)* ':' suite
|
||||
with_stmt: 'with' with_item (',' with_item)* ':' [TYPE_COMMENT] suite
|
||||
with_item: test ['as' expr]
|
||||
# NB compile.c makes sure that the default except clause is last
|
||||
except_clause: 'except' [test ['as' NAME]]
|
||||
|
@ -150,3 +152,14 @@ encoding_decl: NAME
|
|||
|
||||
yield_expr: 'yield' [yield_arg]
|
||||
yield_arg: 'from' test | testlist_star_expr
|
||||
|
||||
# the TYPE_COMMENT in suites is only parsed for funcdefs,
|
||||
# but can't go elsewhere due to ambiguity
|
||||
func_body_suite: simple_stmt | NEWLINE [TYPE_COMMENT NEWLINE] INDENT stmt+ DEDENT
|
||||
|
||||
func_type_input: func_type NEWLINE* ENDMARKER
|
||||
func_type: '(' [typelist] ')' '->' test
|
||||
# typelist is a modified typedargslist (see above)
|
||||
typelist: (test (',' test)* [','
|
||||
['*' [test] (',' test)* [',' '**' test] | '**' test]]
|
||||
| '*' [test] (',' test)* [',' '**' test] | '**' test)
|
||||
|
|
|
@ -55,6 +55,8 @@ ELLIPSIS '...'
|
|||
COLONEQUAL ':='
|
||||
|
||||
OP
|
||||
TYPE_IGNORE
|
||||
TYPE_COMMENT
|
||||
ERRORTOKEN
|
||||
|
||||
# These aren't used by the C tokenizer but are needed for tokenize.py
|
||||
|
|
|
@ -46,14 +46,17 @@ typedef struct _alias *alias_ty;
|
|||
|
||||
typedef struct _withitem *withitem_ty;
|
||||
|
||||
typedef struct _type_ignore *type_ignore_ty;
|
||||
|
||||
|
||||
enum _mod_kind {Module_kind=1, Interactive_kind=2, Expression_kind=3,
|
||||
Suite_kind=4};
|
||||
FunctionType_kind=4, Suite_kind=5};
|
||||
struct _mod {
|
||||
enum _mod_kind kind;
|
||||
union {
|
||||
struct {
|
||||
asdl_seq *body;
|
||||
asdl_seq *type_ignores;
|
||||
} Module;
|
||||
|
||||
struct {
|
||||
|
@ -64,6 +67,11 @@ struct _mod {
|
|||
expr_ty body;
|
||||
} Expression;
|
||||
|
||||
struct {
|
||||
asdl_seq *argtypes;
|
||||
expr_ty returns;
|
||||
} FunctionType;
|
||||
|
||||
struct {
|
||||
asdl_seq *body;
|
||||
} Suite;
|
||||
|
@ -88,6 +96,7 @@ struct _stmt {
|
|||
asdl_seq *body;
|
||||
asdl_seq *decorator_list;
|
||||
expr_ty returns;
|
||||
string type_comment;
|
||||
} FunctionDef;
|
||||
|
||||
struct {
|
||||
|
@ -96,6 +105,7 @@ struct _stmt {
|
|||
asdl_seq *body;
|
||||
asdl_seq *decorator_list;
|
||||
expr_ty returns;
|
||||
string type_comment;
|
||||
} AsyncFunctionDef;
|
||||
|
||||
struct {
|
||||
|
@ -117,6 +127,7 @@ struct _stmt {
|
|||
struct {
|
||||
asdl_seq *targets;
|
||||
expr_ty value;
|
||||
string type_comment;
|
||||
} Assign;
|
||||
|
||||
struct {
|
||||
|
@ -137,6 +148,7 @@ struct _stmt {
|
|||
expr_ty iter;
|
||||
asdl_seq *body;
|
||||
asdl_seq *orelse;
|
||||
string type_comment;
|
||||
} For;
|
||||
|
||||
struct {
|
||||
|
@ -144,6 +156,7 @@ struct _stmt {
|
|||
expr_ty iter;
|
||||
asdl_seq *body;
|
||||
asdl_seq *orelse;
|
||||
string type_comment;
|
||||
} AsyncFor;
|
||||
|
||||
struct {
|
||||
|
@ -161,11 +174,13 @@ struct _stmt {
|
|||
struct {
|
||||
asdl_seq *items;
|
||||
asdl_seq *body;
|
||||
string type_comment;
|
||||
} With;
|
||||
|
||||
struct {
|
||||
asdl_seq *items;
|
||||
asdl_seq *body;
|
||||
string type_comment;
|
||||
} AsyncWith;
|
||||
|
||||
struct {
|
||||
|
@ -421,6 +436,7 @@ struct _arguments {
|
|||
struct _arg {
|
||||
identifier arg;
|
||||
expr_ty annotation;
|
||||
string type_comment;
|
||||
int lineno;
|
||||
int col_offset;
|
||||
int end_lineno;
|
||||
|
@ -442,26 +458,40 @@ struct _withitem {
|
|||
expr_ty optional_vars;
|
||||
};
|
||||
|
||||
enum _type_ignore_kind {TypeIgnore_kind=1};
|
||||
struct _type_ignore {
|
||||
enum _type_ignore_kind kind;
|
||||
union {
|
||||
struct {
|
||||
int lineno;
|
||||
} TypeIgnore;
|
||||
|
||||
} v;
|
||||
};
|
||||
|
||||
|
||||
// Note: these macros affect function definitions, not only call sites.
|
||||
#define Module(a0, a1) _Py_Module(a0, a1)
|
||||
mod_ty _Py_Module(asdl_seq * body, PyArena *arena);
|
||||
#define Module(a0, a1, a2) _Py_Module(a0, a1, a2)
|
||||
mod_ty _Py_Module(asdl_seq * body, asdl_seq * type_ignores, PyArena *arena);
|
||||
#define Interactive(a0, a1) _Py_Interactive(a0, a1)
|
||||
mod_ty _Py_Interactive(asdl_seq * body, PyArena *arena);
|
||||
#define Expression(a0, a1) _Py_Expression(a0, a1)
|
||||
mod_ty _Py_Expression(expr_ty body, PyArena *arena);
|
||||
#define FunctionType(a0, a1, a2) _Py_FunctionType(a0, a1, a2)
|
||||
mod_ty _Py_FunctionType(asdl_seq * argtypes, expr_ty returns, PyArena *arena);
|
||||
#define Suite(a0, a1) _Py_Suite(a0, a1)
|
||||
mod_ty _Py_Suite(asdl_seq * body, PyArena *arena);
|
||||
#define FunctionDef(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) _Py_FunctionDef(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)
|
||||
#define FunctionDef(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) _Py_FunctionDef(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)
|
||||
stmt_ty _Py_FunctionDef(identifier name, arguments_ty args, asdl_seq * body,
|
||||
asdl_seq * decorator_list, expr_ty returns, int lineno,
|
||||
int col_offset, int end_lineno, int end_col_offset,
|
||||
PyArena *arena);
|
||||
#define AsyncFunctionDef(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) _Py_AsyncFunctionDef(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)
|
||||
asdl_seq * decorator_list, expr_ty returns, string
|
||||
type_comment, int lineno, int col_offset, int
|
||||
end_lineno, int end_col_offset, PyArena *arena);
|
||||
#define AsyncFunctionDef(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) _Py_AsyncFunctionDef(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)
|
||||
stmt_ty _Py_AsyncFunctionDef(identifier name, arguments_ty args, asdl_seq *
|
||||
body, asdl_seq * decorator_list, expr_ty returns,
|
||||
int lineno, int col_offset, int end_lineno, int
|
||||
end_col_offset, PyArena *arena);
|
||||
string type_comment, int lineno, int col_offset,
|
||||
int end_lineno, int end_col_offset, PyArena
|
||||
*arena);
|
||||
#define ClassDef(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) _Py_ClassDef(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)
|
||||
stmt_ty _Py_ClassDef(identifier name, asdl_seq * bases, asdl_seq * keywords,
|
||||
asdl_seq * body, asdl_seq * decorator_list, int lineno,
|
||||
|
@ -473,10 +503,10 @@ stmt_ty _Py_Return(expr_ty value, int lineno, int col_offset, int end_lineno,
|
|||
#define Delete(a0, a1, a2, a3, a4, a5) _Py_Delete(a0, a1, a2, a3, a4, a5)
|
||||
stmt_ty _Py_Delete(asdl_seq * targets, int lineno, int col_offset, int
|
||||
end_lineno, int end_col_offset, PyArena *arena);
|
||||
#define Assign(a0, a1, a2, a3, a4, a5, a6) _Py_Assign(a0, a1, a2, a3, a4, a5, a6)
|
||||
stmt_ty _Py_Assign(asdl_seq * targets, expr_ty value, int lineno, int
|
||||
col_offset, int end_lineno, int end_col_offset, PyArena
|
||||
*arena);
|
||||
#define Assign(a0, a1, a2, a3, a4, a5, a6, a7) _Py_Assign(a0, a1, a2, a3, a4, a5, a6, a7)
|
||||
stmt_ty _Py_Assign(asdl_seq * targets, expr_ty value, string type_comment, int
|
||||
lineno, int col_offset, int end_lineno, int end_col_offset,
|
||||
PyArena *arena);
|
||||
#define AugAssign(a0, a1, a2, a3, a4, a5, a6, a7) _Py_AugAssign(a0, a1, a2, a3, a4, a5, a6, a7)
|
||||
stmt_ty _Py_AugAssign(expr_ty target, operator_ty op, expr_ty value, int
|
||||
lineno, int col_offset, int end_lineno, int
|
||||
|
@ -485,14 +515,14 @@ stmt_ty _Py_AugAssign(expr_ty target, operator_ty op, expr_ty value, int
|
|||
stmt_ty _Py_AnnAssign(expr_ty target, expr_ty annotation, expr_ty value, int
|
||||
simple, int lineno, int col_offset, int end_lineno, int
|
||||
end_col_offset, PyArena *arena);
|
||||
#define For(a0, a1, a2, a3, a4, a5, a6, a7, a8) _Py_For(a0, a1, a2, a3, a4, a5, a6, a7, a8)
|
||||
#define For(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) _Py_For(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)
|
||||
stmt_ty _Py_For(expr_ty target, expr_ty iter, asdl_seq * body, asdl_seq *
|
||||
orelse, int lineno, int col_offset, int end_lineno, int
|
||||
end_col_offset, PyArena *arena);
|
||||
#define AsyncFor(a0, a1, a2, a3, a4, a5, a6, a7, a8) _Py_AsyncFor(a0, a1, a2, a3, a4, a5, a6, a7, a8)
|
||||
orelse, string type_comment, int lineno, int col_offset, int
|
||||
end_lineno, int end_col_offset, PyArena *arena);
|
||||
#define AsyncFor(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) _Py_AsyncFor(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)
|
||||
stmt_ty _Py_AsyncFor(expr_ty target, expr_ty iter, asdl_seq * body, asdl_seq *
|
||||
orelse, int lineno, int col_offset, int end_lineno, int
|
||||
end_col_offset, PyArena *arena);
|
||||
orelse, string type_comment, int lineno, int col_offset,
|
||||
int end_lineno, int end_col_offset, PyArena *arena);
|
||||
#define While(a0, a1, a2, a3, a4, a5, a6, a7) _Py_While(a0, a1, a2, a3, a4, a5, a6, a7)
|
||||
stmt_ty _Py_While(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno,
|
||||
int col_offset, int end_lineno, int end_col_offset, PyArena
|
||||
|
@ -501,13 +531,14 @@ stmt_ty _Py_While(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno,
|
|||
stmt_ty _Py_If(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno,
|
||||
int col_offset, int end_lineno, int end_col_offset, PyArena
|
||||
*arena);
|
||||
#define With(a0, a1, a2, a3, a4, a5, a6) _Py_With(a0, a1, a2, a3, a4, a5, a6)
|
||||
stmt_ty _Py_With(asdl_seq * items, asdl_seq * body, int lineno, int col_offset,
|
||||
int end_lineno, int end_col_offset, PyArena *arena);
|
||||
#define AsyncWith(a0, a1, a2, a3, a4, a5, a6) _Py_AsyncWith(a0, a1, a2, a3, a4, a5, a6)
|
||||
stmt_ty _Py_AsyncWith(asdl_seq * items, asdl_seq * body, int lineno, int
|
||||
col_offset, int end_lineno, int end_col_offset, PyArena
|
||||
*arena);
|
||||
#define With(a0, a1, a2, a3, a4, a5, a6, a7) _Py_With(a0, a1, a2, a3, a4, a5, a6, a7)
|
||||
stmt_ty _Py_With(asdl_seq * items, asdl_seq * body, string type_comment, int
|
||||
lineno, int col_offset, int end_lineno, int end_col_offset,
|
||||
PyArena *arena);
|
||||
#define AsyncWith(a0, a1, a2, a3, a4, a5, a6, a7) _Py_AsyncWith(a0, a1, a2, a3, a4, a5, a6, a7)
|
||||
stmt_ty _Py_AsyncWith(asdl_seq * items, asdl_seq * body, string type_comment,
|
||||
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);
|
||||
|
@ -656,9 +687,10 @@ excepthandler_ty _Py_ExceptHandler(expr_ty type, identifier name, asdl_seq *
|
|||
arguments_ty _Py_arguments(asdl_seq * args, arg_ty vararg, asdl_seq *
|
||||
kwonlyargs, asdl_seq * kw_defaults, arg_ty kwarg,
|
||||
asdl_seq * defaults, PyArena *arena);
|
||||
#define arg(a0, a1, a2, a3, a4, a5, a6) _Py_arg(a0, a1, a2, a3, a4, a5, a6)
|
||||
arg_ty _Py_arg(identifier arg, expr_ty annotation, int lineno, int col_offset,
|
||||
int end_lineno, int end_col_offset, PyArena *arena);
|
||||
#define arg(a0, a1, a2, a3, a4, a5, a6, a7) _Py_arg(a0, a1, a2, a3, a4, a5, a6, a7)
|
||||
arg_ty _Py_arg(identifier arg, expr_ty annotation, string type_comment, int
|
||||
lineno, int col_offset, int end_lineno, int end_col_offset,
|
||||
PyArena *arena);
|
||||
#define keyword(a0, a1, a2) _Py_keyword(a0, a1, a2)
|
||||
keyword_ty _Py_keyword(identifier arg, expr_ty value, PyArena *arena);
|
||||
#define alias(a0, a1, a2) _Py_alias(a0, a1, a2)
|
||||
|
@ -666,6 +698,8 @@ 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 TypeIgnore(a0, a1) _Py_TypeIgnore(a0, a1)
|
||||
type_ignore_ty _Py_TypeIgnore(int lineno, PyArena *arena);
|
||||
|
||||
PyObject* PyAST_mod2obj(mod_ty t);
|
||||
mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena, int mode);
|
||||
|
|
|
@ -22,6 +22,7 @@ PyAPI_FUNC(PyCodeObject *) PyNode_Compile(struct _node *, const char *);
|
|||
#define PyCF_DONT_IMPLY_DEDENT 0x0200
|
||||
#define PyCF_ONLY_AST 0x0400
|
||||
#define PyCF_IGNORE_COOKIE 0x0800
|
||||
#define PyCF_TYPE_COMMENTS 0x1000
|
||||
|
||||
#ifndef Py_LIMITED_API
|
||||
typedef struct {
|
||||
|
@ -85,10 +86,10 @@ PyAPI_FUNC(int) _PyAST_Optimize(struct _mod *, PyArena *arena, int optimize);
|
|||
|
||||
#endif /* !Py_LIMITED_API */
|
||||
|
||||
/* These definitions must match corresponding definitions in graminit.h.
|
||||
There's code in compile.c that checks that they are the same. */
|
||||
/* These definitions must match corresponding definitions in graminit.h. */
|
||||
#define Py_single_input 256
|
||||
#define Py_file_input 257
|
||||
#define Py_eval_input 258
|
||||
#define Py_func_type_input 345
|
||||
|
||||
#endif /* !Py_COMPILE_H */
|
||||
|
|
|
@ -88,3 +88,7 @@
|
|||
#define encoding_decl 341
|
||||
#define yield_expr 342
|
||||
#define yield_arg 343
|
||||
#define func_body_suite 344
|
||||
#define func_type_input 345
|
||||
#define func_type 346
|
||||
#define typelist 347
|
||||
|
|
|
@ -37,6 +37,7 @@ typedef struct {
|
|||
|
||||
#define PyPARSE_IGNORE_COOKIE 0x0010
|
||||
#define PyPARSE_BARRY_AS_BDFL 0x0020
|
||||
#define PyPARSE_TYPE_COMMENTS 0x0040
|
||||
|
||||
PyAPI_FUNC(node *) PyParser_ParseString(const char *, grammar *, int,
|
||||
perrdetail *);
|
||||
|
|
|
@ -65,8 +65,10 @@ extern "C" {
|
|||
#define ELLIPSIS 52
|
||||
#define COLONEQUAL 53
|
||||
#define OP 54
|
||||
#define ERRORTOKEN 55
|
||||
#define N_TOKENS 59
|
||||
#define TYPE_IGNORE 55
|
||||
#define TYPE_COMMENT 56
|
||||
#define ERRORTOKEN 57
|
||||
#define N_TOKENS 61
|
||||
#define NT_OFFSET 256
|
||||
|
||||
/* Special definitions for cooperation with parser */
|
||||
|
|
|
@ -27,12 +27,16 @@
|
|||
from _ast import *
|
||||
|
||||
|
||||
def parse(source, filename='<unknown>', mode='exec'):
|
||||
def parse(source, filename='<unknown>', mode='exec', *, type_comments=False):
|
||||
"""
|
||||
Parse the source into an AST node.
|
||||
Equivalent to compile(source, filename, mode, PyCF_ONLY_AST).
|
||||
Pass type_comments=True to get back type comments where the syntax allows.
|
||||
"""
|
||||
return compile(source, filename, mode, PyCF_ONLY_AST)
|
||||
flags = PyCF_ONLY_AST
|
||||
if type_comments:
|
||||
flags |= PyCF_TYPE_COMMENTS
|
||||
return compile(source, filename, mode, flags)
|
||||
|
||||
|
||||
def literal_eval(node_or_string):
|
||||
|
|
|
@ -100,6 +100,10 @@ comp_if = 340
|
|||
encoding_decl = 341
|
||||
yield_expr = 342
|
||||
yield_arg = 343
|
||||
func_body_suite = 344
|
||||
func_type_input = 345
|
||||
func_type = 346
|
||||
typelist = 347
|
||||
#--end constants--
|
||||
|
||||
sym_name = {}
|
||||
|
|
|
@ -117,7 +117,8 @@ class TestAsdlParser(unittest.TestCase):
|
|||
|
||||
v = CustomVisitor()
|
||||
v.visit(self.types['mod'])
|
||||
self.assertEqual(v.names_with_seq, ['Module', 'Interactive', 'Suite'])
|
||||
self.assertEqual(v.names_with_seq,
|
||||
['Module', 'Module', 'Interactive', 'FunctionType', 'Suite'])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
@ -455,7 +455,7 @@ class AST_Tests(unittest.TestCase):
|
|||
|
||||
def test_module(self):
|
||||
body = [ast.Num(42)]
|
||||
x = ast.Module(body)
|
||||
x = ast.Module(body, [])
|
||||
self.assertEqual(x.body, body)
|
||||
|
||||
def test_nodeclasses(self):
|
||||
|
@ -524,13 +524,13 @@ class AST_Tests(unittest.TestCase):
|
|||
|
||||
def test_invalid_sum(self):
|
||||
pos = dict(lineno=2, col_offset=3)
|
||||
m = ast.Module([ast.Expr(ast.expr(**pos), **pos)])
|
||||
m = ast.Module([ast.Expr(ast.expr(**pos), **pos)], [])
|
||||
with self.assertRaises(TypeError) as cm:
|
||||
compile(m, "<test>", "exec")
|
||||
self.assertIn("but got <_ast.expr", str(cm.exception))
|
||||
|
||||
def test_invalid_identitifer(self):
|
||||
m = ast.Module([ast.Expr(ast.Name(42, ast.Load()))])
|
||||
m = ast.Module([ast.Expr(ast.Name(42, ast.Load()))], [])
|
||||
ast.fix_missing_locations(m)
|
||||
with self.assertRaises(TypeError) as cm:
|
||||
compile(m, "<test>", "exec")
|
||||
|
@ -575,11 +575,11 @@ class ASTHelpers_Test(unittest.TestCase):
|
|||
self.assertEqual(ast.dump(node),
|
||||
"Module(body=[Expr(value=Call(func=Name(id='spam', ctx=Load()), "
|
||||
"args=[Name(id='eggs', ctx=Load()), Constant(value='and cheese')], "
|
||||
"keywords=[]))])"
|
||||
"keywords=[]))], type_ignores=[])"
|
||||
)
|
||||
self.assertEqual(ast.dump(node, annotate_fields=False),
|
||||
"Module([Expr(Call(Name('spam', Load()), [Name('eggs', Load()), "
|
||||
"Constant('and cheese')], []))])"
|
||||
"Constant('and cheese')], []))], [])"
|
||||
)
|
||||
self.assertEqual(ast.dump(node, include_attributes=True),
|
||||
"Module(body=[Expr(value=Call(func=Name(id='spam', ctx=Load(), "
|
||||
|
@ -588,7 +588,7 @@ class ASTHelpers_Test(unittest.TestCase):
|
|||
"end_lineno=1, end_col_offset=9), Constant(value='and cheese', "
|
||||
"lineno=1, col_offset=11, end_lineno=1, end_col_offset=23)], keywords=[], "
|
||||
"lineno=1, col_offset=0, end_lineno=1, end_col_offset=24), "
|
||||
"lineno=1, col_offset=0, end_lineno=1, end_col_offset=24)])"
|
||||
"lineno=1, col_offset=0, end_lineno=1, end_col_offset=24)], type_ignores=[])"
|
||||
)
|
||||
|
||||
def test_copy_location(self):
|
||||
|
@ -617,7 +617,8 @@ class ASTHelpers_Test(unittest.TestCase):
|
|||
"lineno=1, col_offset=0, end_lineno=1, end_col_offset=0), "
|
||||
"args=[Constant(value='eggs', lineno=1, col_offset=0, end_lineno=1, "
|
||||
"end_col_offset=0)], keywords=[], lineno=1, col_offset=0, end_lineno=1, "
|
||||
"end_col_offset=0), lineno=1, col_offset=0, end_lineno=1, end_col_offset=0)])"
|
||||
"end_col_offset=0), lineno=1, col_offset=0, end_lineno=1, end_col_offset=0)], "
|
||||
"type_ignores=[])"
|
||||
)
|
||||
|
||||
def test_increment_lineno(self):
|
||||
|
@ -760,7 +761,7 @@ class ASTHelpers_Test(unittest.TestCase):
|
|||
names=[ast.alias(name='sleep')],
|
||||
level=None,
|
||||
lineno=None, col_offset=None)]
|
||||
mod = ast.Module(body)
|
||||
mod = ast.Module(body, [])
|
||||
with self.assertRaises(ValueError) as cm:
|
||||
compile(mod, 'test', 'exec')
|
||||
self.assertIn("invalid integer value: None", str(cm.exception))
|
||||
|
@ -770,7 +771,7 @@ class ASTHelpers_Test(unittest.TestCase):
|
|||
names=[ast.alias(name='sleep')],
|
||||
level=None,
|
||||
lineno=0, col_offset=0)]
|
||||
mod = ast.Module(body)
|
||||
mod = ast.Module(body, [])
|
||||
code = compile(mod, 'test', 'exec')
|
||||
ns = {}
|
||||
exec(code, ns)
|
||||
|
@ -790,11 +791,11 @@ class ASTValidatorTests(unittest.TestCase):
|
|||
self.assertIn(msg, str(cm.exception))
|
||||
|
||||
def expr(self, node, msg=None, *, exc=ValueError):
|
||||
mod = ast.Module([ast.Expr(node)])
|
||||
mod = ast.Module([ast.Expr(node)], [])
|
||||
self.mod(mod, msg, exc=exc)
|
||||
|
||||
def stmt(self, stmt, msg=None):
|
||||
mod = ast.Module([stmt])
|
||||
mod = ast.Module([stmt], [])
|
||||
self.mod(mod, msg)
|
||||
|
||||
def test_module(self):
|
||||
|
@ -1603,61 +1604,61 @@ def main():
|
|||
raise SystemExit
|
||||
unittest.main()
|
||||
|
||||
#### EVERYTHING BELOW IS GENERATED #####
|
||||
#### EVERYTHING BELOW IS GENERATED BY python Lib/test/test_ast.py -g #####
|
||||
exec_results = [
|
||||
('Module', [('Expr', (1, 0), ('Constant', (1, 0), None))]),
|
||||
('Module', [('Expr', (1, 0), ('Constant', (1, 0), 'module docstring'))]),
|
||||
('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, [], [], None, []), [('Pass', (1, 9))], [], None)]),
|
||||
('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, [], [], None, []), [('Expr', (1, 9), ('Constant', (1, 9), 'function docstring'))], [], None)]),
|
||||
('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None)], None, [], [], None, []), [('Pass', (1, 10))], [], None)]),
|
||||
('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None)], None, [], [], None, [('Constant', (1, 8), 0)]), [('Pass', (1, 12))], [], None)]),
|
||||
('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], ('arg', (1, 7), 'args', None), [], [], None, []), [('Pass', (1, 14))], [], None)]),
|
||||
('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, [], [], ('arg', (1, 8), 'kwargs', None), []), [('Pass', (1, 17))], [], None)]),
|
||||
('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None), ('arg', (1, 9), 'b', None), ('arg', (1, 14), 'c', None), ('arg', (1, 22), 'd', None), ('arg', (1, 28), 'e', None)], ('arg', (1, 35), 'args', None), [('arg', (1, 41), 'f', None)], [('Constant', (1, 43), 42)], ('arg', (1, 49), 'kwargs', None), [('Constant', (1, 11), 1), ('Constant', (1, 16), None), ('List', (1, 24), [], ('Load',)), ('Dict', (1, 30), [], [])]), [('Expr', (1, 58), ('Constant', (1, 58), 'doc for f()'))], [], None)]),
|
||||
('Module', [('ClassDef', (1, 0), 'C', [], [], [('Pass', (1, 8))], [])]),
|
||||
('Module', [('ClassDef', (1, 0), 'C', [], [], [('Expr', (1, 9), ('Constant', (1, 9), 'docstring for class C'))], [])]),
|
||||
('Module', [('ClassDef', (1, 0), 'C', [('Name', (1, 8), 'object', ('Load',))], [], [('Pass', (1, 17))], [])]),
|
||||
('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, [], [], None, []), [('Return', (1, 8), ('Constant', (1, 15), 1))], [], None)]),
|
||||
('Module', [('Delete', (1, 0), [('Name', (1, 4), 'v', ('Del',))])]),
|
||||
('Module', [('Assign', (1, 0), [('Name', (1, 0), 'v', ('Store',))], ('Constant', (1, 4), 1))]),
|
||||
('Module', [('Assign', (1, 0), [('Tuple', (1, 0), [('Name', (1, 0), 'a', ('Store',)), ('Name', (1, 2), 'b', ('Store',))], ('Store',))], ('Name', (1, 6), 'c', ('Load',)))]),
|
||||
('Module', [('Assign', (1, 0), [('Tuple', (1, 0), [('Name', (1, 1), 'a', ('Store',)), ('Name', (1, 3), 'b', ('Store',))], ('Store',))], ('Name', (1, 8), 'c', ('Load',)))]),
|
||||
('Module', [('Assign', (1, 0), [('List', (1, 0), [('Name', (1, 1), 'a', ('Store',)), ('Name', (1, 3), 'b', ('Store',))], ('Store',))], ('Name', (1, 8), 'c', ('Load',)))]),
|
||||
('Module', [('AugAssign', (1, 0), ('Name', (1, 0), 'v', ('Store',)), ('Add',), ('Constant', (1, 5), 1))]),
|
||||
('Module', [('For', (1, 0), ('Name', (1, 4), 'v', ('Store',)), ('Name', (1, 9), 'v', ('Load',)), [('Pass', (1, 11))], [])]),
|
||||
('Module', [('While', (1, 0), ('Name', (1, 6), 'v', ('Load',)), [('Pass', (1, 8))], [])]),
|
||||
('Module', [('If', (1, 0), ('Name', (1, 3), 'v', ('Load',)), [('Pass', (1, 5))], [])]),
|
||||
('Module', [('With', (1, 0), [('withitem', ('Name', (1, 5), 'x', ('Load',)), ('Name', (1, 10), 'y', ('Store',)))], [('Pass', (1, 13))])]),
|
||||
('Module', [('With', (1, 0), [('withitem', ('Name', (1, 5), 'x', ('Load',)), ('Name', (1, 10), 'y', ('Store',))), ('withitem', ('Name', (1, 13), 'z', ('Load',)), ('Name', (1, 18), 'q', ('Store',)))], [('Pass', (1, 21))])]),
|
||||
('Module', [('Raise', (1, 0), ('Call', (1, 6), ('Name', (1, 6), 'Exception', ('Load',)), [('Constant', (1, 16), 'string')], []), None)]),
|
||||
('Module', [('Try', (1, 0), [('Pass', (2, 2))], [('ExceptHandler', (3, 0), ('Name', (3, 7), 'Exception', ('Load',)), None, [('Pass', (4, 2))])], [], [])]),
|
||||
('Module', [('Try', (1, 0), [('Pass', (2, 2))], [], [], [('Pass', (4, 2))])]),
|
||||
('Module', [('Assert', (1, 0), ('Name', (1, 7), 'v', ('Load',)), None)]),
|
||||
('Module', [('Import', (1, 0), [('alias', 'sys', None)])]),
|
||||
('Module', [('ImportFrom', (1, 0), 'sys', [('alias', 'v', None)], 0)]),
|
||||
('Module', [('Global', (1, 0), ['v'])]),
|
||||
('Module', [('Expr', (1, 0), ('Constant', (1, 0), 1))]),
|
||||
('Module', [('Pass', (1, 0))]),
|
||||
('Module', [('For', (1, 0), ('Name', (1, 4), 'v', ('Store',)), ('Name', (1, 9), 'v', ('Load',)), [('Break', (1, 11))], [])]),
|
||||
('Module', [('For', (1, 0), ('Name', (1, 4), 'v', ('Store',)), ('Name', (1, 9), 'v', ('Load',)), [('Continue', (1, 11))], [])]),
|
||||
('Module', [('For', (1, 0), ('Tuple', (1, 4), [('Name', (1, 4), 'a', ('Store',)), ('Name', (1, 6), 'b', ('Store',))], ('Store',)), ('Name', (1, 11), 'c', ('Load',)), [('Pass', (1, 14))], [])]),
|
||||
('Module', [('For', (1, 0), ('Tuple', (1, 4), [('Name', (1, 5), 'a', ('Store',)), ('Name', (1, 7), 'b', ('Store',))], ('Store',)), ('Name', (1, 13), 'c', ('Load',)), [('Pass', (1, 16))], [])]),
|
||||
('Module', [('For', (1, 0), ('List', (1, 4), [('Name', (1, 5), 'a', ('Store',)), ('Name', (1, 7), 'b', ('Store',))], ('Store',)), ('Name', (1, 13), 'c', ('Load',)), [('Pass', (1, 16))], [])]),
|
||||
('Module', [('Expr', (1, 0), ('GeneratorExp', (1, 0), ('Tuple', (2, 4), [('Name', (3, 4), 'Aa', ('Load',)), ('Name', (5, 7), 'Bb', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (8, 4), [('Name', (8, 4), 'Aa', ('Store',)), ('Name', (10, 4), 'Bb', ('Store',))], ('Store',)), ('Name', (10, 10), 'Cc', ('Load',)), [], 0)]))]),
|
||||
('Module', [('Expr', (1, 0), ('DictComp', (1, 0), ('Name', (1, 1), 'a', ('Load',)), ('Name', (1, 5), 'b', ('Load',)), [('comprehension', ('Name', (1, 11), 'w', ('Store',)), ('Name', (1, 16), 'x', ('Load',)), [], 0), ('comprehension', ('Name', (1, 22), 'm', ('Store',)), ('Name', (1, 27), 'p', ('Load',)), [('Name', (1, 32), 'g', ('Load',))], 0)]))]),
|
||||
('Module', [('Expr', (1, 0), ('DictComp', (1, 0), ('Name', (1, 1), 'a', ('Load',)), ('Name', (1, 5), 'b', ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 11), 'v', ('Store',)), ('Name', (1, 13), 'w', ('Store',))], ('Store',)), ('Name', (1, 18), 'x', ('Load',)), [], 0)]))]),
|
||||
('Module', [('Expr', (1, 0), ('SetComp', (1, 0), ('Name', (1, 1), 'r', ('Load',)), [('comprehension', ('Name', (1, 7), 'l', ('Store',)), ('Name', (1, 12), 'x', ('Load',)), [('Name', (1, 17), 'g', ('Load',))], 0)]))]),
|
||||
('Module', [('Expr', (1, 0), ('SetComp', (1, 0), ('Name', (1, 1), 'r', ('Load',)), [('comprehension', ('Tuple', (1, 7), [('Name', (1, 7), 'l', ('Store',)), ('Name', (1, 9), 'm', ('Store',))], ('Store',)), ('Name', (1, 14), 'x', ('Load',)), [], 0)]))]),
|
||||
('Module', [('AsyncFunctionDef', (1, 0), 'f', ('arguments', [], None, [], [], None, []), [('Expr', (2, 1), ('Constant', (2, 1), 'async function')), ('Expr', (3, 1), ('Await', (3, 1), ('Call', (3, 7), ('Name', (3, 7), 'something', ('Load',)), [], [])))], [], None)]),
|
||||
('Module', [('AsyncFunctionDef', (1, 0), 'f', ('arguments', [], None, [], [], None, []), [('AsyncFor', (2, 1), ('Name', (2, 11), 'e', ('Store',)), ('Name', (2, 16), 'i', ('Load',)), [('Expr', (2, 19), ('Constant', (2, 19), 1))], [('Expr', (3, 7), ('Constant', (3, 7), 2))])], [], None)]),
|
||||
('Module', [('AsyncFunctionDef', (1, 0), 'f', ('arguments', [], None, [], [], None, []), [('AsyncWith', (2, 1), [('withitem', ('Name', (2, 12), 'a', ('Load',)), ('Name', (2, 17), 'b', ('Store',)))], [('Expr', (2, 20), ('Constant', (2, 20), 1))])], [], None)]),
|
||||
('Module', [('Expr', (1, 0), ('Dict', (1, 0), [None, ('Constant', (1, 10), 2)], [('Dict', (1, 3), [('Constant', (1, 4), 1)], [('Constant', (1, 6), 2)]), ('Constant', (1, 12), 3)]))]),
|
||||
('Module', [('Expr', (1, 0), ('Set', (1, 0), [('Starred', (1, 1), ('Set', (1, 2), [('Constant', (1, 3), 1), ('Constant', (1, 6), 2)]), ('Load',)), ('Constant', (1, 10), 3)]))]),
|
||||
('Module', [('AsyncFunctionDef', (1, 0), 'f', ('arguments', [], None, [], [], None, []), [('Expr', (2, 1), ('ListComp', (2, 1), ('Name', (2, 2), 'i', ('Load',)), [('comprehension', ('Name', (2, 14), 'b', ('Store',)), ('Name', (2, 19), 'c', ('Load',)), [], 1)]))], [], None)]),
|
||||
('Module', [('FunctionDef', (3, 0), 'f', ('arguments', [], None, [], [], None, []), [('Pass', (3, 9))], [('Name', (1, 1), 'deco1', ('Load',)), ('Call', (2, 0), ('Name', (2, 1), 'deco2', ('Load',)), [], [])], None)]),
|
||||
('Module', [('AsyncFunctionDef', (3, 0), 'f', ('arguments', [], None, [], [], None, []), [('Pass', (3, 15))], [('Name', (1, 1), 'deco1', ('Load',)), ('Call', (2, 0), ('Name', (2, 1), 'deco2', ('Load',)), [], [])], None)]),
|
||||
('Module', [('ClassDef', (3, 0), 'C', [], [], [('Pass', (3, 9))], [('Name', (1, 1), 'deco1', ('Load',)), ('Call', (2, 0), ('Name', (2, 1), 'deco2', ('Load',)), [], [])])]),
|
||||
('Module', [('FunctionDef', (2, 0), 'f', ('arguments', [], None, [], [], None, []), [('Pass', (2, 9))], [('Call', (1, 1), ('Name', (1, 1), 'deco', ('Load',)), [('GeneratorExp', (1, 5), ('Name', (1, 6), 'a', ('Load',)), [('comprehension', ('Name', (1, 12), 'a', ('Store',)), ('Name', (1, 17), 'b', ('Load',)), [], 0)])], [])], None)]),
|
||||
('Module', [('Expr', (1, 0), ('Constant', (1, 0), None))], []),
|
||||
('Module', [('Expr', (1, 0), ('Constant', (1, 0), 'module docstring'))], []),
|
||||
('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, [], [], None, []), [('Pass', (1, 9))], [], None, None)], []),
|
||||
('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, [], [], None, []), [('Expr', (1, 9), ('Constant', (1, 9), 'function docstring'))], [], None, None)], []),
|
||||
('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None, None)], None, [], [], None, []), [('Pass', (1, 10))], [], None, None)], []),
|
||||
('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None, None)], None, [], [], None, [('Constant', (1, 8), 0)]), [('Pass', (1, 12))], [], None, None)], []),
|
||||
('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], ('arg', (1, 7), 'args', None, None), [], [], None, []), [('Pass', (1, 14))], [], None, None)], []),
|
||||
('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, [], [], ('arg', (1, 8), 'kwargs', None, None), []), [('Pass', (1, 17))], [], None, None)], []),
|
||||
('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [('arg', (1, 6), 'a', None, None), ('arg', (1, 9), 'b', None, None), ('arg', (1, 14), 'c', None, None), ('arg', (1, 22), 'd', None, None), ('arg', (1, 28), 'e', None, None)], ('arg', (1, 35), 'args', None, None), [('arg', (1, 41), 'f', None, None)], [('Constant', (1, 43), 42)], ('arg', (1, 49), 'kwargs', None, None), [('Constant', (1, 11), 1), ('Constant', (1, 16), None), ('List', (1, 24), [], ('Load',)), ('Dict', (1, 30), [], [])]), [('Expr', (1, 58), ('Constant', (1, 58), 'doc for f()'))], [], None, None)], []),
|
||||
('Module', [('ClassDef', (1, 0), 'C', [], [], [('Pass', (1, 8))], [])], []),
|
||||
('Module', [('ClassDef', (1, 0), 'C', [], [], [('Expr', (1, 9), ('Constant', (1, 9), 'docstring for class C'))], [])], []),
|
||||
('Module', [('ClassDef', (1, 0), 'C', [('Name', (1, 8), 'object', ('Load',))], [], [('Pass', (1, 17))], [])], []),
|
||||
('Module', [('FunctionDef', (1, 0), 'f', ('arguments', [], None, [], [], None, []), [('Return', (1, 8), ('Constant', (1, 15), 1))], [], None, None)], []),
|
||||
('Module', [('Delete', (1, 0), [('Name', (1, 4), 'v', ('Del',))])], []),
|
||||
('Module', [('Assign', (1, 0), [('Name', (1, 0), 'v', ('Store',))], ('Constant', (1, 4), 1), None)], []),
|
||||
('Module', [('Assign', (1, 0), [('Tuple', (1, 0), [('Name', (1, 0), 'a', ('Store',)), ('Name', (1, 2), 'b', ('Store',))], ('Store',))], ('Name', (1, 6), 'c', ('Load',)), None)], []),
|
||||
('Module', [('Assign', (1, 0), [('Tuple', (1, 0), [('Name', (1, 1), 'a', ('Store',)), ('Name', (1, 3), 'b', ('Store',))], ('Store',))], ('Name', (1, 8), 'c', ('Load',)), None)], []),
|
||||
('Module', [('Assign', (1, 0), [('List', (1, 0), [('Name', (1, 1), 'a', ('Store',)), ('Name', (1, 3), 'b', ('Store',))], ('Store',))], ('Name', (1, 8), 'c', ('Load',)), None)], []),
|
||||
('Module', [('AugAssign', (1, 0), ('Name', (1, 0), 'v', ('Store',)), ('Add',), ('Constant', (1, 5), 1))], []),
|
||||
('Module', [('For', (1, 0), ('Name', (1, 4), 'v', ('Store',)), ('Name', (1, 9), 'v', ('Load',)), [('Pass', (1, 11))], [], None)], []),
|
||||
('Module', [('While', (1, 0), ('Name', (1, 6), 'v', ('Load',)), [('Pass', (1, 8))], [])], []),
|
||||
('Module', [('If', (1, 0), ('Name', (1, 3), 'v', ('Load',)), [('Pass', (1, 5))], [])], []),
|
||||
('Module', [('With', (1, 0), [('withitem', ('Name', (1, 5), 'x', ('Load',)), ('Name', (1, 10), 'y', ('Store',)))], [('Pass', (1, 13))], None)], []),
|
||||
('Module', [('With', (1, 0), [('withitem', ('Name', (1, 5), 'x', ('Load',)), ('Name', (1, 10), 'y', ('Store',))), ('withitem', ('Name', (1, 13), 'z', ('Load',)), ('Name', (1, 18), 'q', ('Store',)))], [('Pass', (1, 21))], None)], []),
|
||||
('Module', [('Raise', (1, 0), ('Call', (1, 6), ('Name', (1, 6), 'Exception', ('Load',)), [('Constant', (1, 16), 'string')], []), None)], []),
|
||||
('Module', [('Try', (1, 0), [('Pass', (2, 2))], [('ExceptHandler', (3, 0), ('Name', (3, 7), 'Exception', ('Load',)), None, [('Pass', (4, 2))])], [], [])], []),
|
||||
('Module', [('Try', (1, 0), [('Pass', (2, 2))], [], [], [('Pass', (4, 2))])], []),
|
||||
('Module', [('Assert', (1, 0), ('Name', (1, 7), 'v', ('Load',)), None)], []),
|
||||
('Module', [('Import', (1, 0), [('alias', 'sys', None)])], []),
|
||||
('Module', [('ImportFrom', (1, 0), 'sys', [('alias', 'v', None)], 0)], []),
|
||||
('Module', [('Global', (1, 0), ['v'])], []),
|
||||
('Module', [('Expr', (1, 0), ('Constant', (1, 0), 1))], []),
|
||||
('Module', [('Pass', (1, 0))], []),
|
||||
('Module', [('For', (1, 0), ('Name', (1, 4), 'v', ('Store',)), ('Name', (1, 9), 'v', ('Load',)), [('Break', (1, 11))], [], None)], []),
|
||||
('Module', [('For', (1, 0), ('Name', (1, 4), 'v', ('Store',)), ('Name', (1, 9), 'v', ('Load',)), [('Continue', (1, 11))], [], None)], []),
|
||||
('Module', [('For', (1, 0), ('Tuple', (1, 4), [('Name', (1, 4), 'a', ('Store',)), ('Name', (1, 6), 'b', ('Store',))], ('Store',)), ('Name', (1, 11), 'c', ('Load',)), [('Pass', (1, 14))], [], None)], []),
|
||||
('Module', [('For', (1, 0), ('Tuple', (1, 4), [('Name', (1, 5), 'a', ('Store',)), ('Name', (1, 7), 'b', ('Store',))], ('Store',)), ('Name', (1, 13), 'c', ('Load',)), [('Pass', (1, 16))], [], None)], []),
|
||||
('Module', [('For', (1, 0), ('List', (1, 4), [('Name', (1, 5), 'a', ('Store',)), ('Name', (1, 7), 'b', ('Store',))], ('Store',)), ('Name', (1, 13), 'c', ('Load',)), [('Pass', (1, 16))], [], None)], []),
|
||||
('Module', [('Expr', (1, 0), ('GeneratorExp', (1, 0), ('Tuple', (2, 4), [('Name', (3, 4), 'Aa', ('Load',)), ('Name', (5, 7), 'Bb', ('Load',))], ('Load',)), [('comprehension', ('Tuple', (8, 4), [('Name', (8, 4), 'Aa', ('Store',)), ('Name', (10, 4), 'Bb', ('Store',))], ('Store',)), ('Name', (10, 10), 'Cc', ('Load',)), [], 0)]))], []),
|
||||
('Module', [('Expr', (1, 0), ('DictComp', (1, 0), ('Name', (1, 1), 'a', ('Load',)), ('Name', (1, 5), 'b', ('Load',)), [('comprehension', ('Name', (1, 11), 'w', ('Store',)), ('Name', (1, 16), 'x', ('Load',)), [], 0), ('comprehension', ('Name', (1, 22), 'm', ('Store',)), ('Name', (1, 27), 'p', ('Load',)), [('Name', (1, 32), 'g', ('Load',))], 0)]))], []),
|
||||
('Module', [('Expr', (1, 0), ('DictComp', (1, 0), ('Name', (1, 1), 'a', ('Load',)), ('Name', (1, 5), 'b', ('Load',)), [('comprehension', ('Tuple', (1, 11), [('Name', (1, 11), 'v', ('Store',)), ('Name', (1, 13), 'w', ('Store',))], ('Store',)), ('Name', (1, 18), 'x', ('Load',)), [], 0)]))], []),
|
||||
('Module', [('Expr', (1, 0), ('SetComp', (1, 0), ('Name', (1, 1), 'r', ('Load',)), [('comprehension', ('Name', (1, 7), 'l', ('Store',)), ('Name', (1, 12), 'x', ('Load',)), [('Name', (1, 17), 'g', ('Load',))], 0)]))], []),
|
||||
('Module', [('Expr', (1, 0), ('SetComp', (1, 0), ('Name', (1, 1), 'r', ('Load',)), [('comprehension', ('Tuple', (1, 7), [('Name', (1, 7), 'l', ('Store',)), ('Name', (1, 9), 'm', ('Store',))], ('Store',)), ('Name', (1, 14), 'x', ('Load',)), [], 0)]))], []),
|
||||
('Module', [('AsyncFunctionDef', (1, 0), 'f', ('arguments', [], None, [], [], None, []), [('Expr', (2, 1), ('Constant', (2, 1), 'async function')), ('Expr', (3, 1), ('Await', (3, 1), ('Call', (3, 7), ('Name', (3, 7), 'something', ('Load',)), [], [])))], [], None, None)], []),
|
||||
('Module', [('AsyncFunctionDef', (1, 0), 'f', ('arguments', [], None, [], [], None, []), [('AsyncFor', (2, 1), ('Name', (2, 11), 'e', ('Store',)), ('Name', (2, 16), 'i', ('Load',)), [('Expr', (2, 19), ('Constant', (2, 19), 1))], [('Expr', (3, 7), ('Constant', (3, 7), 2))], None)], [], None, None)], []),
|
||||
('Module', [('AsyncFunctionDef', (1, 0), 'f', ('arguments', [], None, [], [], None, []), [('AsyncWith', (2, 1), [('withitem', ('Name', (2, 12), 'a', ('Load',)), ('Name', (2, 17), 'b', ('Store',)))], [('Expr', (2, 20), ('Constant', (2, 20), 1))], None)], [], None, None)], []),
|
||||
('Module', [('Expr', (1, 0), ('Dict', (1, 0), [None, ('Constant', (1, 10), 2)], [('Dict', (1, 3), [('Constant', (1, 4), 1)], [('Constant', (1, 6), 2)]), ('Constant', (1, 12), 3)]))], []),
|
||||
('Module', [('Expr', (1, 0), ('Set', (1, 0), [('Starred', (1, 1), ('Set', (1, 2), [('Constant', (1, 3), 1), ('Constant', (1, 6), 2)]), ('Load',)), ('Constant', (1, 10), 3)]))], []),
|
||||
('Module', [('AsyncFunctionDef', (1, 0), 'f', ('arguments', [], None, [], [], None, []), [('Expr', (2, 1), ('ListComp', (2, 1), ('Name', (2, 2), 'i', ('Load',)), [('comprehension', ('Name', (2, 14), 'b', ('Store',)), ('Name', (2, 19), 'c', ('Load',)), [], 1)]))], [], None, None)], []),
|
||||
('Module', [('FunctionDef', (3, 0), 'f', ('arguments', [], None, [], [], None, []), [('Pass', (3, 9))], [('Name', (1, 1), 'deco1', ('Load',)), ('Call', (2, 0), ('Name', (2, 1), 'deco2', ('Load',)), [], [])], None, None)], []),
|
||||
('Module', [('AsyncFunctionDef', (3, 0), 'f', ('arguments', [], None, [], [], None, []), [('Pass', (3, 15))], [('Name', (1, 1), 'deco1', ('Load',)), ('Call', (2, 0), ('Name', (2, 1), 'deco2', ('Load',)), [], [])], None, None)], []),
|
||||
('Module', [('ClassDef', (3, 0), 'C', [], [], [('Pass', (3, 9))], [('Name', (1, 1), 'deco1', ('Load',)), ('Call', (2, 0), ('Name', (2, 1), 'deco2', ('Load',)), [], [])])], []),
|
||||
('Module', [('FunctionDef', (2, 0), 'f', ('arguments', [], None, [], [], None, []), [('Pass', (2, 9))], [('Call', (1, 1), ('Name', (1, 1), 'deco', ('Load',)), [('GeneratorExp', (1, 5), ('Name', (1, 6), 'a', ('Load',)), [('comprehension', ('Name', (1, 12), 'a', ('Store',)), ('Name', (1, 17), 'b', ('Load',)), [], 0)])], [])], None, None)], []),
|
||||
]
|
||||
single_results = [
|
||||
('Interactive', [('Expr', (1, 0), ('BinOp', (1, 0), ('Constant', (1, 0), 1), ('Add',), ('Constant', (1, 2), 2)))]),
|
||||
|
|
|
@ -0,0 +1,295 @@
|
|||
import ast
|
||||
import unittest
|
||||
|
||||
|
||||
funcdef = """\
|
||||
def foo():
|
||||
# type: () -> int
|
||||
pass
|
||||
|
||||
def bar(): # type: () -> None
|
||||
pass
|
||||
"""
|
||||
|
||||
asyncdef = """\
|
||||
async def foo():
|
||||
# type: () -> int
|
||||
return await bar()
|
||||
|
||||
async def bar(): # type: () -> int
|
||||
return await bar()
|
||||
"""
|
||||
|
||||
redundantdef = """\
|
||||
def foo(): # type: () -> int
|
||||
# type: () -> str
|
||||
return ''
|
||||
"""
|
||||
|
||||
nonasciidef = """\
|
||||
def foo():
|
||||
# type: () -> àçčéñt
|
||||
pass
|
||||
"""
|
||||
|
||||
forstmt = """\
|
||||
for a in []: # type: int
|
||||
pass
|
||||
"""
|
||||
|
||||
withstmt = """\
|
||||
with context() as a: # type: int
|
||||
pass
|
||||
"""
|
||||
|
||||
vardecl = """\
|
||||
a = 0 # type: int
|
||||
"""
|
||||
|
||||
ignores = """\
|
||||
def foo():
|
||||
pass # type: ignore
|
||||
|
||||
def bar():
|
||||
x = 1 # type: ignore
|
||||
"""
|
||||
|
||||
# Test for long-form type-comments in arguments. A test function
|
||||
# named 'fabvk' would have two positional args, a and b, plus a
|
||||
# var-arg *v, plus a kw-arg **k. It is verified in test_longargs()
|
||||
# that it has exactly these arguments, no more, no fewer.
|
||||
longargs = """\
|
||||
def fa(
|
||||
a = 1, # type: A
|
||||
):
|
||||
pass
|
||||
|
||||
def fa(
|
||||
a = 1 # type: A
|
||||
):
|
||||
pass
|
||||
|
||||
def fab(
|
||||
a, # type: A
|
||||
b, # type: B
|
||||
):
|
||||
pass
|
||||
|
||||
def fab(
|
||||
a, # type: A
|
||||
b # type: B
|
||||
):
|
||||
pass
|
||||
|
||||
def fv(
|
||||
*v, # type: V
|
||||
):
|
||||
pass
|
||||
|
||||
def fv(
|
||||
*v # type: V
|
||||
):
|
||||
pass
|
||||
|
||||
def fk(
|
||||
**k, # type: K
|
||||
):
|
||||
pass
|
||||
|
||||
def fk(
|
||||
**k # type: K
|
||||
):
|
||||
pass
|
||||
|
||||
def fvk(
|
||||
*v, # type: V
|
||||
**k, # type: K
|
||||
):
|
||||
pass
|
||||
|
||||
def fvk(
|
||||
*v, # type: V
|
||||
**k # type: K
|
||||
):
|
||||
pass
|
||||
|
||||
def fav(
|
||||
a, # type: A
|
||||
*v, # type: V
|
||||
):
|
||||
pass
|
||||
|
||||
def fav(
|
||||
a, # type: A
|
||||
*v # type: V
|
||||
):
|
||||
pass
|
||||
|
||||
def fak(
|
||||
a, # type: A
|
||||
**k, # type: K
|
||||
):
|
||||
pass
|
||||
|
||||
def fak(
|
||||
a, # type: A
|
||||
**k # type: K
|
||||
):
|
||||
pass
|
||||
|
||||
def favk(
|
||||
a, # type: A
|
||||
*v, # type: V
|
||||
**k, # type: K
|
||||
):
|
||||
pass
|
||||
|
||||
def favk(
|
||||
a, # type: A
|
||||
*v, # type: V
|
||||
**k # type: K
|
||||
):
|
||||
pass
|
||||
"""
|
||||
|
||||
|
||||
class TypeCommentTests(unittest.TestCase):
|
||||
|
||||
def parse(self, source):
|
||||
return ast.parse(source, type_comments=True)
|
||||
|
||||
def classic_parse(self, source):
|
||||
return ast.parse(source)
|
||||
|
||||
def test_funcdef(self):
|
||||
tree = self.parse(funcdef)
|
||||
self.assertEqual(tree.body[0].type_comment, "() -> int")
|
||||
self.assertEqual(tree.body[1].type_comment, "() -> None")
|
||||
tree = self.classic_parse(funcdef)
|
||||
self.assertEqual(tree.body[0].type_comment, None)
|
||||
self.assertEqual(tree.body[1].type_comment, None)
|
||||
|
||||
def test_asyncdef(self):
|
||||
tree = self.parse(asyncdef)
|
||||
self.assertEqual(tree.body[0].type_comment, "() -> int")
|
||||
self.assertEqual(tree.body[1].type_comment, "() -> int")
|
||||
tree = self.classic_parse(asyncdef)
|
||||
self.assertEqual(tree.body[0].type_comment, None)
|
||||
self.assertEqual(tree.body[1].type_comment, None)
|
||||
|
||||
def test_redundantdef(self):
|
||||
with self.assertRaisesRegex(SyntaxError, "^Cannot have two type comments on def"):
|
||||
tree = self.parse(redundantdef)
|
||||
|
||||
def test_nonasciidef(self):
|
||||
tree = self.parse(nonasciidef)
|
||||
self.assertEqual(tree.body[0].type_comment, "() -> àçčéñt")
|
||||
|
||||
def test_forstmt(self):
|
||||
tree = self.parse(forstmt)
|
||||
self.assertEqual(tree.body[0].type_comment, "int")
|
||||
tree = self.classic_parse(forstmt)
|
||||
self.assertEqual(tree.body[0].type_comment, None)
|
||||
|
||||
def test_withstmt(self):
|
||||
tree = self.parse(withstmt)
|
||||
self.assertEqual(tree.body[0].type_comment, "int")
|
||||
tree = self.classic_parse(withstmt)
|
||||
self.assertEqual(tree.body[0].type_comment, None)
|
||||
|
||||
def test_vardecl(self):
|
||||
tree = self.parse(vardecl)
|
||||
self.assertEqual(tree.body[0].type_comment, "int")
|
||||
tree = self.classic_parse(vardecl)
|
||||
self.assertEqual(tree.body[0].type_comment, None)
|
||||
|
||||
def test_ignores(self):
|
||||
tree = self.parse(ignores)
|
||||
self.assertEqual([ti.lineno for ti in tree.type_ignores], [2, 5])
|
||||
tree = self.classic_parse(ignores)
|
||||
self.assertEqual(tree.type_ignores, [])
|
||||
|
||||
def test_longargs(self):
|
||||
tree = self.parse(longargs)
|
||||
for t in tree.body:
|
||||
# The expected args are encoded in the function name
|
||||
todo = set(t.name[1:])
|
||||
self.assertEqual(len(t.args.args),
|
||||
len(todo) - bool(t.args.vararg) - bool(t.args.kwarg))
|
||||
self.assertTrue(t.name.startswith('f'), t.name)
|
||||
for c in t.name[1:]:
|
||||
todo.remove(c)
|
||||
if c == 'v':
|
||||
arg = t.args.vararg
|
||||
elif c == 'k':
|
||||
arg = t.args.kwarg
|
||||
else:
|
||||
assert 0 <= ord(c) - ord('a') < len(t.args.args)
|
||||
arg = t.args.args[ord(c) - ord('a')]
|
||||
self.assertEqual(arg.arg, c) # That's the argument name
|
||||
self.assertEqual(arg.type_comment, arg.arg.upper())
|
||||
assert not todo
|
||||
tree = self.classic_parse(longargs)
|
||||
for t in tree.body:
|
||||
for arg in t.args.args + [t.args.vararg, t.args.kwarg]:
|
||||
if arg is not None:
|
||||
self.assertIsNone(arg.type_comment, "%s(%s:%r)" %
|
||||
(t.name, arg.arg, arg.type_comment))
|
||||
|
||||
def test_inappropriate_type_comments(self):
|
||||
"""Tests for inappropriately-placed type comments.
|
||||
|
||||
These should be silently ignored with type comments off,
|
||||
but raise SyntaxError with type comments on.
|
||||
|
||||
This is not meant to be exhaustive.
|
||||
"""
|
||||
|
||||
def check_both_ways(source):
|
||||
ast.parse(source, type_comments=False)
|
||||
with self.assertRaises(SyntaxError):
|
||||
ast.parse(source, type_comments=True)
|
||||
|
||||
check_both_ways("pass # type: int\n")
|
||||
check_both_ways("foo() # type: int\n")
|
||||
check_both_ways("x += 1 # type: int\n")
|
||||
check_both_ways("while True: # type: int\n continue\n")
|
||||
check_both_ways("while True:\n continue # type: int\n")
|
||||
check_both_ways("try: # type: int\n pass\nfinally:\n pass\n")
|
||||
check_both_ways("try:\n pass\nfinally: # type: int\n pass\n")
|
||||
|
||||
def test_func_type_input(self):
|
||||
|
||||
def parse_func_type_input(source):
|
||||
return ast.parse(source, "<unknown>", "func_type")
|
||||
|
||||
# Some checks below will crash if the returned structure is wrong
|
||||
tree = parse_func_type_input("() -> int")
|
||||
self.assertEqual(tree.argtypes, [])
|
||||
self.assertEqual(tree.returns.id, "int")
|
||||
|
||||
tree = parse_func_type_input("(int) -> List[str]")
|
||||
self.assertEqual(len(tree.argtypes), 1)
|
||||
arg = tree.argtypes[0]
|
||||
self.assertEqual(arg.id, "int")
|
||||
self.assertEqual(tree.returns.value.id, "List")
|
||||
self.assertEqual(tree.returns.slice.value.id, "str")
|
||||
|
||||
tree = parse_func_type_input("(int, *str, **Any) -> float")
|
||||
self.assertEqual(tree.argtypes[0].id, "int")
|
||||
self.assertEqual(tree.argtypes[1].id, "str")
|
||||
self.assertEqual(tree.argtypes[2].id, "Any")
|
||||
self.assertEqual(tree.returns.id, "float")
|
||||
|
||||
with self.assertRaises(SyntaxError):
|
||||
tree = parse_func_type_input("(int, *str, *Any) -> float")
|
||||
|
||||
with self.assertRaises(SyntaxError):
|
||||
tree = parse_func_type_input("(int, **str, Any) -> float")
|
||||
|
||||
with self.assertRaises(SyntaxError):
|
||||
tree = parse_func_type_input("(**int, **str) -> float")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
|
@ -58,12 +58,14 @@ RARROW = 51
|
|||
ELLIPSIS = 52
|
||||
COLONEQUAL = 53
|
||||
OP = 54
|
||||
TYPE_IGNORE = 55
|
||||
TYPE_COMMENT = 56
|
||||
# These aren't used by the C tokenizer but are needed for tokenize.py
|
||||
ERRORTOKEN = 55
|
||||
COMMENT = 56
|
||||
NL = 57
|
||||
ENCODING = 58
|
||||
N_TOKENS = 59
|
||||
ERRORTOKEN = 57
|
||||
COMMENT = 58
|
||||
NL = 59
|
||||
ENCODING = 60
|
||||
N_TOKENS = 61
|
||||
# Special definitions for cooperation with parser
|
||||
NT_OFFSET = 256
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Add the option to parse PEP 484 type comments in the ast module. (Off by default.) This is merging the key functionality of the third party fork thereof, [typed_ast](https://github.com/python/typed_ast).
|
|
@ -663,6 +663,12 @@ validate_node(node *tree)
|
|||
for (pos = 0; pos < nch; ++pos) {
|
||||
node *ch = CHILD(tree, pos);
|
||||
int ch_type = TYPE(ch);
|
||||
if (ch_type == suite && TYPE(tree) == funcdef) {
|
||||
/* This is the opposite hack of what we do in parser.c
|
||||
(search for func_body_suite), except we don't ever
|
||||
support type comments here. */
|
||||
ch_type = func_body_suite;
|
||||
}
|
||||
for (arc = 0; arc < dfa_state->s_narcs; ++arc) {
|
||||
short a_label = dfa_state->s_arc[arc].a_lbl;
|
||||
assert(a_label < _PyParser_Grammar.g_ll.ll_nlabels);
|
||||
|
|
|
@ -3,17 +3,20 @@
|
|||
|
||||
module Python
|
||||
{
|
||||
mod = Module(stmt* body)
|
||||
mod = Module(stmt* body, type_ignore *type_ignores)
|
||||
| Interactive(stmt* body)
|
||||
| Expression(expr body)
|
||||
| FunctionType(expr* argtypes, expr returns)
|
||||
|
||||
-- not really an actual node but useful in Jython's typesystem.
|
||||
| Suite(stmt* body)
|
||||
|
||||
stmt = FunctionDef(identifier name, arguments args,
|
||||
stmt* body, expr* decorator_list, expr? returns)
|
||||
stmt* body, expr* decorator_list, expr? returns,
|
||||
string? type_comment)
|
||||
| AsyncFunctionDef(identifier name, arguments args,
|
||||
stmt* body, expr* decorator_list, expr? returns)
|
||||
stmt* body, expr* decorator_list, expr? returns,
|
||||
string? type_comment)
|
||||
|
||||
| ClassDef(identifier name,
|
||||
expr* bases,
|
||||
|
@ -23,18 +26,18 @@ module Python
|
|||
| Return(expr? value)
|
||||
|
||||
| Delete(expr* targets)
|
||||
| Assign(expr* targets, expr value)
|
||||
| Assign(expr* targets, expr value, string? type_comment)
|
||||
| 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)
|
||||
|
||||
-- use 'orelse' because else is a keyword in target languages
|
||||
| For(expr target, expr iter, stmt* body, stmt* orelse)
|
||||
| AsyncFor(expr target, expr iter, stmt* body, stmt* orelse)
|
||||
| For(expr target, expr iter, stmt* body, stmt* orelse, string? type_comment)
|
||||
| AsyncFor(expr target, expr iter, stmt* body, stmt* orelse, string? type_comment)
|
||||
| While(expr test, stmt* body, stmt* orelse)
|
||||
| If(expr test, stmt* body, stmt* orelse)
|
||||
| With(withitem* items, stmt* body)
|
||||
| AsyncWith(withitem* items, stmt* body)
|
||||
| With(withitem* items, stmt* body, string? type_comment)
|
||||
| AsyncWith(withitem* items, stmt* body, string? type_comment)
|
||||
|
||||
| Raise(expr? exc, expr? cause)
|
||||
| Try(stmt* body, excepthandler* handlers, stmt* orelse, stmt* finalbody)
|
||||
|
@ -111,7 +114,7 @@ module Python
|
|||
arguments = (arg* args, arg? vararg, arg* kwonlyargs, expr* kw_defaults,
|
||||
arg? kwarg, expr* defaults)
|
||||
|
||||
arg = (identifier arg, expr? annotation)
|
||||
arg = (identifier arg, expr? annotation, string? type_comment)
|
||||
attributes (int lineno, int col_offset, int? end_lineno, int? end_col_offset)
|
||||
|
||||
-- keyword arguments supplied to call (NULL identifier for **kwargs)
|
||||
|
@ -121,5 +124,7 @@ module Python
|
|||
alias = (identifier name, identifier? asname)
|
||||
|
||||
withitem = (expr context_expr, expr? optional_vars)
|
||||
|
||||
type_ignore = TypeIgnore(int lineno)
|
||||
}
|
||||
|
||||
|
|
|
@ -890,6 +890,15 @@ static int obj2ast_identifier(PyObject* obj, PyObject** out, PyArena* arena)
|
|||
return obj2ast_object(obj, out, arena);
|
||||
}
|
||||
|
||||
static int obj2ast_string(PyObject* obj, PyObject** out, PyArena* arena)
|
||||
{
|
||||
if (!PyUnicode_CheckExact(obj) && !PyBytes_CheckExact(obj)) {
|
||||
PyErr_SetString(PyExc_TypeError, "AST string must be of type str");
|
||||
return 1;
|
||||
}
|
||||
return obj2ast_object(obj, out, arena);
|
||||
}
|
||||
|
||||
static int obj2ast_int(PyObject* obj, int* out, PyArena* arena)
|
||||
{
|
||||
int i;
|
||||
|
@ -993,6 +1002,8 @@ class ASTModuleVisitor(PickleVisitor):
|
|||
self.emit('if (PyDict_SetItemString(d, "AST", (PyObject*)&AST_type) < 0) return NULL;', 1)
|
||||
self.emit('if (PyModule_AddIntMacro(m, PyCF_ONLY_AST) < 0)', 1)
|
||||
self.emit("return NULL;", 2)
|
||||
self.emit('if (PyModule_AddIntMacro(m, PyCF_TYPE_COMMENTS) < 0)', 1)
|
||||
self.emit("return NULL;", 2)
|
||||
for dfn in mod.dfns:
|
||||
self.visit(dfn)
|
||||
self.emit("return m;", 1)
|
||||
|
@ -1176,18 +1187,19 @@ PyObject* PyAST_mod2obj(mod_ty t)
|
|||
}
|
||||
|
||||
/* mode is 0 for "exec", 1 for "eval" and 2 for "single" input */
|
||||
/* and 3 for "func_type" */
|
||||
mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena, int mode)
|
||||
{
|
||||
mod_ty res;
|
||||
PyObject *req_type[3];
|
||||
char *req_name[] = {"Module", "Expression", "Interactive"};
|
||||
char *req_name[] = {"Module", "Expression", "Interactive", "FunctionType"};
|
||||
int isinstance;
|
||||
|
||||
req_type[0] = (PyObject*)Module_type;
|
||||
req_type[1] = (PyObject*)Expression_type;
|
||||
req_type[2] = (PyObject*)Interactive_type;
|
||||
|
||||
assert(0 <= mode && mode <= 2);
|
||||
assert(0 <= mode && mode <= 3);
|
||||
|
||||
if (!init_types())
|
||||
return NULL;
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "node.h"
|
||||
#include "parser.h"
|
||||
#include "errcode.h"
|
||||
#include "graminit.h"
|
||||
|
||||
|
||||
#ifdef Py_DEBUG
|
||||
|
@ -260,7 +261,15 @@ PyParser_AddToken(parser_state *ps, int type, char *str,
|
|||
/* Push non-terminal */
|
||||
int nt = (x >> 8) + NT_OFFSET;
|
||||
int arrow = x & ((1<<7)-1);
|
||||
dfa *d1 = PyGrammar_FindDFA(
|
||||
dfa *d1;
|
||||
if (nt == func_body_suite && !(ps->p_flags & PyCF_TYPE_COMMENTS)) {
|
||||
/* When parsing type comments is not requested,
|
||||
we can provide better errors about bad indentation
|
||||
by using 'suite' for the body of a funcdef */
|
||||
D(printf(" [switch func_body_suite to suite]"));
|
||||
nt = suite;
|
||||
}
|
||||
d1 = PyGrammar_FindDFA(
|
||||
ps->p_grammar, nt);
|
||||
if ((err = push(&ps->p_stack, nt, d1,
|
||||
arrow, lineno, col_offset,
|
||||
|
@ -268,7 +277,7 @@ PyParser_AddToken(parser_state *ps, int type, char *str,
|
|||
D(printf(" MemError: push\n"));
|
||||
return err;
|
||||
}
|
||||
D(printf(" Push ...\n"));
|
||||
D(printf(" Push '%s'\n", d1->d_name));
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,42 @@
|
|||
static node *parsetok(struct tok_state *, grammar *, int, perrdetail *, int *);
|
||||
static int initerr(perrdetail *err_ret, PyObject * filename);
|
||||
|
||||
typedef struct {
|
||||
int *items;
|
||||
size_t size;
|
||||
size_t num_items;
|
||||
} growable_int_array;
|
||||
|
||||
static int
|
||||
growable_int_array_init(growable_int_array *arr, size_t initial_size) {
|
||||
assert(initial_size > 0);
|
||||
arr->items = malloc(initial_size * sizeof(*arr->items));
|
||||
arr->size = initial_size;
|
||||
arr->num_items = 0;
|
||||
|
||||
return arr->items != NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
growable_int_array_add(growable_int_array *arr, int item) {
|
||||
if (arr->num_items >= arr->size) {
|
||||
arr->size *= 2;
|
||||
arr->items = realloc(arr->items, arr->size * sizeof(*arr->items));
|
||||
if (!arr->items) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
arr->items[arr->num_items] = item;
|
||||
arr->num_items++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
growable_int_array_deallocate(growable_int_array *arr) {
|
||||
free(arr->items);
|
||||
}
|
||||
|
||||
/* Parse input coming from a string. Return error code, print some errors. */
|
||||
node *
|
||||
PyParser_ParseString(const char *s, grammar *g, int start, perrdetail *err_ret)
|
||||
|
@ -59,6 +95,9 @@ PyParser_ParseStringObject(const char *s, PyObject *filename,
|
|||
err_ret->error = PyErr_Occurred() ? E_DECODE : E_NOMEM;
|
||||
return NULL;
|
||||
}
|
||||
if (*flags & PyPARSE_TYPE_COMMENTS) {
|
||||
tok->type_comments = 1;
|
||||
}
|
||||
|
||||
#ifndef PGEN
|
||||
Py_INCREF(err_ret->filename);
|
||||
|
@ -127,6 +166,9 @@ PyParser_ParseFileObject(FILE *fp, PyObject *filename,
|
|||
err_ret->error = E_NOMEM;
|
||||
return NULL;
|
||||
}
|
||||
if (*flags & PyPARSE_TYPE_COMMENTS) {
|
||||
tok->type_comments = 1;
|
||||
}
|
||||
#ifndef PGEN
|
||||
Py_INCREF(err_ret->filename);
|
||||
tok->filename = err_ret->filename;
|
||||
|
@ -188,6 +230,13 @@ parsetok(struct tok_state *tok, grammar *g, int start, perrdetail *err_ret,
|
|||
node *n;
|
||||
int started = 0;
|
||||
int col_offset, end_col_offset;
|
||||
growable_int_array type_ignores;
|
||||
|
||||
if (!growable_int_array_init(&type_ignores, 10)) {
|
||||
err_ret->error = E_NOMEM;
|
||||
PyTokenizer_Free(tok);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((ps = PyParser_New(g, start)) == NULL) {
|
||||
err_ret->error = E_NOMEM;
|
||||
|
@ -197,6 +246,8 @@ parsetok(struct tok_state *tok, grammar *g, int start, perrdetail *err_ret,
|
|||
#ifdef PY_PARSER_REQUIRES_FUTURE_KEYWORD
|
||||
if (*flags & PyPARSE_BARRY_AS_BDFL)
|
||||
ps->p_flags |= CO_FUTURE_BARRY_AS_BDFL;
|
||||
if (*flags & PyPARSE_TYPE_COMMENTS)
|
||||
ps->p_flags |= PyCF_TYPE_COMMENTS;
|
||||
#endif
|
||||
|
||||
for (;;) {
|
||||
|
@ -277,6 +328,15 @@ parsetok(struct tok_state *tok, grammar *g, int start, perrdetail *err_ret,
|
|||
else {
|
||||
end_col_offset = -1;
|
||||
}
|
||||
|
||||
if (type == TYPE_IGNORE) {
|
||||
if (!growable_int_array_add(&type_ignores, tok->lineno)) {
|
||||
err_ret->error = E_NOMEM;
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((err_ret->error =
|
||||
PyParser_AddToken(ps, (int)type, str,
|
||||
lineno, col_offset, tok->lineno, end_col_offset,
|
||||
|
@ -293,6 +353,24 @@ parsetok(struct tok_state *tok, grammar *g, int start, perrdetail *err_ret,
|
|||
n = ps->p_tree;
|
||||
ps->p_tree = NULL;
|
||||
|
||||
if (n->n_type == file_input) {
|
||||
/* Put type_ignore nodes in the ENDMARKER of file_input. */
|
||||
int num;
|
||||
node *ch;
|
||||
size_t i;
|
||||
|
||||
num = NCH(n);
|
||||
ch = CHILD(n, num - 1);
|
||||
REQ(ch, ENDMARKER);
|
||||
|
||||
for (i = 0; i < type_ignores.num_items; i++) {
|
||||
PyNode_AddChild(ch, TYPE_IGNORE, NULL,
|
||||
type_ignores.items[i], 0,
|
||||
type_ignores.items[i], 0);
|
||||
}
|
||||
}
|
||||
growable_int_array_deallocate(&type_ignores);
|
||||
|
||||
#ifndef PGEN
|
||||
/* Check that the source for a single input statement really
|
||||
is a single statement by looking at what is left in the
|
||||
|
|
|
@ -61,6 +61,8 @@ const char * const _PyParser_TokenNames[] = {
|
|||
"ELLIPSIS",
|
||||
"COLONEQUAL",
|
||||
"OP",
|
||||
"TYPE_IGNORE",
|
||||
"TYPE_COMMENT",
|
||||
"<ERRORTOKEN>",
|
||||
"<COMMENT>",
|
||||
"<NL>",
|
||||
|
|
|
@ -48,6 +48,10 @@ static int tok_nextc(struct tok_state *tok);
|
|||
static void tok_backup(struct tok_state *tok, int c);
|
||||
|
||||
|
||||
/* Spaces in this constant are treated as "zero or more spaces or tabs" when
|
||||
tokenizing. */
|
||||
static const char* type_comment_prefix = "# type: ";
|
||||
|
||||
/* Create and initialize a new tok_state structure */
|
||||
|
||||
static struct tok_state *
|
||||
|
@ -82,6 +86,7 @@ tok_new(void)
|
|||
tok->decoding_readline = NULL;
|
||||
tok->decoding_buffer = NULL;
|
||||
#endif
|
||||
tok->type_comments = 0;
|
||||
|
||||
return tok;
|
||||
}
|
||||
|
@ -1245,11 +1250,61 @@ tok_get(struct tok_state *tok, char **p_start, char **p_end)
|
|||
/* Set start of current token */
|
||||
tok->start = tok->cur - 1;
|
||||
|
||||
/* Skip comment */
|
||||
/* Skip comment, unless it's a type comment */
|
||||
if (c == '#') {
|
||||
const char *prefix, *p, *type_start;
|
||||
|
||||
while (c != EOF && c != '\n') {
|
||||
c = tok_nextc(tok);
|
||||
}
|
||||
|
||||
if (tok->type_comments) {
|
||||
p = tok->start;
|
||||
prefix = type_comment_prefix;
|
||||
while (*prefix && p < tok->cur) {
|
||||
if (*prefix == ' ') {
|
||||
while (*p == ' ' || *p == '\t') {
|
||||
p++;
|
||||
}
|
||||
} else if (*prefix == *p) {
|
||||
p++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
prefix++;
|
||||
}
|
||||
|
||||
/* This is a type comment if we matched all of type_comment_prefix. */
|
||||
if (!*prefix) {
|
||||
int is_type_ignore = 1;
|
||||
tok_backup(tok, c); /* don't eat the newline or EOF */
|
||||
|
||||
type_start = p;
|
||||
|
||||
is_type_ignore = tok->cur >= p + 6 && memcmp(p, "ignore", 6) == 0;
|
||||
p += 6;
|
||||
while (is_type_ignore && p < tok->cur) {
|
||||
if (*p == '#')
|
||||
break;
|
||||
is_type_ignore = is_type_ignore && (*p == ' ' || *p == '\t');
|
||||
p++;
|
||||
}
|
||||
|
||||
if (is_type_ignore) {
|
||||
/* If this type ignore is the only thing on the line, consume the newline also. */
|
||||
if (blankline) {
|
||||
tok_nextc(tok);
|
||||
tok->atbol = 1;
|
||||
}
|
||||
return TYPE_IGNORE;
|
||||
} else {
|
||||
*p_start = (char *) type_start; /* after type_comment_prefix */
|
||||
*p_end = tok->cur;
|
||||
return TYPE_COMMENT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for EOF and errors now */
|
||||
|
|
|
@ -70,6 +70,8 @@ struct tok_state {
|
|||
const char* enc; /* Encoding for the current str. */
|
||||
const char* str;
|
||||
const char* input; /* Tokenizer's newline translated copy of the string. */
|
||||
|
||||
int type_comments; /* Whether to look for type comments */
|
||||
};
|
||||
|
||||
extern struct tok_state *PyTokenizer_FromString(const char *, int);
|
||||
|
|
|
@ -10,8 +10,10 @@ static PyTypeObject *mod_type;
|
|||
static PyObject* ast2obj_mod(void*);
|
||||
static PyTypeObject *Module_type;
|
||||
_Py_IDENTIFIER(body);
|
||||
_Py_IDENTIFIER(type_ignores);
|
||||
static char *Module_fields[]={
|
||||
"body",
|
||||
"type_ignores",
|
||||
};
|
||||
static PyTypeObject *Interactive_type;
|
||||
static char *Interactive_fields[]={
|
||||
|
@ -21,6 +23,13 @@ static PyTypeObject *Expression_type;
|
|||
static char *Expression_fields[]={
|
||||
"body",
|
||||
};
|
||||
static PyTypeObject *FunctionType_type;
|
||||
_Py_IDENTIFIER(argtypes);
|
||||
_Py_IDENTIFIER(returns);
|
||||
static char *FunctionType_fields[]={
|
||||
"argtypes",
|
||||
"returns",
|
||||
};
|
||||
static PyTypeObject *Suite_type;
|
||||
static char *Suite_fields[]={
|
||||
"body",
|
||||
|
@ -41,13 +50,14 @@ static PyTypeObject *FunctionDef_type;
|
|||
_Py_IDENTIFIER(name);
|
||||
_Py_IDENTIFIER(args);
|
||||
_Py_IDENTIFIER(decorator_list);
|
||||
_Py_IDENTIFIER(returns);
|
||||
_Py_IDENTIFIER(type_comment);
|
||||
static char *FunctionDef_fields[]={
|
||||
"name",
|
||||
"args",
|
||||
"body",
|
||||
"decorator_list",
|
||||
"returns",
|
||||
"type_comment",
|
||||
};
|
||||
static PyTypeObject *AsyncFunctionDef_type;
|
||||
static char *AsyncFunctionDef_fields[]={
|
||||
|
@ -56,6 +66,7 @@ static char *AsyncFunctionDef_fields[]={
|
|||
"body",
|
||||
"decorator_list",
|
||||
"returns",
|
||||
"type_comment",
|
||||
};
|
||||
static PyTypeObject *ClassDef_type;
|
||||
_Py_IDENTIFIER(bases);
|
||||
|
@ -81,6 +92,7 @@ static PyTypeObject *Assign_type;
|
|||
static char *Assign_fields[]={
|
||||
"targets",
|
||||
"value",
|
||||
"type_comment",
|
||||
};
|
||||
static PyTypeObject *AugAssign_type;
|
||||
_Py_IDENTIFIER(target);
|
||||
|
@ -107,6 +119,7 @@ static char *For_fields[]={
|
|||
"iter",
|
||||
"body",
|
||||
"orelse",
|
||||
"type_comment",
|
||||
};
|
||||
static PyTypeObject *AsyncFor_type;
|
||||
static char *AsyncFor_fields[]={
|
||||
|
@ -114,6 +127,7 @@ static char *AsyncFor_fields[]={
|
|||
"iter",
|
||||
"body",
|
||||
"orelse",
|
||||
"type_comment",
|
||||
};
|
||||
static PyTypeObject *While_type;
|
||||
_Py_IDENTIFIER(test);
|
||||
|
@ -133,11 +147,13 @@ _Py_IDENTIFIER(items);
|
|||
static char *With_fields[]={
|
||||
"items",
|
||||
"body",
|
||||
"type_comment",
|
||||
};
|
||||
static PyTypeObject *AsyncWith_type;
|
||||
static char *AsyncWith_fields[]={
|
||||
"items",
|
||||
"body",
|
||||
"type_comment",
|
||||
};
|
||||
static PyTypeObject *Raise_type;
|
||||
_Py_IDENTIFIER(exc);
|
||||
|
@ -478,6 +494,7 @@ _Py_IDENTIFIER(arg);
|
|||
static char *arg_fields[]={
|
||||
"arg",
|
||||
"annotation",
|
||||
"type_comment",
|
||||
};
|
||||
static PyTypeObject *keyword_type;
|
||||
static PyObject* ast2obj_keyword(void*);
|
||||
|
@ -500,6 +517,12 @@ static char *withitem_fields[]={
|
|||
"context_expr",
|
||||
"optional_vars",
|
||||
};
|
||||
static PyTypeObject *type_ignore_type;
|
||||
static PyObject* ast2obj_type_ignore(void*);
|
||||
static PyTypeObject *TypeIgnore_type;
|
||||
static char *TypeIgnore_fields[]={
|
||||
"lineno",
|
||||
};
|
||||
|
||||
|
||||
_Py_IDENTIFIER(_fields);
|
||||
|
@ -769,6 +792,15 @@ static int obj2ast_identifier(PyObject* obj, PyObject** out, PyArena* arena)
|
|||
return obj2ast_object(obj, out, arena);
|
||||
}
|
||||
|
||||
static int obj2ast_string(PyObject* obj, PyObject** out, PyArena* arena)
|
||||
{
|
||||
if (!PyUnicode_CheckExact(obj) && !PyBytes_CheckExact(obj)) {
|
||||
PyErr_SetString(PyExc_TypeError, "AST string must be of type str");
|
||||
return 1;
|
||||
}
|
||||
return obj2ast_object(obj, out, arena);
|
||||
}
|
||||
|
||||
static int obj2ast_int(PyObject* obj, int* out, PyArena* arena)
|
||||
{
|
||||
int i;
|
||||
|
@ -810,23 +842,26 @@ static int init_types(void)
|
|||
mod_type = make_type("mod", &AST_type, NULL, 0);
|
||||
if (!mod_type) return 0;
|
||||
if (!add_attributes(mod_type, NULL, 0)) return 0;
|
||||
Module_type = make_type("Module", mod_type, Module_fields, 1);
|
||||
Module_type = make_type("Module", mod_type, Module_fields, 2);
|
||||
if (!Module_type) return 0;
|
||||
Interactive_type = make_type("Interactive", mod_type, Interactive_fields,
|
||||
1);
|
||||
if (!Interactive_type) return 0;
|
||||
Expression_type = make_type("Expression", mod_type, Expression_fields, 1);
|
||||
if (!Expression_type) return 0;
|
||||
FunctionType_type = make_type("FunctionType", mod_type,
|
||||
FunctionType_fields, 2);
|
||||
if (!FunctionType_type) return 0;
|
||||
Suite_type = make_type("Suite", mod_type, Suite_fields, 1);
|
||||
if (!Suite_type) return 0;
|
||||
stmt_type = make_type("stmt", &AST_type, NULL, 0);
|
||||
if (!stmt_type) return 0;
|
||||
if (!add_attributes(stmt_type, stmt_attributes, 4)) return 0;
|
||||
FunctionDef_type = make_type("FunctionDef", stmt_type, FunctionDef_fields,
|
||||
5);
|
||||
6);
|
||||
if (!FunctionDef_type) return 0;
|
||||
AsyncFunctionDef_type = make_type("AsyncFunctionDef", stmt_type,
|
||||
AsyncFunctionDef_fields, 5);
|
||||
AsyncFunctionDef_fields, 6);
|
||||
if (!AsyncFunctionDef_type) return 0;
|
||||
ClassDef_type = make_type("ClassDef", stmt_type, ClassDef_fields, 5);
|
||||
if (!ClassDef_type) return 0;
|
||||
|
@ -834,23 +869,23 @@ static int init_types(void)
|
|||
if (!Return_type) return 0;
|
||||
Delete_type = make_type("Delete", stmt_type, Delete_fields, 1);
|
||||
if (!Delete_type) return 0;
|
||||
Assign_type = make_type("Assign", stmt_type, Assign_fields, 2);
|
||||
Assign_type = make_type("Assign", stmt_type, Assign_fields, 3);
|
||||
if (!Assign_type) return 0;
|
||||
AugAssign_type = make_type("AugAssign", stmt_type, AugAssign_fields, 3);
|
||||
if (!AugAssign_type) return 0;
|
||||
AnnAssign_type = make_type("AnnAssign", stmt_type, AnnAssign_fields, 4);
|
||||
if (!AnnAssign_type) return 0;
|
||||
For_type = make_type("For", stmt_type, For_fields, 4);
|
||||
For_type = make_type("For", stmt_type, For_fields, 5);
|
||||
if (!For_type) return 0;
|
||||
AsyncFor_type = make_type("AsyncFor", stmt_type, AsyncFor_fields, 4);
|
||||
AsyncFor_type = make_type("AsyncFor", stmt_type, AsyncFor_fields, 5);
|
||||
if (!AsyncFor_type) return 0;
|
||||
While_type = make_type("While", stmt_type, While_fields, 3);
|
||||
if (!While_type) return 0;
|
||||
If_type = make_type("If", stmt_type, If_fields, 3);
|
||||
if (!If_type) return 0;
|
||||
With_type = make_type("With", stmt_type, With_fields, 2);
|
||||
With_type = make_type("With", stmt_type, With_fields, 3);
|
||||
if (!With_type) return 0;
|
||||
AsyncWith_type = make_type("AsyncWith", stmt_type, AsyncWith_fields, 2);
|
||||
AsyncWith_type = make_type("AsyncWith", stmt_type, AsyncWith_fields, 3);
|
||||
if (!AsyncWith_type) return 0;
|
||||
Raise_type = make_type("Raise", stmt_type, Raise_fields, 2);
|
||||
if (!Raise_type) return 0;
|
||||
|
@ -1113,7 +1148,7 @@ static int init_types(void)
|
|||
arguments_type = make_type("arguments", &AST_type, arguments_fields, 6);
|
||||
if (!arguments_type) return 0;
|
||||
if (!add_attributes(arguments_type, NULL, 0)) return 0;
|
||||
arg_type = make_type("arg", &AST_type, arg_fields, 2);
|
||||
arg_type = make_type("arg", &AST_type, arg_fields, 3);
|
||||
if (!arg_type) return 0;
|
||||
if (!add_attributes(arg_type, arg_attributes, 4)) return 0;
|
||||
keyword_type = make_type("keyword", &AST_type, keyword_fields, 2);
|
||||
|
@ -1125,6 +1160,12 @@ static int init_types(void)
|
|||
withitem_type = make_type("withitem", &AST_type, withitem_fields, 2);
|
||||
if (!withitem_type) return 0;
|
||||
if (!add_attributes(withitem_type, NULL, 0)) return 0;
|
||||
type_ignore_type = make_type("type_ignore", &AST_type, NULL, 0);
|
||||
if (!type_ignore_type) return 0;
|
||||
if (!add_attributes(type_ignore_type, NULL, 0)) return 0;
|
||||
TypeIgnore_type = make_type("TypeIgnore", type_ignore_type,
|
||||
TypeIgnore_fields, 1);
|
||||
if (!TypeIgnore_type) return 0;
|
||||
initialized = 1;
|
||||
return 1;
|
||||
}
|
||||
|
@ -1148,9 +1189,11 @@ static int obj2ast_arg(PyObject* obj, arg_ty* out, PyArena* arena);
|
|||
static int obj2ast_keyword(PyObject* obj, keyword_ty* out, PyArena* arena);
|
||||
static int obj2ast_alias(PyObject* obj, alias_ty* out, PyArena* arena);
|
||||
static int obj2ast_withitem(PyObject* obj, withitem_ty* out, PyArena* arena);
|
||||
static int obj2ast_type_ignore(PyObject* obj, type_ignore_ty* out, PyArena*
|
||||
arena);
|
||||
|
||||
mod_ty
|
||||
Module(asdl_seq * body, PyArena *arena)
|
||||
Module(asdl_seq * body, asdl_seq * type_ignores, PyArena *arena)
|
||||
{
|
||||
mod_ty p;
|
||||
p = (mod_ty)PyArena_Malloc(arena, sizeof(*p));
|
||||
|
@ -1158,6 +1201,7 @@ Module(asdl_seq * body, PyArena *arena)
|
|||
return NULL;
|
||||
p->kind = Module_kind;
|
||||
p->v.Module.body = body;
|
||||
p->v.Module.type_ignores = type_ignores;
|
||||
return p;
|
||||
}
|
||||
|
||||
|
@ -1190,6 +1234,24 @@ Expression(expr_ty body, PyArena *arena)
|
|||
return p;
|
||||
}
|
||||
|
||||
mod_ty
|
||||
FunctionType(asdl_seq * argtypes, expr_ty returns, PyArena *arena)
|
||||
{
|
||||
mod_ty p;
|
||||
if (!returns) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"field returns is required for FunctionType");
|
||||
return NULL;
|
||||
}
|
||||
p = (mod_ty)PyArena_Malloc(arena, sizeof(*p));
|
||||
if (!p)
|
||||
return NULL;
|
||||
p->kind = FunctionType_kind;
|
||||
p->v.FunctionType.argtypes = argtypes;
|
||||
p->v.FunctionType.returns = returns;
|
||||
return p;
|
||||
}
|
||||
|
||||
mod_ty
|
||||
Suite(asdl_seq * body, PyArena *arena)
|
||||
{
|
||||
|
@ -1204,8 +1266,8 @@ Suite(asdl_seq * body, PyArena *arena)
|
|||
|
||||
stmt_ty
|
||||
FunctionDef(identifier name, arguments_ty args, asdl_seq * body, asdl_seq *
|
||||
decorator_list, expr_ty returns, int lineno, int col_offset, int
|
||||
end_lineno, int end_col_offset, PyArena *arena)
|
||||
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) {
|
||||
|
@ -1227,6 +1289,7 @@ FunctionDef(identifier name, arguments_ty args, asdl_seq * body, asdl_seq *
|
|||
p->v.FunctionDef.body = body;
|
||||
p->v.FunctionDef.decorator_list = decorator_list;
|
||||
p->v.FunctionDef.returns = returns;
|
||||
p->v.FunctionDef.type_comment = type_comment;
|
||||
p->lineno = lineno;
|
||||
p->col_offset = col_offset;
|
||||
p->end_lineno = end_lineno;
|
||||
|
@ -1236,8 +1299,9 @@ FunctionDef(identifier name, arguments_ty args, asdl_seq * body, asdl_seq *
|
|||
|
||||
stmt_ty
|
||||
AsyncFunctionDef(identifier name, arguments_ty args, asdl_seq * body, asdl_seq
|
||||
* decorator_list, expr_ty returns, int lineno, int col_offset,
|
||||
int end_lineno, int end_col_offset, PyArena *arena)
|
||||
* 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) {
|
||||
|
@ -1259,6 +1323,7 @@ AsyncFunctionDef(identifier name, arguments_ty args, asdl_seq * body, asdl_seq
|
|||
p->v.AsyncFunctionDef.body = body;
|
||||
p->v.AsyncFunctionDef.decorator_list = decorator_list;
|
||||
p->v.AsyncFunctionDef.returns = returns;
|
||||
p->v.AsyncFunctionDef.type_comment = type_comment;
|
||||
p->lineno = lineno;
|
||||
p->col_offset = col_offset;
|
||||
p->end_lineno = end_lineno;
|
||||
|
@ -1328,8 +1393,8 @@ Delete(asdl_seq * targets, int lineno, int col_offset, int end_lineno, int
|
|||
}
|
||||
|
||||
stmt_ty
|
||||
Assign(asdl_seq * targets, expr_ty value, int lineno, int col_offset, int
|
||||
end_lineno, int end_col_offset, PyArena *arena)
|
||||
Assign(asdl_seq * targets, expr_ty value, string type_comment, int lineno, int
|
||||
col_offset, int end_lineno, int end_col_offset, PyArena *arena)
|
||||
{
|
||||
stmt_ty p;
|
||||
if (!value) {
|
||||
|
@ -1343,6 +1408,7 @@ Assign(asdl_seq * targets, expr_ty value, int lineno, int col_offset, int
|
|||
p->kind = Assign_kind;
|
||||
p->v.Assign.targets = targets;
|
||||
p->v.Assign.value = value;
|
||||
p->v.Assign.type_comment = type_comment;
|
||||
p->lineno = lineno;
|
||||
p->col_offset = col_offset;
|
||||
p->end_lineno = end_lineno;
|
||||
|
@ -1416,8 +1482,9 @@ AnnAssign(expr_ty target, expr_ty annotation, expr_ty value, int simple, int
|
|||
}
|
||||
|
||||
stmt_ty
|
||||
For(expr_ty target, expr_ty iter, asdl_seq * body, asdl_seq * orelse, int
|
||||
lineno, int col_offset, int end_lineno, int end_col_offset, PyArena *arena)
|
||||
For(expr_ty target, expr_ty iter, asdl_seq * body, asdl_seq * orelse, string
|
||||
type_comment, int lineno, int col_offset, int end_lineno, int
|
||||
end_col_offset, PyArena *arena)
|
||||
{
|
||||
stmt_ty p;
|
||||
if (!target) {
|
||||
|
@ -1438,6 +1505,7 @@ For(expr_ty target, expr_ty iter, asdl_seq * body, asdl_seq * orelse, int
|
|||
p->v.For.iter = iter;
|
||||
p->v.For.body = body;
|
||||
p->v.For.orelse = orelse;
|
||||
p->v.For.type_comment = type_comment;
|
||||
p->lineno = lineno;
|
||||
p->col_offset = col_offset;
|
||||
p->end_lineno = end_lineno;
|
||||
|
@ -1446,9 +1514,9 @@ For(expr_ty target, expr_ty iter, asdl_seq * body, asdl_seq * orelse, int
|
|||
}
|
||||
|
||||
stmt_ty
|
||||
AsyncFor(expr_ty target, expr_ty iter, asdl_seq * body, asdl_seq * orelse, int
|
||||
lineno, int col_offset, int end_lineno, int end_col_offset, PyArena
|
||||
*arena)
|
||||
AsyncFor(expr_ty target, expr_ty iter, asdl_seq * body, asdl_seq * orelse,
|
||||
string type_comment, int lineno, int col_offset, int end_lineno, int
|
||||
end_col_offset, PyArena *arena)
|
||||
{
|
||||
stmt_ty p;
|
||||
if (!target) {
|
||||
|
@ -1469,6 +1537,7 @@ AsyncFor(expr_ty target, expr_ty iter, asdl_seq * body, asdl_seq * orelse, int
|
|||
p->v.AsyncFor.iter = iter;
|
||||
p->v.AsyncFor.body = body;
|
||||
p->v.AsyncFor.orelse = orelse;
|
||||
p->v.AsyncFor.type_comment = type_comment;
|
||||
p->lineno = lineno;
|
||||
p->col_offset = col_offset;
|
||||
p->end_lineno = end_lineno;
|
||||
|
@ -1525,8 +1594,8 @@ If(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno, int
|
|||
}
|
||||
|
||||
stmt_ty
|
||||
With(asdl_seq * items, asdl_seq * body, int lineno, int col_offset, int
|
||||
end_lineno, int end_col_offset, PyArena *arena)
|
||||
With(asdl_seq * items, asdl_seq * body, string type_comment, int lineno, int
|
||||
col_offset, int end_lineno, int end_col_offset, PyArena *arena)
|
||||
{
|
||||
stmt_ty p;
|
||||
p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
|
||||
|
@ -1535,6 +1604,7 @@ With(asdl_seq * items, asdl_seq * body, int lineno, int col_offset, int
|
|||
p->kind = With_kind;
|
||||
p->v.With.items = items;
|
||||
p->v.With.body = body;
|
||||
p->v.With.type_comment = type_comment;
|
||||
p->lineno = lineno;
|
||||
p->col_offset = col_offset;
|
||||
p->end_lineno = end_lineno;
|
||||
|
@ -1543,8 +1613,8 @@ With(asdl_seq * items, asdl_seq * body, int lineno, int col_offset, int
|
|||
}
|
||||
|
||||
stmt_ty
|
||||
AsyncWith(asdl_seq * items, asdl_seq * body, int lineno, int col_offset, int
|
||||
end_lineno, int end_col_offset, PyArena *arena)
|
||||
AsyncWith(asdl_seq * items, asdl_seq * body, string type_comment, int lineno,
|
||||
int col_offset, int end_lineno, int end_col_offset, PyArena *arena)
|
||||
{
|
||||
stmt_ty p;
|
||||
p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
|
||||
|
@ -1553,6 +1623,7 @@ AsyncWith(asdl_seq * items, asdl_seq * body, int lineno, int col_offset, int
|
|||
p->kind = AsyncWith_kind;
|
||||
p->v.AsyncWith.items = items;
|
||||
p->v.AsyncWith.body = body;
|
||||
p->v.AsyncWith.type_comment = type_comment;
|
||||
p->lineno = lineno;
|
||||
p->col_offset = col_offset;
|
||||
p->end_lineno = end_lineno;
|
||||
|
@ -2518,8 +2589,8 @@ arguments(asdl_seq * args, arg_ty vararg, asdl_seq * kwonlyargs, asdl_seq *
|
|||
}
|
||||
|
||||
arg_ty
|
||||
arg(identifier arg, expr_ty annotation, int lineno, int col_offset, int
|
||||
end_lineno, int end_col_offset, PyArena *arena)
|
||||
arg(identifier arg, expr_ty annotation, string type_comment, int lineno, int
|
||||
col_offset, int end_lineno, int end_col_offset, PyArena *arena)
|
||||
{
|
||||
arg_ty p;
|
||||
if (!arg) {
|
||||
|
@ -2532,6 +2603,7 @@ arg(identifier arg, expr_ty annotation, int lineno, int col_offset, int
|
|||
return NULL;
|
||||
p->arg = arg;
|
||||
p->annotation = annotation;
|
||||
p->type_comment = type_comment;
|
||||
p->lineno = lineno;
|
||||
p->col_offset = col_offset;
|
||||
p->end_lineno = end_lineno;
|
||||
|
@ -2590,6 +2662,18 @@ withitem(expr_ty context_expr, expr_ty optional_vars, PyArena *arena)
|
|||
return p;
|
||||
}
|
||||
|
||||
type_ignore_ty
|
||||
TypeIgnore(int lineno, PyArena *arena)
|
||||
{
|
||||
type_ignore_ty p;
|
||||
p = (type_ignore_ty)PyArena_Malloc(arena, sizeof(*p));
|
||||
if (!p)
|
||||
return NULL;
|
||||
p->kind = TypeIgnore_kind;
|
||||
p->v.TypeIgnore.lineno = lineno;
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
PyObject*
|
||||
ast2obj_mod(void* _o)
|
||||
|
@ -2609,6 +2693,11 @@ ast2obj_mod(void* _o)
|
|||
if (_PyObject_SetAttrId(result, &PyId_body, value) == -1)
|
||||
goto failed;
|
||||
Py_DECREF(value);
|
||||
value = ast2obj_list(o->v.Module.type_ignores, ast2obj_type_ignore);
|
||||
if (!value) goto failed;
|
||||
if (_PyObject_SetAttrId(result, &PyId_type_ignores, value) == -1)
|
||||
goto failed;
|
||||
Py_DECREF(value);
|
||||
break;
|
||||
case Interactive_kind:
|
||||
result = PyType_GenericNew(Interactive_type, NULL, NULL);
|
||||
|
@ -2628,6 +2717,20 @@ ast2obj_mod(void* _o)
|
|||
goto failed;
|
||||
Py_DECREF(value);
|
||||
break;
|
||||
case FunctionType_kind:
|
||||
result = PyType_GenericNew(FunctionType_type, NULL, NULL);
|
||||
if (!result) goto failed;
|
||||
value = ast2obj_list(o->v.FunctionType.argtypes, ast2obj_expr);
|
||||
if (!value) goto failed;
|
||||
if (_PyObject_SetAttrId(result, &PyId_argtypes, value) == -1)
|
||||
goto failed;
|
||||
Py_DECREF(value);
|
||||
value = ast2obj_expr(o->v.FunctionType.returns);
|
||||
if (!value) goto failed;
|
||||
if (_PyObject_SetAttrId(result, &PyId_returns, value) == -1)
|
||||
goto failed;
|
||||
Py_DECREF(value);
|
||||
break;
|
||||
case Suite_kind:
|
||||
result = PyType_GenericNew(Suite_type, NULL, NULL);
|
||||
if (!result) goto failed;
|
||||
|
@ -2683,6 +2786,11 @@ ast2obj_stmt(void* _o)
|
|||
if (_PyObject_SetAttrId(result, &PyId_returns, value) == -1)
|
||||
goto failed;
|
||||
Py_DECREF(value);
|
||||
value = ast2obj_string(o->v.FunctionDef.type_comment);
|
||||
if (!value) goto failed;
|
||||
if (_PyObject_SetAttrId(result, &PyId_type_comment, value) == -1)
|
||||
goto failed;
|
||||
Py_DECREF(value);
|
||||
break;
|
||||
case AsyncFunctionDef_kind:
|
||||
result = PyType_GenericNew(AsyncFunctionDef_type, NULL, NULL);
|
||||
|
@ -2713,6 +2821,11 @@ ast2obj_stmt(void* _o)
|
|||
if (_PyObject_SetAttrId(result, &PyId_returns, value) == -1)
|
||||
goto failed;
|
||||
Py_DECREF(value);
|
||||
value = ast2obj_string(o->v.AsyncFunctionDef.type_comment);
|
||||
if (!value) goto failed;
|
||||
if (_PyObject_SetAttrId(result, &PyId_type_comment, value) == -1)
|
||||
goto failed;
|
||||
Py_DECREF(value);
|
||||
break;
|
||||
case ClassDef_kind:
|
||||
result = PyType_GenericNew(ClassDef_type, NULL, NULL);
|
||||
|
@ -2774,6 +2887,11 @@ ast2obj_stmt(void* _o)
|
|||
if (_PyObject_SetAttrId(result, &PyId_value, value) == -1)
|
||||
goto failed;
|
||||
Py_DECREF(value);
|
||||
value = ast2obj_string(o->v.Assign.type_comment);
|
||||
if (!value) goto failed;
|
||||
if (_PyObject_SetAttrId(result, &PyId_type_comment, value) == -1)
|
||||
goto failed;
|
||||
Py_DECREF(value);
|
||||
break;
|
||||
case AugAssign_kind:
|
||||
result = PyType_GenericNew(AugAssign_type, NULL, NULL);
|
||||
|
@ -2841,6 +2959,11 @@ ast2obj_stmt(void* _o)
|
|||
if (_PyObject_SetAttrId(result, &PyId_orelse, value) == -1)
|
||||
goto failed;
|
||||
Py_DECREF(value);
|
||||
value = ast2obj_string(o->v.For.type_comment);
|
||||
if (!value) goto failed;
|
||||
if (_PyObject_SetAttrId(result, &PyId_type_comment, value) == -1)
|
||||
goto failed;
|
||||
Py_DECREF(value);
|
||||
break;
|
||||
case AsyncFor_kind:
|
||||
result = PyType_GenericNew(AsyncFor_type, NULL, NULL);
|
||||
|
@ -2865,6 +2988,11 @@ ast2obj_stmt(void* _o)
|
|||
if (_PyObject_SetAttrId(result, &PyId_orelse, value) == -1)
|
||||
goto failed;
|
||||
Py_DECREF(value);
|
||||
value = ast2obj_string(o->v.AsyncFor.type_comment);
|
||||
if (!value) goto failed;
|
||||
if (_PyObject_SetAttrId(result, &PyId_type_comment, value) == -1)
|
||||
goto failed;
|
||||
Py_DECREF(value);
|
||||
break;
|
||||
case While_kind:
|
||||
result = PyType_GenericNew(While_type, NULL, NULL);
|
||||
|
@ -2917,6 +3045,11 @@ ast2obj_stmt(void* _o)
|
|||
if (_PyObject_SetAttrId(result, &PyId_body, value) == -1)
|
||||
goto failed;
|
||||
Py_DECREF(value);
|
||||
value = ast2obj_string(o->v.With.type_comment);
|
||||
if (!value) goto failed;
|
||||
if (_PyObject_SetAttrId(result, &PyId_type_comment, value) == -1)
|
||||
goto failed;
|
||||
Py_DECREF(value);
|
||||
break;
|
||||
case AsyncWith_kind:
|
||||
result = PyType_GenericNew(AsyncWith_type, NULL, NULL);
|
||||
|
@ -2931,6 +3064,11 @@ ast2obj_stmt(void* _o)
|
|||
if (_PyObject_SetAttrId(result, &PyId_body, value) == -1)
|
||||
goto failed;
|
||||
Py_DECREF(value);
|
||||
value = ast2obj_string(o->v.AsyncWith.type_comment);
|
||||
if (!value) goto failed;
|
||||
if (_PyObject_SetAttrId(result, &PyId_type_comment, value) == -1)
|
||||
goto failed;
|
||||
Py_DECREF(value);
|
||||
break;
|
||||
case Raise_kind:
|
||||
result = PyType_GenericNew(Raise_type, NULL, NULL);
|
||||
|
@ -3870,6 +4008,11 @@ ast2obj_arg(void* _o)
|
|||
if (_PyObject_SetAttrId(result, &PyId_annotation, value) == -1)
|
||||
goto failed;
|
||||
Py_DECREF(value);
|
||||
value = ast2obj_string(o->type_comment);
|
||||
if (!value) goto failed;
|
||||
if (_PyObject_SetAttrId(result, &PyId_type_comment, value) == -1)
|
||||
goto failed;
|
||||
Py_DECREF(value);
|
||||
value = ast2obj_int(o->lineno);
|
||||
if (!value) goto failed;
|
||||
if (_PyObject_SetAttrId(result, &PyId_lineno, value) < 0)
|
||||
|
@ -3981,6 +4124,33 @@ failed:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
PyObject*
|
||||
ast2obj_type_ignore(void* _o)
|
||||
{
|
||||
type_ignore_ty o = (type_ignore_ty)_o;
|
||||
PyObject *result = NULL, *value = NULL;
|
||||
if (!o) {
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
switch (o->kind) {
|
||||
case TypeIgnore_kind:
|
||||
result = PyType_GenericNew(TypeIgnore_type, NULL, NULL);
|
||||
if (!result) goto failed;
|
||||
value = ast2obj_int(o->v.TypeIgnore.lineno);
|
||||
if (!value) goto failed;
|
||||
if (_PyObject_SetAttrId(result, &PyId_lineno, value) == -1)
|
||||
goto failed;
|
||||
Py_DECREF(value);
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
failed:
|
||||
Py_XDECREF(value);
|
||||
Py_XDECREF(result);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
obj2ast_mod(PyObject* obj, mod_ty* out, PyArena* arena)
|
||||
|
@ -3999,6 +4169,7 @@ obj2ast_mod(PyObject* obj, mod_ty* out, PyArena* arena)
|
|||
}
|
||||
if (isinstance) {
|
||||
asdl_seq* body;
|
||||
asdl_seq* type_ignores;
|
||||
|
||||
if (_PyObject_LookupAttrId(obj, &PyId_body, &tmp) < 0) {
|
||||
return 1;
|
||||
|
@ -4030,7 +4201,37 @@ obj2ast_mod(PyObject* obj, mod_ty* out, PyArena* arena)
|
|||
}
|
||||
Py_CLEAR(tmp);
|
||||
}
|
||||
*out = Module(body, arena);
|
||||
if (_PyObject_LookupAttrId(obj, &PyId_type_ignores, &tmp) < 0) {
|
||||
return 1;
|
||||
}
|
||||
if (tmp == NULL) {
|
||||
PyErr_SetString(PyExc_TypeError, "required field \"type_ignores\" missing from Module");
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
int res;
|
||||
Py_ssize_t len;
|
||||
Py_ssize_t i;
|
||||
if (!PyList_Check(tmp)) {
|
||||
PyErr_Format(PyExc_TypeError, "Module field \"type_ignores\" must be a list, not a %.200s", tmp->ob_type->tp_name);
|
||||
goto failed;
|
||||
}
|
||||
len = PyList_GET_SIZE(tmp);
|
||||
type_ignores = _Py_asdl_seq_new(len, arena);
|
||||
if (type_ignores == NULL) goto failed;
|
||||
for (i = 0; i < len; i++) {
|
||||
type_ignore_ty val;
|
||||
res = obj2ast_type_ignore(PyList_GET_ITEM(tmp, i), &val, arena);
|
||||
if (res != 0) goto failed;
|
||||
if (len != PyList_GET_SIZE(tmp)) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "Module field \"type_ignores\" changed size during iteration");
|
||||
goto failed;
|
||||
}
|
||||
asdl_seq_SET(type_ignores, i, val);
|
||||
}
|
||||
Py_CLEAR(tmp);
|
||||
}
|
||||
*out = Module(body, type_ignores, arena);
|
||||
if (*out == NULL) goto failed;
|
||||
return 0;
|
||||
}
|
||||
|
@ -4099,6 +4300,61 @@ obj2ast_mod(PyObject* obj, mod_ty* out, PyArena* arena)
|
|||
if (*out == NULL) goto failed;
|
||||
return 0;
|
||||
}
|
||||
isinstance = PyObject_IsInstance(obj, (PyObject*)FunctionType_type);
|
||||
if (isinstance == -1) {
|
||||
return 1;
|
||||
}
|
||||
if (isinstance) {
|
||||
asdl_seq* argtypes;
|
||||
expr_ty returns;
|
||||
|
||||
if (_PyObject_LookupAttrId(obj, &PyId_argtypes, &tmp) < 0) {
|
||||
return 1;
|
||||
}
|
||||
if (tmp == NULL) {
|
||||
PyErr_SetString(PyExc_TypeError, "required field \"argtypes\" missing from FunctionType");
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
int res;
|
||||
Py_ssize_t len;
|
||||
Py_ssize_t i;
|
||||
if (!PyList_Check(tmp)) {
|
||||
PyErr_Format(PyExc_TypeError, "FunctionType field \"argtypes\" must be a list, not a %.200s", tmp->ob_type->tp_name);
|
||||
goto failed;
|
||||
}
|
||||
len = PyList_GET_SIZE(tmp);
|
||||
argtypes = _Py_asdl_seq_new(len, arena);
|
||||
if (argtypes == NULL) goto failed;
|
||||
for (i = 0; i < len; i++) {
|
||||
expr_ty val;
|
||||
res = obj2ast_expr(PyList_GET_ITEM(tmp, i), &val, arena);
|
||||
if (res != 0) goto failed;
|
||||
if (len != PyList_GET_SIZE(tmp)) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "FunctionType field \"argtypes\" changed size during iteration");
|
||||
goto failed;
|
||||
}
|
||||
asdl_seq_SET(argtypes, i, val);
|
||||
}
|
||||
Py_CLEAR(tmp);
|
||||
}
|
||||
if (_PyObject_LookupAttrId(obj, &PyId_returns, &tmp) < 0) {
|
||||
return 1;
|
||||
}
|
||||
if (tmp == NULL) {
|
||||
PyErr_SetString(PyExc_TypeError, "required field \"returns\" missing from FunctionType");
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
int res;
|
||||
res = obj2ast_expr(tmp, &returns, arena);
|
||||
if (res != 0) goto failed;
|
||||
Py_CLEAR(tmp);
|
||||
}
|
||||
*out = FunctionType(argtypes, returns, arena);
|
||||
if (*out == NULL) goto failed;
|
||||
return 0;
|
||||
}
|
||||
isinstance = PyObject_IsInstance(obj, (PyObject*)Suite_type);
|
||||
if (isinstance == -1) {
|
||||
return 1;
|
||||
|
@ -4224,6 +4480,7 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena)
|
|||
asdl_seq* body;
|
||||
asdl_seq* decorator_list;
|
||||
expr_ty returns;
|
||||
string type_comment;
|
||||
|
||||
if (_PyObject_LookupAttrId(obj, &PyId_name, &tmp) < 0) {
|
||||
return 1;
|
||||
|
@ -4324,8 +4581,22 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena)
|
|||
if (res != 0) goto failed;
|
||||
Py_CLEAR(tmp);
|
||||
}
|
||||
*out = FunctionDef(name, args, body, decorator_list, returns, lineno,
|
||||
col_offset, end_lineno, end_col_offset, arena);
|
||||
if (_PyObject_LookupAttrId(obj, &PyId_type_comment, &tmp) < 0) {
|
||||
return 1;
|
||||
}
|
||||
if (tmp == NULL || tmp == Py_None) {
|
||||
Py_CLEAR(tmp);
|
||||
type_comment = NULL;
|
||||
}
|
||||
else {
|
||||
int res;
|
||||
res = obj2ast_string(tmp, &type_comment, arena);
|
||||
if (res != 0) goto failed;
|
||||
Py_CLEAR(tmp);
|
||||
}
|
||||
*out = FunctionDef(name, args, body, decorator_list, returns,
|
||||
type_comment, lineno, col_offset, end_lineno,
|
||||
end_col_offset, arena);
|
||||
if (*out == NULL) goto failed;
|
||||
return 0;
|
||||
}
|
||||
|
@ -4339,6 +4610,7 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena)
|
|||
asdl_seq* body;
|
||||
asdl_seq* decorator_list;
|
||||
expr_ty returns;
|
||||
string type_comment;
|
||||
|
||||
if (_PyObject_LookupAttrId(obj, &PyId_name, &tmp) < 0) {
|
||||
return 1;
|
||||
|
@ -4439,9 +4711,22 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena)
|
|||
if (res != 0) goto failed;
|
||||
Py_CLEAR(tmp);
|
||||
}
|
||||
if (_PyObject_LookupAttrId(obj, &PyId_type_comment, &tmp) < 0) {
|
||||
return 1;
|
||||
}
|
||||
if (tmp == NULL || tmp == Py_None) {
|
||||
Py_CLEAR(tmp);
|
||||
type_comment = NULL;
|
||||
}
|
||||
else {
|
||||
int res;
|
||||
res = obj2ast_string(tmp, &type_comment, arena);
|
||||
if (res != 0) goto failed;
|
||||
Py_CLEAR(tmp);
|
||||
}
|
||||
*out = AsyncFunctionDef(name, args, body, decorator_list, returns,
|
||||
lineno, col_offset, end_lineno, end_col_offset,
|
||||
arena);
|
||||
type_comment, lineno, col_offset, end_lineno,
|
||||
end_col_offset, arena);
|
||||
if (*out == NULL) goto failed;
|
||||
return 0;
|
||||
}
|
||||
|
@ -4668,6 +4953,7 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena)
|
|||
if (isinstance) {
|
||||
asdl_seq* targets;
|
||||
expr_ty value;
|
||||
string type_comment;
|
||||
|
||||
if (_PyObject_LookupAttrId(obj, &PyId_targets, &tmp) < 0) {
|
||||
return 1;
|
||||
|
@ -4712,8 +4998,21 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena)
|
|||
if (res != 0) goto failed;
|
||||
Py_CLEAR(tmp);
|
||||
}
|
||||
*out = Assign(targets, value, lineno, col_offset, end_lineno,
|
||||
end_col_offset, arena);
|
||||
if (_PyObject_LookupAttrId(obj, &PyId_type_comment, &tmp) < 0) {
|
||||
return 1;
|
||||
}
|
||||
if (tmp == NULL || tmp == Py_None) {
|
||||
Py_CLEAR(tmp);
|
||||
type_comment = NULL;
|
||||
}
|
||||
else {
|
||||
int res;
|
||||
res = obj2ast_string(tmp, &type_comment, arena);
|
||||
if (res != 0) goto failed;
|
||||
Py_CLEAR(tmp);
|
||||
}
|
||||
*out = Assign(targets, value, type_comment, lineno, col_offset,
|
||||
end_lineno, end_col_offset, arena);
|
||||
if (*out == NULL) goto failed;
|
||||
return 0;
|
||||
}
|
||||
|
@ -4846,6 +5145,7 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena)
|
|||
expr_ty iter;
|
||||
asdl_seq* body;
|
||||
asdl_seq* orelse;
|
||||
string type_comment;
|
||||
|
||||
if (_PyObject_LookupAttrId(obj, &PyId_target, &tmp) < 0) {
|
||||
return 1;
|
||||
|
@ -4933,8 +5233,21 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena)
|
|||
}
|
||||
Py_CLEAR(tmp);
|
||||
}
|
||||
*out = For(target, iter, body, orelse, lineno, col_offset, end_lineno,
|
||||
end_col_offset, arena);
|
||||
if (_PyObject_LookupAttrId(obj, &PyId_type_comment, &tmp) < 0) {
|
||||
return 1;
|
||||
}
|
||||
if (tmp == NULL || tmp == Py_None) {
|
||||
Py_CLEAR(tmp);
|
||||
type_comment = NULL;
|
||||
}
|
||||
else {
|
||||
int res;
|
||||
res = obj2ast_string(tmp, &type_comment, arena);
|
||||
if (res != 0) goto failed;
|
||||
Py_CLEAR(tmp);
|
||||
}
|
||||
*out = For(target, iter, body, orelse, type_comment, lineno,
|
||||
col_offset, end_lineno, end_col_offset, arena);
|
||||
if (*out == NULL) goto failed;
|
||||
return 0;
|
||||
}
|
||||
|
@ -4947,6 +5260,7 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena)
|
|||
expr_ty iter;
|
||||
asdl_seq* body;
|
||||
asdl_seq* orelse;
|
||||
string type_comment;
|
||||
|
||||
if (_PyObject_LookupAttrId(obj, &PyId_target, &tmp) < 0) {
|
||||
return 1;
|
||||
|
@ -5034,8 +5348,21 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena)
|
|||
}
|
||||
Py_CLEAR(tmp);
|
||||
}
|
||||
*out = AsyncFor(target, iter, body, orelse, lineno, col_offset,
|
||||
end_lineno, end_col_offset, arena);
|
||||
if (_PyObject_LookupAttrId(obj, &PyId_type_comment, &tmp) < 0) {
|
||||
return 1;
|
||||
}
|
||||
if (tmp == NULL || tmp == Py_None) {
|
||||
Py_CLEAR(tmp);
|
||||
type_comment = NULL;
|
||||
}
|
||||
else {
|
||||
int res;
|
||||
res = obj2ast_string(tmp, &type_comment, arena);
|
||||
if (res != 0) goto failed;
|
||||
Py_CLEAR(tmp);
|
||||
}
|
||||
*out = AsyncFor(target, iter, body, orelse, type_comment, lineno,
|
||||
col_offset, end_lineno, end_col_offset, arena);
|
||||
if (*out == NULL) goto failed;
|
||||
return 0;
|
||||
}
|
||||
|
@ -5220,6 +5547,7 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena)
|
|||
if (isinstance) {
|
||||
asdl_seq* items;
|
||||
asdl_seq* body;
|
||||
string type_comment;
|
||||
|
||||
if (_PyObject_LookupAttrId(obj, &PyId_items, &tmp) < 0) {
|
||||
return 1;
|
||||
|
@ -5281,7 +5609,20 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena)
|
|||
}
|
||||
Py_CLEAR(tmp);
|
||||
}
|
||||
*out = With(items, body, lineno, col_offset, end_lineno,
|
||||
if (_PyObject_LookupAttrId(obj, &PyId_type_comment, &tmp) < 0) {
|
||||
return 1;
|
||||
}
|
||||
if (tmp == NULL || tmp == Py_None) {
|
||||
Py_CLEAR(tmp);
|
||||
type_comment = NULL;
|
||||
}
|
||||
else {
|
||||
int res;
|
||||
res = obj2ast_string(tmp, &type_comment, arena);
|
||||
if (res != 0) goto failed;
|
||||
Py_CLEAR(tmp);
|
||||
}
|
||||
*out = With(items, body, type_comment, lineno, col_offset, end_lineno,
|
||||
end_col_offset, arena);
|
||||
if (*out == NULL) goto failed;
|
||||
return 0;
|
||||
|
@ -5293,6 +5634,7 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena)
|
|||
if (isinstance) {
|
||||
asdl_seq* items;
|
||||
asdl_seq* body;
|
||||
string type_comment;
|
||||
|
||||
if (_PyObject_LookupAttrId(obj, &PyId_items, &tmp) < 0) {
|
||||
return 1;
|
||||
|
@ -5354,8 +5696,21 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena)
|
|||
}
|
||||
Py_CLEAR(tmp);
|
||||
}
|
||||
*out = AsyncWith(items, body, lineno, col_offset, end_lineno,
|
||||
end_col_offset, arena);
|
||||
if (_PyObject_LookupAttrId(obj, &PyId_type_comment, &tmp) < 0) {
|
||||
return 1;
|
||||
}
|
||||
if (tmp == NULL || tmp == Py_None) {
|
||||
Py_CLEAR(tmp);
|
||||
type_comment = NULL;
|
||||
}
|
||||
else {
|
||||
int res;
|
||||
res = obj2ast_string(tmp, &type_comment, arena);
|
||||
if (res != 0) goto failed;
|
||||
Py_CLEAR(tmp);
|
||||
}
|
||||
*out = AsyncWith(items, body, type_comment, lineno, col_offset,
|
||||
end_lineno, end_col_offset, arena);
|
||||
if (*out == NULL) goto failed;
|
||||
return 0;
|
||||
}
|
||||
|
@ -8073,6 +8428,7 @@ obj2ast_arg(PyObject* obj, arg_ty* out, PyArena* arena)
|
|||
PyObject* tmp = NULL;
|
||||
identifier arg;
|
||||
expr_ty annotation;
|
||||
string type_comment;
|
||||
int lineno;
|
||||
int col_offset;
|
||||
int end_lineno;
|
||||
|
@ -8104,6 +8460,19 @@ obj2ast_arg(PyObject* obj, arg_ty* out, PyArena* arena)
|
|||
if (res != 0) goto failed;
|
||||
Py_CLEAR(tmp);
|
||||
}
|
||||
if (_PyObject_LookupAttrId(obj, &PyId_type_comment, &tmp) < 0) {
|
||||
return 1;
|
||||
}
|
||||
if (tmp == NULL || tmp == Py_None) {
|
||||
Py_CLEAR(tmp);
|
||||
type_comment = NULL;
|
||||
}
|
||||
else {
|
||||
int res;
|
||||
res = obj2ast_string(tmp, &type_comment, arena);
|
||||
if (res != 0) goto failed;
|
||||
Py_CLEAR(tmp);
|
||||
}
|
||||
if (_PyObject_LookupAttrId(obj, &PyId_lineno, &tmp) < 0) {
|
||||
return 1;
|
||||
}
|
||||
|
@ -8156,8 +8525,8 @@ obj2ast_arg(PyObject* obj, arg_ty* out, PyArena* arena)
|
|||
if (res != 0) goto failed;
|
||||
Py_CLEAR(tmp);
|
||||
}
|
||||
*out = arg(arg, annotation, lineno, col_offset, end_lineno, end_col_offset,
|
||||
arena);
|
||||
*out = arg(arg, annotation, type_comment, lineno, col_offset, end_lineno,
|
||||
end_col_offset, arena);
|
||||
return 0;
|
||||
failed:
|
||||
Py_XDECREF(tmp);
|
||||
|
@ -8284,6 +8653,48 @@ failed:
|
|||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
obj2ast_type_ignore(PyObject* obj, type_ignore_ty* out, PyArena* arena)
|
||||
{
|
||||
int isinstance;
|
||||
|
||||
PyObject *tmp = NULL;
|
||||
|
||||
if (obj == Py_None) {
|
||||
*out = NULL;
|
||||
return 0;
|
||||
}
|
||||
isinstance = PyObject_IsInstance(obj, (PyObject*)TypeIgnore_type);
|
||||
if (isinstance == -1) {
|
||||
return 1;
|
||||
}
|
||||
if (isinstance) {
|
||||
int lineno;
|
||||
|
||||
if (_PyObject_LookupAttrId(obj, &PyId_lineno, &tmp) < 0) {
|
||||
return 1;
|
||||
}
|
||||
if (tmp == NULL) {
|
||||
PyErr_SetString(PyExc_TypeError, "required field \"lineno\" missing from TypeIgnore");
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
int res;
|
||||
res = obj2ast_int(tmp, &lineno, arena);
|
||||
if (res != 0) goto failed;
|
||||
Py_CLEAR(tmp);
|
||||
}
|
||||
*out = TypeIgnore(lineno, arena);
|
||||
if (*out == NULL) goto failed;
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyErr_Format(PyExc_TypeError, "expected some sort of type_ignore, but got %R", obj);
|
||||
failed:
|
||||
Py_XDECREF(tmp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static struct PyModuleDef _astmodule = {
|
||||
PyModuleDef_HEAD_INIT, "_ast"
|
||||
|
@ -8299,6 +8710,8 @@ PyInit__ast(void)
|
|||
if (PyDict_SetItemString(d, "AST", (PyObject*)&AST_type) < 0) return NULL;
|
||||
if (PyModule_AddIntMacro(m, PyCF_ONLY_AST) < 0)
|
||||
return NULL;
|
||||
if (PyModule_AddIntMacro(m, PyCF_TYPE_COMMENTS) < 0)
|
||||
return NULL;
|
||||
if (PyDict_SetItemString(d, "mod", (PyObject*)mod_type) < 0) return NULL;
|
||||
if (PyDict_SetItemString(d, "Module", (PyObject*)Module_type) < 0) return
|
||||
NULL;
|
||||
|
@ -8306,6 +8719,8 @@ PyInit__ast(void)
|
|||
0) return NULL;
|
||||
if (PyDict_SetItemString(d, "Expression", (PyObject*)Expression_type) < 0)
|
||||
return NULL;
|
||||
if (PyDict_SetItemString(d, "FunctionType", (PyObject*)FunctionType_type) <
|
||||
0) return NULL;
|
||||
if (PyDict_SetItemString(d, "Suite", (PyObject*)Suite_type) < 0) return
|
||||
NULL;
|
||||
if (PyDict_SetItemString(d, "stmt", (PyObject*)stmt_type) < 0) return NULL;
|
||||
|
@ -8486,6 +8901,10 @@ PyInit__ast(void)
|
|||
NULL;
|
||||
if (PyDict_SetItemString(d, "withitem", (PyObject*)withitem_type) < 0)
|
||||
return NULL;
|
||||
if (PyDict_SetItemString(d, "type_ignore", (PyObject*)type_ignore_type) <
|
||||
0) return NULL;
|
||||
if (PyDict_SetItemString(d, "TypeIgnore", (PyObject*)TypeIgnore_type) < 0)
|
||||
return NULL;
|
||||
return m;
|
||||
}
|
||||
|
||||
|
@ -8498,18 +8917,19 @@ PyObject* PyAST_mod2obj(mod_ty t)
|
|||
}
|
||||
|
||||
/* mode is 0 for "exec", 1 for "eval" and 2 for "single" input */
|
||||
/* and 3 for "func_type" */
|
||||
mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena, int mode)
|
||||
{
|
||||
mod_ty res;
|
||||
PyObject *req_type[3];
|
||||
char *req_name[] = {"Module", "Expression", "Interactive"};
|
||||
char *req_name[] = {"Module", "Expression", "Interactive", "FunctionType"};
|
||||
int isinstance;
|
||||
|
||||
req_type[0] = (PyObject*)Module_type;
|
||||
req_type[1] = (PyObject*)Expression_type;
|
||||
req_type[2] = (PyObject*)Interactive_type;
|
||||
|
||||
assert(0 <= mode && mode <= 2);
|
||||
assert(0 <= mode && mode <= 3);
|
||||
|
||||
if (!init_types())
|
||||
return NULL;
|
||||
|
|
304
Python/ast.c
304
Python/ast.c
|
@ -698,6 +698,13 @@ ast_error(struct compiling *c, const node *n, const char *errmsg, ...)
|
|||
small_stmt elements is returned.
|
||||
*/
|
||||
|
||||
static string
|
||||
new_type_comment(const char *s)
|
||||
{
|
||||
return PyUnicode_DecodeUTF8(s, strlen(s), NULL);
|
||||
}
|
||||
#define NEW_TYPE_COMMENT(n) new_type_comment(STR(n))
|
||||
|
||||
static int
|
||||
num_stmts(const node *n)
|
||||
{
|
||||
|
@ -725,11 +732,17 @@ num_stmts(const node *n)
|
|||
case simple_stmt:
|
||||
return NCH(n) / 2; /* Divide by 2 to remove count of semi-colons */
|
||||
case suite:
|
||||
case func_body_suite:
|
||||
/* func_body_suite: simple_stmt | NEWLINE [TYPE_COMMENT NEWLINE] INDENT stmt+ DEDENT */
|
||||
/* suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT */
|
||||
if (NCH(n) == 1)
|
||||
return num_stmts(CHILD(n, 0));
|
||||
else {
|
||||
i = 2;
|
||||
l = 0;
|
||||
for (i = 2; i < (NCH(n) - 1); i++)
|
||||
if (TYPE(CHILD(n, 1)) == TYPE_COMMENT)
|
||||
i += 2;
|
||||
for (; i < (NCH(n) - 1); i++)
|
||||
l += num_stmts(CHILD(n, i));
|
||||
return l;
|
||||
}
|
||||
|
@ -753,10 +766,13 @@ PyAST_FromNodeObject(const node *n, PyCompilerFlags *flags,
|
|||
{
|
||||
int i, j, k, num;
|
||||
asdl_seq *stmts = NULL;
|
||||
asdl_seq *type_ignores = NULL;
|
||||
stmt_ty s;
|
||||
node *ch;
|
||||
struct compiling c;
|
||||
mod_ty res = NULL;
|
||||
asdl_seq *argtypes = NULL;
|
||||
expr_ty ret, arg;
|
||||
|
||||
c.c_arena = arena;
|
||||
/* borrowed reference */
|
||||
|
@ -795,7 +811,23 @@ PyAST_FromNodeObject(const node *n, PyCompilerFlags *flags,
|
|||
}
|
||||
}
|
||||
}
|
||||
res = Module(stmts, arena);
|
||||
|
||||
/* Type ignores are stored under the ENDMARKER in file_input. */
|
||||
ch = CHILD(n, NCH(n) - 1);
|
||||
REQ(ch, ENDMARKER);
|
||||
num = NCH(ch);
|
||||
type_ignores = _Py_asdl_seq_new(num, arena);
|
||||
if (!type_ignores)
|
||||
goto out;
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
type_ignore_ty ti = TypeIgnore(LINENO(CHILD(ch, i)), arena);
|
||||
if (!ti)
|
||||
goto out;
|
||||
asdl_seq_SET(type_ignores, i, ti);
|
||||
}
|
||||
|
||||
res = Module(stmts, type_ignores, arena);
|
||||
break;
|
||||
case eval_input: {
|
||||
expr_ty testlist_ast;
|
||||
|
@ -847,6 +879,46 @@ PyAST_FromNodeObject(const node *n, PyCompilerFlags *flags,
|
|||
res = Interactive(stmts, arena);
|
||||
}
|
||||
break;
|
||||
case func_type_input:
|
||||
n = CHILD(n, 0);
|
||||
REQ(n, func_type);
|
||||
|
||||
if (TYPE(CHILD(n, 1)) == typelist) {
|
||||
ch = CHILD(n, 1);
|
||||
/* this is overly permissive -- we don't pay any attention to
|
||||
* stars on the args -- just parse them into an ordered list */
|
||||
num = 0;
|
||||
for (i = 0; i < NCH(ch); i++) {
|
||||
if (TYPE(CHILD(ch, i)) == test) {
|
||||
num++;
|
||||
}
|
||||
}
|
||||
|
||||
argtypes = _Py_asdl_seq_new(num, arena);
|
||||
if (!argtypes)
|
||||
goto out;
|
||||
|
||||
j = 0;
|
||||
for (i = 0; i < NCH(ch); i++) {
|
||||
if (TYPE(CHILD(ch, i)) == test) {
|
||||
arg = ast_for_expr(&c, CHILD(ch, i));
|
||||
if (!arg)
|
||||
goto out;
|
||||
asdl_seq_SET(argtypes, j++, arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
argtypes = _Py_asdl_seq_new(0, arena);
|
||||
if (!argtypes)
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = ast_for_expr(&c, CHILD(n, NCH(n) - 1));
|
||||
if (!ret)
|
||||
goto out;
|
||||
res = FunctionType(argtypes, ret, arena);
|
||||
break;
|
||||
default:
|
||||
PyErr_Format(PyExc_SystemError,
|
||||
"invalid node %d for PyAST_FromNode", TYPE(n));
|
||||
|
@ -1269,7 +1341,7 @@ ast_for_arg(struct compiling *c, const node *n)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
ret = arg(name, annotation, LINENO(n), n->n_col_offset,
|
||||
ret = arg(name, annotation, NULL, LINENO(n), n->n_col_offset,
|
||||
n->n_end_lineno, n->n_end_col_offset, c->c_arena);
|
||||
if (!ret)
|
||||
return NULL;
|
||||
|
@ -1328,13 +1400,22 @@ handle_keywordonly_args(struct compiling *c, const node *n, int start,
|
|||
goto error;
|
||||
if (forbidden_name(c, argname, ch, 0))
|
||||
goto error;
|
||||
arg = arg(argname, annotation, LINENO(ch), ch->n_col_offset,
|
||||
arg = arg(argname, annotation, NULL, LINENO(ch), ch->n_col_offset,
|
||||
ch->n_end_lineno, ch->n_end_col_offset,
|
||||
c->c_arena);
|
||||
if (!arg)
|
||||
goto error;
|
||||
asdl_seq_SET(kwonlyargs, j++, arg);
|
||||
i += 2; /* the name and the comma */
|
||||
i += 1; /* the name */
|
||||
if (TYPE(CHILD(n, i)) == COMMA)
|
||||
i += 1; /* the comma, if present */
|
||||
break;
|
||||
case TYPE_COMMENT:
|
||||
/* arg will be equal to the last argument processed */
|
||||
arg->type_comment = NEW_TYPE_COMMENT(ch);
|
||||
if (!arg->type_comment)
|
||||
goto error;
|
||||
i += 1;
|
||||
break;
|
||||
case DOUBLESTAR:
|
||||
return i;
|
||||
|
@ -1464,19 +1545,29 @@ ast_for_arguments(struct compiling *c, const node *n)
|
|||
if (!arg)
|
||||
return NULL;
|
||||
asdl_seq_SET(posargs, k++, arg);
|
||||
i += 2; /* the name and the comma */
|
||||
i += 1; /* the name */
|
||||
if (i < NCH(n) && TYPE(CHILD(n, i)) == COMMA)
|
||||
i += 1; /* the comma, if present */
|
||||
break;
|
||||
case STAR:
|
||||
if (i+1 >= NCH(n) ||
|
||||
(i+2 == NCH(n) && TYPE(CHILD(n, i+1)) == COMMA)) {
|
||||
(i+2 == NCH(n) && (TYPE(CHILD(n, i+1)) == COMMA
|
||||
|| TYPE(CHILD(n, i+1)) == TYPE_COMMENT))) {
|
||||
ast_error(c, CHILD(n, i),
|
||||
"named arguments must follow bare *");
|
||||
"named arguments must follow bare *");
|
||||
return NULL;
|
||||
}
|
||||
ch = CHILD(n, i+1); /* tfpdef or COMMA */
|
||||
if (TYPE(ch) == COMMA) {
|
||||
int res = 0;
|
||||
i += 2; /* now follows keyword only arguments */
|
||||
|
||||
if (i < NCH(n) && TYPE(CHILD(n, i)) == TYPE_COMMENT) {
|
||||
ast_error(c, CHILD(n, i),
|
||||
"bare * has associated type comment");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
res = handle_keywordonly_args(c, n, i,
|
||||
kwonlyargs, kwdefaults);
|
||||
if (res == -1) return NULL;
|
||||
|
@ -1487,7 +1578,17 @@ ast_for_arguments(struct compiling *c, const node *n)
|
|||
if (!vararg)
|
||||
return NULL;
|
||||
|
||||
i += 3;
|
||||
i += 2; /* the star and the name */
|
||||
if (i < NCH(n) && TYPE(CHILD(n, i)) == COMMA)
|
||||
i += 1; /* the comma, if present */
|
||||
|
||||
if (i < NCH(n) && TYPE(CHILD(n, i)) == TYPE_COMMENT) {
|
||||
vararg->type_comment = NEW_TYPE_COMMENT(CHILD(n, i));
|
||||
if (!vararg->type_comment)
|
||||
return NULL;
|
||||
i += 1;
|
||||
}
|
||||
|
||||
if (i < NCH(n) && (TYPE(CHILD(n, i)) == tfpdef
|
||||
|| TYPE(CHILD(n, i)) == vfpdef)) {
|
||||
int res = 0;
|
||||
|
@ -1504,7 +1605,21 @@ ast_for_arguments(struct compiling *c, const node *n)
|
|||
kwarg = ast_for_arg(c, ch);
|
||||
if (!kwarg)
|
||||
return NULL;
|
||||
i += 3;
|
||||
i += 2; /* the double star and the name */
|
||||
if (TYPE(CHILD(n, i)) == COMMA)
|
||||
i += 1; /* the comma, if present */
|
||||
break;
|
||||
case TYPE_COMMENT:
|
||||
assert(i);
|
||||
|
||||
if (kwarg)
|
||||
arg = kwarg;
|
||||
|
||||
/* arg will be equal to the last argument processed */
|
||||
arg->type_comment = NEW_TYPE_COMMENT(ch);
|
||||
if (!arg->type_comment)
|
||||
return NULL;
|
||||
i += 1;
|
||||
break;
|
||||
default:
|
||||
PyErr_Format(PyExc_SystemError,
|
||||
|
@ -1613,7 +1728,7 @@ static stmt_ty
|
|||
ast_for_funcdef_impl(struct compiling *c, const node *n0,
|
||||
asdl_seq *decorator_seq, bool is_async)
|
||||
{
|
||||
/* funcdef: 'def' NAME parameters ['->' test] ':' suite */
|
||||
/* funcdef: 'def' NAME parameters ['->' test] ':' [TYPE_COMMENT] suite */
|
||||
const node * const n = is_async ? CHILD(n0, 1) : n0;
|
||||
identifier name;
|
||||
arguments_ty args;
|
||||
|
@ -1621,6 +1736,8 @@ ast_for_funcdef_impl(struct compiling *c, const node *n0,
|
|||
expr_ty returns = NULL;
|
||||
int name_i = 1;
|
||||
int end_lineno, end_col_offset;
|
||||
node *tc;
|
||||
string type_comment = NULL;
|
||||
|
||||
REQ(n, funcdef);
|
||||
|
||||
|
@ -1638,16 +1755,37 @@ ast_for_funcdef_impl(struct compiling *c, const node *n0,
|
|||
return NULL;
|
||||
name_i += 2;
|
||||
}
|
||||
if (TYPE(CHILD(n, name_i + 3)) == TYPE_COMMENT) {
|
||||
type_comment = NEW_TYPE_COMMENT(CHILD(n, name_i + 3));
|
||||
if (!type_comment)
|
||||
return NULL;
|
||||
name_i += 1;
|
||||
}
|
||||
body = ast_for_suite(c, CHILD(n, name_i + 3));
|
||||
if (!body)
|
||||
return NULL;
|
||||
get_last_end_pos(body, &end_lineno, &end_col_offset);
|
||||
|
||||
if (NCH(CHILD(n, name_i + 3)) > 1) {
|
||||
/* Check if the suite has a type comment in it. */
|
||||
tc = CHILD(CHILD(n, name_i + 3), 1);
|
||||
|
||||
if (TYPE(tc) == TYPE_COMMENT) {
|
||||
if (type_comment != NULL) {
|
||||
ast_error(c, n, "Cannot have two type comments on def");
|
||||
return NULL;
|
||||
}
|
||||
type_comment = NEW_TYPE_COMMENT(tc);
|
||||
if (!type_comment)
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_async)
|
||||
return AsyncFunctionDef(name, args, body, decorator_seq, returns,
|
||||
return AsyncFunctionDef(name, args, body, decorator_seq, returns, type_comment,
|
||||
LINENO(n0), n0->n_col_offset, end_lineno, end_col_offset, c->c_arena);
|
||||
else
|
||||
return FunctionDef(name, args, body, decorator_seq, returns,
|
||||
return FunctionDef(name, args, body, decorator_seq, returns, type_comment,
|
||||
LINENO(n), n->n_col_offset, end_lineno, end_col_offset, c->c_arena);
|
||||
}
|
||||
|
||||
|
@ -2295,7 +2433,7 @@ ast_for_atom(struct compiling *c, const node *n)
|
|||
/* It's a dictionary comprehension. */
|
||||
if (is_dict) {
|
||||
ast_error(c, n, "dict unpacking cannot be used in "
|
||||
"dict comprehension");
|
||||
"dict comprehension");
|
||||
return NULL;
|
||||
}
|
||||
res = ast_for_dictcomp(c, ch);
|
||||
|
@ -2870,13 +3008,13 @@ ast_for_call(struct compiling *c, const node *n, expr_ty func,
|
|||
if (nkeywords) {
|
||||
if (ndoublestars) {
|
||||
ast_error(c, chch,
|
||||
"positional argument follows "
|
||||
"keyword argument unpacking");
|
||||
"positional argument follows "
|
||||
"keyword argument unpacking");
|
||||
}
|
||||
else {
|
||||
ast_error(c, chch,
|
||||
"positional argument follows "
|
||||
"keyword argument");
|
||||
"positional argument follows "
|
||||
"keyword argument");
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
@ -2890,8 +3028,8 @@ ast_for_call(struct compiling *c, const node *n, expr_ty func,
|
|||
expr_ty starred;
|
||||
if (ndoublestars) {
|
||||
ast_error(c, chch,
|
||||
"iterable argument unpacking follows "
|
||||
"keyword argument unpacking");
|
||||
"iterable argument unpacking follows "
|
||||
"keyword argument unpacking");
|
||||
return NULL;
|
||||
}
|
||||
e = ast_for_expr(c, CHILD(ch, 1));
|
||||
|
@ -2929,13 +3067,13 @@ ast_for_call(struct compiling *c, const node *n, expr_ty func,
|
|||
if (nkeywords) {
|
||||
if (ndoublestars) {
|
||||
ast_error(c, chch,
|
||||
"positional argument follows "
|
||||
"keyword argument unpacking");
|
||||
"positional argument follows "
|
||||
"keyword argument unpacking");
|
||||
}
|
||||
else {
|
||||
ast_error(c, chch,
|
||||
"positional argument follows "
|
||||
"keyword argument");
|
||||
"positional argument follows "
|
||||
"keyword argument");
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
@ -2996,7 +3134,7 @@ ast_for_call(struct compiling *c, const node *n, expr_ty func,
|
|||
tmp = ((keyword_ty)asdl_seq_GET(keywords, k))->arg;
|
||||
if (tmp && !PyUnicode_Compare(tmp, key)) {
|
||||
ast_error(c, chch,
|
||||
"keyword argument repeated");
|
||||
"keyword argument repeated");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
@ -3045,15 +3183,16 @@ ast_for_expr_stmt(struct compiling *c, const node *n)
|
|||
{
|
||||
REQ(n, expr_stmt);
|
||||
/* expr_stmt: testlist_star_expr (annassign | augassign (yield_expr|testlist) |
|
||||
('=' (yield_expr|testlist_star_expr))*)
|
||||
annassign: ':' test ['=' test]
|
||||
testlist_star_expr: (test|star_expr) (',' test|star_expr)* [',']
|
||||
augassign: '+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^='
|
||||
| '<<=' | '>>=' | '**=' | '//='
|
||||
[('=' (yield_expr|testlist_star_expr))+ [TYPE_COMMENT]] )
|
||||
annassign: ':' test ['=' (yield_expr|testlist)]
|
||||
testlist_star_expr: (test|star_expr) (',' (test|star_expr))* [',']
|
||||
augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' |
|
||||
'<<=' | '>>=' | '**=' | '//=')
|
||||
test: ... here starts the operator precedence dance
|
||||
*/
|
||||
int num = NCH(n);
|
||||
|
||||
if (NCH(n) == 1) {
|
||||
if (num == 1) {
|
||||
expr_ty e = ast_for_testlist(c, CHILD(n, 0));
|
||||
if (!e)
|
||||
return NULL;
|
||||
|
@ -3178,17 +3317,22 @@ ast_for_expr_stmt(struct compiling *c, const node *n)
|
|||
}
|
||||
}
|
||||
else {
|
||||
int i;
|
||||
int i, nch_minus_type, has_type_comment;
|
||||
asdl_seq *targets;
|
||||
node *value;
|
||||
expr_ty expression;
|
||||
string type_comment;
|
||||
|
||||
/* a normal assignment */
|
||||
REQ(CHILD(n, 1), EQUAL);
|
||||
targets = _Py_asdl_seq_new(NCH(n) / 2, c->c_arena);
|
||||
|
||||
has_type_comment = TYPE(CHILD(n, num - 1)) == TYPE_COMMENT;
|
||||
nch_minus_type = num - has_type_comment;
|
||||
|
||||
targets = _Py_asdl_seq_new(nch_minus_type / 2, c->c_arena);
|
||||
if (!targets)
|
||||
return NULL;
|
||||
for (i = 0; i < NCH(n) - 2; i += 2) {
|
||||
for (i = 0; i < nch_minus_type - 2; i += 2) {
|
||||
expr_ty e;
|
||||
node *ch = CHILD(n, i);
|
||||
if (TYPE(ch) == yield_expr) {
|
||||
|
@ -3205,14 +3349,21 @@ ast_for_expr_stmt(struct compiling *c, const node *n)
|
|||
|
||||
asdl_seq_SET(targets, i / 2, e);
|
||||
}
|
||||
value = CHILD(n, NCH(n) - 1);
|
||||
value = CHILD(n, nch_minus_type - 1);
|
||||
if (TYPE(value) == testlist_star_expr)
|
||||
expression = ast_for_testlist(c, value);
|
||||
else
|
||||
expression = ast_for_expr(c, value);
|
||||
if (!expression)
|
||||
return NULL;
|
||||
return Assign(targets, expression, LINENO(n), n->n_col_offset,
|
||||
if (has_type_comment) {
|
||||
type_comment = NEW_TYPE_COMMENT(CHILD(n, nch_minus_type));
|
||||
if (!type_comment)
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
type_comment = NULL;
|
||||
return Assign(targets, expression, type_comment, LINENO(n), n->n_col_offset,
|
||||
n->n_end_lineno, n->n_end_col_offset, c->c_arena);
|
||||
}
|
||||
}
|
||||
|
@ -3520,8 +3671,9 @@ ast_for_import_stmt(struct compiling *c, const node *n)
|
|||
n = CHILD(n, idx);
|
||||
n_children = NCH(n);
|
||||
if (n_children % 2 == 0) {
|
||||
ast_error(c, n, "trailing comma not allowed without"
|
||||
" surrounding parentheses");
|
||||
ast_error(c, n,
|
||||
"trailing comma not allowed without"
|
||||
" surrounding parentheses");
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
|
@ -3639,13 +3791,15 @@ ast_for_assert_stmt(struct compiling *c, const node *n)
|
|||
static asdl_seq *
|
||||
ast_for_suite(struct compiling *c, const node *n)
|
||||
{
|
||||
/* suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT */
|
||||
/* suite: simple_stmt | NEWLINE [TYPE_COMMENT NEWLINE] INDENT stmt+ DEDENT */
|
||||
asdl_seq *seq;
|
||||
stmt_ty s;
|
||||
int i, total, num, end, pos = 0;
|
||||
node *ch;
|
||||
|
||||
REQ(n, suite);
|
||||
if (TYPE(n) != func_body_suite) {
|
||||
REQ(n, suite);
|
||||
}
|
||||
|
||||
total = num_stmts(n);
|
||||
seq = _Py_asdl_seq_new(total, c->c_arena);
|
||||
|
@ -3669,7 +3823,13 @@ ast_for_suite(struct compiling *c, const node *n)
|
|||
}
|
||||
}
|
||||
else {
|
||||
for (i = 2; i < (NCH(n) - 1); i++) {
|
||||
i = 2;
|
||||
if (TYPE(CHILD(n, 1)) == TYPE_COMMENT) {
|
||||
i += 2;
|
||||
REQ(CHILD(n, 2), NEWLINE);
|
||||
}
|
||||
|
||||
for (; i < (NCH(n) - 1); i++) {
|
||||
ch = CHILD(n, i);
|
||||
REQ(ch, stmt);
|
||||
num = num_stmts(ch);
|
||||
|
@ -3903,11 +4063,15 @@ ast_for_for_stmt(struct compiling *c, const node *n0, bool is_async)
|
|||
expr_ty target, first;
|
||||
const node *node_target;
|
||||
int end_lineno, end_col_offset;
|
||||
/* for_stmt: 'for' exprlist 'in' testlist ':' suite ['else' ':' suite] */
|
||||
int has_type_comment;
|
||||
string type_comment;
|
||||
/* for_stmt: 'for' exprlist 'in' testlist ':' [TYPE_COMMENT] suite ['else' ':' suite] */
|
||||
REQ(n, for_stmt);
|
||||
|
||||
if (NCH(n) == 9) {
|
||||
seq = ast_for_suite(c, CHILD(n, 8));
|
||||
has_type_comment = TYPE(CHILD(n, 5)) == TYPE_COMMENT;
|
||||
|
||||
if (NCH(n) == 9 + has_type_comment) {
|
||||
seq = ast_for_suite(c, CHILD(n, 8 + has_type_comment));
|
||||
if (!seq)
|
||||
return NULL;
|
||||
}
|
||||
|
@ -3929,7 +4093,7 @@ ast_for_for_stmt(struct compiling *c, const node *n0, bool is_async)
|
|||
expression = ast_for_testlist(c, CHILD(n, 3));
|
||||
if (!expression)
|
||||
return NULL;
|
||||
suite_seq = ast_for_suite(c, CHILD(n, 5));
|
||||
suite_seq = ast_for_suite(c, CHILD(n, 5 + has_type_comment));
|
||||
if (!suite_seq)
|
||||
return NULL;
|
||||
|
||||
|
@ -3938,12 +4102,21 @@ ast_for_for_stmt(struct compiling *c, const node *n0, bool is_async)
|
|||
} else {
|
||||
get_last_end_pos(suite_seq, &end_lineno, &end_col_offset);
|
||||
}
|
||||
|
||||
if (has_type_comment) {
|
||||
type_comment = NEW_TYPE_COMMENT(CHILD(n, 5));
|
||||
if (!type_comment)
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
type_comment = NULL;
|
||||
|
||||
if (is_async)
|
||||
return AsyncFor(target, expression, suite_seq, seq,
|
||||
return AsyncFor(target, expression, suite_seq, seq, type_comment,
|
||||
LINENO(n0), n0->n_col_offset,
|
||||
end_lineno, end_col_offset, c->c_arena);
|
||||
else
|
||||
return For(target, expression, suite_seq, seq,
|
||||
return For(target, expression, suite_seq, seq, type_comment,
|
||||
LINENO(n), n->n_col_offset,
|
||||
end_lineno, end_col_offset, c->c_arena);
|
||||
}
|
||||
|
@ -4111,21 +4284,25 @@ ast_for_with_item(struct compiling *c, const node *n)
|
|||
return withitem(context_expr, optional_vars, c->c_arena);
|
||||
}
|
||||
|
||||
/* with_stmt: 'with' with_item (',' with_item)* ':' suite */
|
||||
/* with_stmt: 'with' with_item (',' with_item)* ':' [TYPE_COMMENT] suite */
|
||||
static stmt_ty
|
||||
ast_for_with_stmt(struct compiling *c, const node *n0, bool is_async)
|
||||
{
|
||||
const node * const n = is_async ? CHILD(n0, 1) : n0;
|
||||
int i, n_items, end_lineno, end_col_offset;
|
||||
int i, n_items, nch_minus_type, has_type_comment, end_lineno, end_col_offset;
|
||||
asdl_seq *items, *body;
|
||||
string type_comment;
|
||||
|
||||
REQ(n, with_stmt);
|
||||
|
||||
n_items = (NCH(n) - 2) / 2;
|
||||
has_type_comment = TYPE(CHILD(n, NCH(n) - 2)) == TYPE_COMMENT;
|
||||
nch_minus_type = NCH(n) - has_type_comment;
|
||||
|
||||
n_items = (nch_minus_type - 2) / 2;
|
||||
items = _Py_asdl_seq_new(n_items, c->c_arena);
|
||||
if (!items)
|
||||
return NULL;
|
||||
for (i = 1; i < NCH(n) - 2; i += 2) {
|
||||
for (i = 1; i < nch_minus_type - 2; i += 2) {
|
||||
withitem_ty item = ast_for_with_item(c, CHILD(n, i));
|
||||
if (!item)
|
||||
return NULL;
|
||||
|
@ -4137,11 +4314,19 @@ ast_for_with_stmt(struct compiling *c, const node *n0, bool is_async)
|
|||
return NULL;
|
||||
get_last_end_pos(body, &end_lineno, &end_col_offset);
|
||||
|
||||
if (has_type_comment) {
|
||||
type_comment = NEW_TYPE_COMMENT(CHILD(n, NCH(n) - 2));
|
||||
if (!type_comment)
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
type_comment = NULL;
|
||||
|
||||
if (is_async)
|
||||
return AsyncWith(items, body, LINENO(n0), n0->n_col_offset,
|
||||
return AsyncWith(items, body, type_comment, LINENO(n0), n0->n_col_offset,
|
||||
end_lineno, end_col_offset, c->c_arena);
|
||||
else
|
||||
return With(items, body, LINENO(n), n->n_col_offset,
|
||||
return With(items, body, type_comment, LINENO(n), n->n_col_offset,
|
||||
end_lineno, end_col_offset, c->c_arena);
|
||||
}
|
||||
|
||||
|
@ -4768,8 +4953,9 @@ fstring_find_expr(const char **str, const char *end, int raw, int recurse_lvl,
|
|||
if (ch == '\\') {
|
||||
/* Error: can't include a backslash character, inside
|
||||
parens or strings or not. */
|
||||
ast_error(c, n, "f-string expression part "
|
||||
"cannot include a backslash");
|
||||
ast_error(c, n,
|
||||
"f-string expression part "
|
||||
"cannot include a backslash");
|
||||
return -1;
|
||||
}
|
||||
if (quote_char) {
|
||||
|
@ -4893,8 +5079,9 @@ fstring_find_expr(const char **str, const char *end, int raw, int recurse_lvl,
|
|||
/* Validate the conversion. */
|
||||
if (!(conversion == 's' || conversion == 'r'
|
||||
|| conversion == 'a')) {
|
||||
ast_error(c, n, "f-string: invalid conversion character: "
|
||||
"expected 's', 'r', or 'a'");
|
||||
ast_error(c, n,
|
||||
"f-string: invalid conversion character: "
|
||||
"expected 's', 'r', or 'a'");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -5446,7 +5633,8 @@ parsestr(struct compiling *c, const node *n, int *bytesmode, int *rawmode,
|
|||
const char *ch;
|
||||
for (ch = s; *ch; ch++) {
|
||||
if (Py_CHARMASK(*ch) >= 0x80) {
|
||||
ast_error(c, n, "bytes can only contain ASCII "
|
||||
ast_error(c, n,
|
||||
"bytes can only contain ASCII "
|
||||
"literal characters.");
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -765,13 +765,13 @@ builtin_compile_impl(PyObject *module, PyObject *source, PyObject *filename,
|
|||
int compile_mode = -1;
|
||||
int is_ast;
|
||||
PyCompilerFlags cf;
|
||||
int start[] = {Py_file_input, Py_eval_input, Py_single_input};
|
||||
int start[] = {Py_file_input, Py_eval_input, Py_single_input, Py_func_type_input};
|
||||
PyObject *result;
|
||||
|
||||
cf.cf_flags = flags | PyCF_SOURCE_IS_UTF8;
|
||||
|
||||
if (flags &
|
||||
~(PyCF_MASK | PyCF_MASK_OBSOLETE | PyCF_DONT_IMPLY_DEDENT | PyCF_ONLY_AST))
|
||||
~(PyCF_MASK | PyCF_MASK_OBSOLETE | PyCF_DONT_IMPLY_DEDENT | PyCF_ONLY_AST | PyCF_TYPE_COMMENTS))
|
||||
{
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"compile(): unrecognised flags");
|
||||
|
@ -795,9 +795,21 @@ builtin_compile_impl(PyObject *module, PyObject *source, PyObject *filename,
|
|||
compile_mode = 1;
|
||||
else if (strcmp(mode, "single") == 0)
|
||||
compile_mode = 2;
|
||||
else if (strcmp(mode, "func_type") == 0) {
|
||||
if (!(flags & PyCF_ONLY_AST)) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"compile() mode 'func_type' requires flag PyCF_ONLY_AST");
|
||||
goto error;
|
||||
}
|
||||
compile_mode = 3;
|
||||
}
|
||||
else {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"compile() mode must be 'exec', 'eval' or 'single'");
|
||||
const char *msg;
|
||||
if (flags & PyCF_ONLY_AST)
|
||||
msg = "compile() mode must be 'exec', 'eval', 'single' or 'func_type'";
|
||||
else
|
||||
msg = "compile() mode must be 'exec', 'eval' or 'single'";
|
||||
PyErr_SetString(PyExc_ValueError, msg);
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
|
1033
Python/graminit.c
1033
Python/graminit.c
File diff suppressed because it is too large
Load Diff
|
@ -158,6 +158,8 @@ static int PARSER_FLAGS(PyCompilerFlags *flags)
|
|||
parser_flags |= PyPARSE_IGNORE_COOKIE;
|
||||
if (flags->cf_flags & CO_FUTURE_BARRY_AS_BDFL)
|
||||
parser_flags |= PyPARSE_BARRY_AS_BDFL;
|
||||
if (flags->cf_flags & PyCF_TYPE_COMMENTS)
|
||||
parser_flags |= PyPARSE_TYPE_COMMENTS;
|
||||
return parser_flags;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue