Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
64fddc42
Commit
64fddc42
authored
May 17, 2018
by
Serhiy Storchaka
Committed by
Łukasz Langa
May 16, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
bpo-33475: Fix and improve converting annotations to strings. (GH-6774)
parent
d852142c
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
358 additions
and
603 deletions
+358
-603
Include/ast.h
Include/ast.h
+1
-3
Lib/test/test_future.py
Lib/test/test_future.py
+64
-63
Misc/NEWS.d/next/Core and Builtins/2018-05-13-01-26-18.bpo-33475.rI0y1U.rst
...ore and Builtins/2018-05-13-01-26-18.bpo-33475.rI0y1U.rst
+2
-0
Python/ast_unparse.c
Python/ast_unparse.c
+290
-536
Python/compile.c
Python/compile.c
+1
-1
No files found.
Include/ast.h
View file @
64fddc42
...
...
@@ -19,9 +19,7 @@ PyAPI_FUNC(mod_ty) PyAST_FromNodeObject(
#ifndef Py_LIMITED_API
/* _PyAST_ExprAsUnicode is defined in ast_unparse.c */
PyAPI_FUNC
(
PyObject
*
)
_PyAST_ExprAsUnicode
(
expr_ty
e
,
int
omit_parens
);
PyAPI_FUNC
(
PyObject
*
)
_PyAST_ExprAsUnicode
(
expr_ty
);
#endif
/* !Py_LIMITED_API */
...
...
Lib/test/test_future.py
View file @
64fddc42
...
...
@@ -157,55 +157,76 @@ class AnnotationsFutureTestCase(unittest.TestCase):
eq
(
'True or False or None'
)
eq
(
'True and False'
)
eq
(
'True and False and None'
)
eq
(
'(Name1 and Name2) or Name3'
)
eq
(
'Name1 or (Name2 and Name3)'
)
eq
(
'(Name1 and Name2) or (Name3 and Name4)'
)
eq
(
'Name1 or (Name2 and Name3) or Name4'
)
eq
(
'Name1 and Name2 or Name3'
)
eq
(
'Name1 and (Name2 or Name3)'
)
eq
(
'Name1 or Name2 and Name3'
)
eq
(
'(Name1 or Name2) and Name3'
)
eq
(
'Name1 and Name2 or Name3 and Name4'
)
eq
(
'Name1 or Name2 and Name3 or Name4'
)
eq
(
'a + b + (c + d)'
)
eq
(
'a * b * (c * d)'
)
eq
(
'(a ** b) ** c ** d'
)
eq
(
'v1 << 2'
)
eq
(
'1 >> v2'
)
eq
(
r
'1 % finished'
)
eq
(
'
((1 + v2) - (v3 * 4)) ^ (((5 ** v6) / 7) // 8)
'
)
eq
(
'1 % finished'
)
eq
(
'
1 + v2 - v3 * 4 ^ 5 ** v6 / 7 // 8
'
)
eq
(
'not great'
)
eq
(
'not not great'
)
eq
(
'~great'
)
eq
(
'+value'
)
eq
(
'++value'
)
eq
(
'-1'
)
eq
(
'(~int) and (not ((v1 ^ (123 + v2)) | True))'
)
eq
(
'~int and not v1 ^ 123 + v2 | True'
)
eq
(
'a + (not b)'
)
eq
(
'lambda arg: None'
)
eq
(
'lambda a=True: a'
)
eq
(
'lambda a, b, c=True: a'
)
eq
(
"lambda a, b, c=True, *, d=(1 << v2), e='str': a"
)
eq
(
"lambda a, b, c=True, *vararg, d=(v1 << 2), e='str', **kwargs: a + b"
)
eq
(
"lambda a, b, c=True, *, d=1 << v2, e='str': a"
)
eq
(
"lambda a, b, c=True, *vararg, d=v1 << 2, e='str', **kwargs: a + b"
)
eq
(
'lambda x: lambda y: x + y'
)
eq
(
'1 if True else 2'
)
eq
(
'(str or None) if True else (str or bytes or None)'
)
eq
(
'(str or None) if (1 if True else 2) else (str or bytes or None)'
)
eq
(
"{'2.7': dead, '3.7': (long_live or die_hard)}"
)
eq
(
"{'2.7': dead, '3.7': (long_live or die_hard), **{'3.6': verygood}}"
)
eq
(
'str or None if int or True else str or bytes or None'
)
eq
(
'str or None if (1 if True else 2) else str or bytes or None'
)
eq
(
"0 if not x else 1 if x > 0 else -1"
)
eq
(
"(1 if x > 0 else -1) if x else 0"
)
eq
(
"{'2.7': dead, '3.7': long_live or die_hard}"
)
eq
(
"{'2.7': dead, '3.7': long_live or die_hard, **{'3.6': verygood}}"
)
eq
(
"{**a, **b, **c}"
)
eq
(
"{'2.7', '3.6', '3.7', '3.8', '3.9', ('4.0' if gilectomy else '3.10')}"
)
eq
(
"({'a': 'b'}, (True or False), (+value), 'string', b'bytes') or None"
)
eq
(
"{'2.7', '3.6', '3.7', '3.8', '3.9', '4.0' if gilectomy else '3.10'}"
)
eq
(
"{*a, *b, *c}"
)
eq
(
"({'a': 'b'}, True or False, +value, 'string', b'bytes') or None"
)
eq
(
"()"
)
eq
(
"(1,)"
)
eq
(
"(1, 2)"
)
eq
(
"(1, 2, 3)"
)
eq
(
"(a,)"
)
eq
(
"(a, b)"
)
eq
(
"(a, b, c)"
)
eq
(
"(*a, *b, *c)"
)
eq
(
"[]"
)
eq
(
"[1, 2, 3, 4, 5, 6, 7, 8, 9, (10 or A), (11 or B), (12 or C)]"
)
eq
(
"[1, 2, 3, 4, 5, 6, 7, 8, 9, 10 or A, 11 or B, 12 or C]"
)
eq
(
"[*a, *b, *c]"
)
eq
(
"{i for i in (1, 2, 3)}"
)
eq
(
"{
(i ** 2)
for i in (1, 2, 3)}"
)
eq
(
"{
(i ** 2)
for i, _ in ((1, 'a'), (2, 'b'), (3, 'c'))}"
)
eq
(
"{
((i ** 2) + j)
for i in (1, 2, 3) for j in (1, 2, 3)}"
)
eq
(
"{
i ** 2
for i in (1, 2, 3)}"
)
eq
(
"{
i ** 2
for i, _ in ((1, 'a'), (2, 'b'), (3, 'c'))}"
)
eq
(
"{
i ** 2 + j
for i in (1, 2, 3) for j in (1, 2, 3)}"
)
eq
(
"[i for i in (1, 2, 3)]"
)
eq
(
"[(i ** 2) for i in (1, 2, 3)]"
)
eq
(
"[(i ** 2) for i, _ in ((1, 'a'), (2, 'b'), (3, 'c'))]"
)
eq
(
"[((i ** 2) + j) for i in (1, 2, 3) for j in (1, 2, 3)]"
)
eq
(
r"{i: 0 for i in (1, 2, 3)}"
)
eq
(
"[i ** 2 for i in (1, 2, 3)]"
)
eq
(
"[i ** 2 for i, _ in ((1, 'a'), (2, 'b'), (3, 'c'))]"
)
eq
(
"[i ** 2 + j for i in (1, 2, 3) for j in (1, 2, 3)]"
)
eq
(
"(i for i in (1, 2, 3))"
)
eq
(
"(i ** 2 for i in (1, 2, 3))"
)
eq
(
"(i ** 2 for i, _ in ((1, 'a'), (2, 'b'), (3, 'c')))"
)
eq
(
"(i ** 2 + j for i in (1, 2, 3) for j in (1, 2, 3))"
)
eq
(
"{i: 0 for i in (1, 2, 3)}"
)
eq
(
"{i: j for i, j in ((1, 'a'), (2, 'b'), (3, 'c'))}"
)
eq
(
"[(x, y) for x, y in (a, b)]"
)
eq
(
"[(x,) for x, in (a,)]"
)
eq
(
"Python3 > Python2 > COBOL"
)
eq
(
"Life is Life"
)
eq
(
"call()"
)
eq
(
"call(arg)"
)
eq
(
"call(kwarg='hey')"
)
eq
(
"call(arg, kwarg='hey')"
)
eq
(
"call(arg, another, kwarg='hey', **kwargs)"
)
eq
(
"call(arg, *args, another, kwarg='hey')"
)
eq
(
"call(arg, another, kwarg='hey', **kwargs, kwarg2='ho')"
)
eq
(
"lukasz.langa.pl"
)
eq
(
"call.me(maybe)"
)
eq
(
"1 .real"
)
...
...
@@ -213,6 +234,7 @@ class AnnotationsFutureTestCase(unittest.TestCase):
eq
(
"....__class__"
)
eq
(
"list[str]"
)
eq
(
"dict[str, int]"
)
eq
(
"set[str,]"
)
eq
(
"tuple[str, ...]"
)
eq
(
"tuple[str, int, float, dict[str, int]]"
)
eq
(
"slice[0]"
)
...
...
@@ -222,49 +244,28 @@ class AnnotationsFutureTestCase(unittest.TestCase):
eq
(
"slice[:-1]"
)
eq
(
"slice[1:]"
)
eq
(
"slice[::-1]"
)
eq
(
'(str or None) if (sys.version_info[0] > (3,)) else (str or bytes or None)'
)
eq
(
"slice[()]"
)
eq
(
"slice[a, b:c, d:e:f]"
)
eq
(
"slice[(x for x in a)]"
)
eq
(
'str or None if sys.version_info[0] > (3,) else str or bytes or None'
)
eq
(
"f'f-string without formatted values is just a string'"
)
eq
(
"f'{{NOT a formatted value}}'"
)
eq
(
"f'some f-string with {a} {few():.2f} {formatted.values!r}'"
)
eq
(
'''f"{f'{nested} inner'} outer"'''
)
eq
(
"f'space between opening braces: { {a for a in (1, 2, 3)}}'"
)
def
test_annotations_inexact
(
self
):
"""Source formatting is not always preserved
This is due to reconstruction from AST. We *need to* put the parens
in nested expressions because we don't know if the source code
had them in the first place or not.
"""
eq
=
partial
(
self
.
assertAnnotationEqual
,
drop_parens
=
True
)
eq
(
'Name1 and Name2 or Name3'
)
eq
(
'Name1 or Name2 and Name3'
)
eq
(
'Name1 and Name2 or Name3 and Name4'
)
eq
(
'Name1 or Name2 and Name3 or Name4'
)
eq
(
'1 + v2 - v3 * 4 ^ v5 ** 6 / 7 // 8'
)
eq
(
'~int and not v1 ^ 123 + v2 | True'
)
eq
(
'str or None if True else str or bytes or None'
)
eq
(
"{'2.7': dead, '3.7': long_live or die_hard}"
)
eq
(
"{'2.7', '3.6', '3.7', '3.8', '3.9', '4.0' if gilectomy else '3.10'}"
)
eq
(
"[1, 2, 3, 4, 5, 6, 7, 8, 9, 10 or A, 11 or B, 12 or C]"
)
# Consequently, we always drop unnecessary parens if they were given in
# the outer scope:
some_name
=
self
.
getActual
(
"(SomeName)"
)
self
.
assertEqual
(
some_name
,
'SomeName'
)
# Interestingly, in the case of tuples (and generator expressions) the
# parens are *required* by the Python syntax in the annotation context.
# But there's no point storing that detail in __annotations__ so we're
# fine with the parens-less form.
eq
=
partial
(
self
.
assertAnnotationEqual
,
is_tuple
=
True
)
eq
(
"(Good, Bad, Ugly)"
)
eq
(
"(i for i in (1, 2, 3))"
)
eq
(
"((i ** 2) for i in (1, 2, 3))"
)
eq
(
"((i ** 2) for i, _ in ((1, 'a'), (2, 'b'), (3, 'c')))"
)
eq
(
"(((i ** 2) + j) for i in (1, 2, 3) for j in (1, 2, 3))"
)
eq
(
"(*starred)"
)
eq
(
"f'{(lambda x: x)}'"
)
eq
(
"f'{(None if a else lambda x: x)}'"
)
eq
(
'(yield from outside_of_generator)'
)
eq
(
'(yield)'
)
eq
(
'(await some.complicated[0].call(with_args=(True or (1 is not 1))))'
)
eq
(
'(yield a + b)'
)
eq
(
'await some.complicated[0].call(with_args=True or 1 is not 1)'
)
eq
(
'[x for x in (a if b else c)]'
)
eq
(
'[x for x in a if (b if c else d)]'
)
eq
(
'f(x for x in a)'
)
eq
(
'f(1, (x for x in a))'
)
eq
(
'f((x for x in a), 2)'
)
eq
(
'(((a)))'
,
'a'
)
eq
(
'(((a, b)))'
,
'(a, b)'
)
if
__name__
==
"__main__"
:
...
...
Misc/NEWS.d/next/Core and Builtins/2018-05-13-01-26-18.bpo-33475.rI0y1U.rst
0 → 100644
View file @
64fddc42
Fixed miscellaneous bugs in converting annotations to strings and optimized
parentheses in the string representation.
Python/ast_unparse.c
View file @
64fddc42
...
...
@@ -9,13 +9,15 @@ static PyObject *_str_dbl_close_br;
/* Forward declarations for recursion via helper functions. */
static
PyObject
*
expr_as_unicode
(
expr_ty
e
,
bool
omit_parens
);
expr_as_unicode
(
expr_ty
e
,
int
level
);
static
int
append_ast_expr
(
_PyUnicodeWriter
*
writer
,
expr_ty
e
,
bool
omit_parens
);
append_ast_expr
(
_PyUnicodeWriter
*
writer
,
expr_ty
e
,
int
level
);
static
int
append_joinedstr
(
_PyUnicodeWriter
*
writer
,
expr_ty
e
,
bool
is_format_spec
);
static
int
append_formattedvalue
(
_PyUnicodeWriter
*
writer
,
expr_ty
e
,
bool
is_format_spec
);
static
int
append_ast_slice
(
_PyUnicodeWriter
*
writer
,
slice_ty
slice
);
static
int
append_charp
(
_PyUnicodeWriter
*
writer
,
const
char
*
charp
)
...
...
@@ -23,6 +25,39 @@ append_charp(_PyUnicodeWriter *writer, const char *charp)
return
_PyUnicodeWriter_WriteASCIIString
(
writer
,
charp
,
-
1
);
}
#define APPEND_STR_FINISH(str) do { \
return append_charp(writer, (str)); \
} while (0)
#define APPEND_STR(str) do { \
if (-1 == append_charp(writer, (str))) { \
return -1; \
} \
} while (0)
#define APPEND_STR_IF(cond, str) do { \
if ((cond) && -1 == append_charp(writer, (str))) { \
return -1; \
} \
} while (0)
#define APPEND_STR_IF_NOT_FIRST(str) do { \
APPEND_STR_IF(!first, (str)); \
first = false; \
} while (0)
#define APPEND_EXPR(expr, pr) do { \
if (-1 == append_ast_expr(writer, (expr), (pr))) { \
return -1; \
} \
} while (0)
#define APPEND(type, value) do { \
if (-1 == append_ast_ ## type(writer, (value))) { \
return -1; \
} \
} while (0)
static
int
append_repr
(
_PyUnicodeWriter
*
writer
,
PyObject
*
obj
)
{
...
...
@@ -37,111 +72,108 @@ append_repr(_PyUnicodeWriter *writer, PyObject *obj)
return
ret
;
}
static
int
append_ast_boolop
(
_PyUnicodeWriter
*
writer
,
expr_ty
e
,
bool
omit_parens
)
/* Priority levels */
enum
{
PR_TUPLE
,
PR_TEST
,
/* 'if'-'else', 'lambda' */
PR_OR
,
/* 'or' */
PR_AND
,
/* 'and' */
PR_NOT
,
/* 'not' */
PR_CMP
,
/* '<', '>', '==', '>=', '<=', '!=',
'in', 'not in', 'is', 'is not' */
PR_EXPR
,
PR_BOR
=
PR_EXPR
,
/* '|' */
PR_BXOR
,
/* '^' */
PR_BAND
,
/* '&' */
PR_SHIFT
,
/* '<<', '>>' */
PR_ARITH
,
/* '+', '-' */
PR_TERM
,
/* '*', '@', '/', '%', '//' */
PR_FACTOR
,
/* unary '+', '-', '~' */
PR_POWER
,
/* '**' */
PR_AWAIT
,
/* 'await' */
PR_ATOM
,
};
static
int
append_ast_boolop
(
_PyUnicodeWriter
*
writer
,
expr_ty
e
,
int
level
)
{
Py_ssize_t
i
,
value_count
;
asdl_seq
*
values
;
const
char
*
op
=
(
e
->
v
.
BoolOp
.
op
==
And
)
?
" and "
:
" or "
;
int
pr
=
(
e
->
v
.
BoolOp
.
op
==
And
)
?
PR_AND
:
PR_OR
;
if
(
!
omit_parens
&&
-
1
==
append_charp
(
writer
,
"("
))
{
return
-
1
;
}
APPEND_STR_IF
(
level
>
pr
,
"("
);
values
=
e
->
v
.
BoolOp
.
values
;
value_count
=
asdl_seq_LEN
(
values
)
-
1
;
assert
(
value_count
>=
0
);
value_count
=
asdl_seq_LEN
(
values
);
if
(
-
1
==
append_ast_expr
(
writer
,
(
expr_ty
)
asdl_seq_GET
(
values
,
0
),
false
))
{
return
-
1
;
}
const
char
*
op
=
(
e
->
v
.
BoolOp
.
op
==
And
)
?
" and "
:
" or "
;
for
(
i
=
1
;
i
<=
value_count
;
++
i
)
{
if
(
-
1
==
append_charp
(
writer
,
op
))
{
return
-
1
;
}
if
(
-
1
==
append_ast_expr
(
writer
,
(
expr_ty
)
asdl_seq_GET
(
values
,
i
),
false
))
{
return
-
1
;
}
for
(
i
=
0
;
i
<
value_count
;
++
i
)
{
APPEND_STR_IF
(
i
>
0
,
op
);
APPEND_EXPR
((
expr_ty
)
asdl_seq_GET
(
values
,
i
),
pr
+
1
);
}
return
omit_parens
?
0
:
append_charp
(
writer
,
")"
);
APPEND_STR_IF
(
level
>
pr
,
")"
);
return
0
;
}
static
int
append_ast_binop
(
_PyUnicodeWriter
*
writer
,
expr_ty
e
,
bool
omit_parens
)
append_ast_binop
(
_PyUnicodeWriter
*
writer
,
expr_ty
e
,
int
level
)
{
const
char
*
op
;
if
(
!
omit_parens
&&
-
1
==
append_charp
(
writer
,
"("
))
{
return
-
1
;
}
if
(
-
1
==
append_ast_expr
(
writer
,
e
->
v
.
BinOp
.
left
,
false
))
{
return
-
1
;
}
switch
(
e
->
v
.
BinOp
.
op
)
{
case
Add
:
op
=
" + "
;
break
;
case
Sub
:
op
=
" - "
;
break
;
case
Mult
:
op
=
" * "
;
break
;
case
MatMult
:
op
=
" @ "
;
break
;
case
Div
:
op
=
" / "
;
break
;
case
Mod
:
op
=
" % "
;
break
;
case
LShift
:
op
=
" << "
;
break
;
case
RShift
:
op
=
" >> "
;
break
;
case
BitOr
:
op
=
" | "
;
break
;
case
BitXor
:
op
=
" ^ "
;
break
;
case
BitAnd
:
op
=
" & "
;
break
;
case
FloorDiv
:
op
=
" // "
;
break
;
case
Pow
:
op
=
" ** "
;
break
;
int
pr
;
bool
rassoc
=
false
;
/* is right-associative? */
switch
(
e
->
v
.
BinOp
.
op
)
{
case
Add
:
op
=
" + "
;
pr
=
PR_ARITH
;
break
;
case
Sub
:
op
=
" - "
;
pr
=
PR_ARITH
;
break
;
case
Mult
:
op
=
" * "
;
pr
=
PR_TERM
;
break
;
case
MatMult
:
op
=
" @ "
;
pr
=
PR_TERM
;
break
;
case
Div
:
op
=
" / "
;
pr
=
PR_TERM
;
break
;
case
Mod
:
op
=
" % "
;
pr
=
PR_TERM
;
break
;
case
LShift
:
op
=
" << "
;
pr
=
PR_SHIFT
;
break
;
case
RShift
:
op
=
" >> "
;
pr
=
PR_SHIFT
;
break
;
case
BitOr
:
op
=
" | "
;
pr
=
PR_BOR
;
break
;
case
BitXor
:
op
=
" ^ "
;
pr
=
PR_BXOR
;
break
;
case
BitAnd
:
op
=
" & "
;
pr
=
PR_BAND
;
break
;
case
FloorDiv
:
op
=
" // "
;
pr
=
PR_TERM
;
break
;
case
Pow
:
op
=
" ** "
;
pr
=
PR_POWER
;
rassoc
=
true
;
break
;
default:
Py_UNREACHABLE
();
}
if
(
-
1
==
append_charp
(
writer
,
op
))
{
return
-
1
;
}
if
(
-
1
==
append_ast_expr
(
writer
,
e
->
v
.
BinOp
.
right
,
false
))
{
PyErr_SetString
(
PyExc_SystemError
,
"unknown binary operator"
);
return
-
1
;
}
return
omit_parens
?
0
:
append_charp
(
writer
,
")"
);
APPEND_STR_IF
(
level
>
pr
,
"("
);
APPEND_EXPR
(
e
->
v
.
BinOp
.
left
,
pr
+
rassoc
);
APPEND_STR
(
op
);
APPEND_EXPR
(
e
->
v
.
BinOp
.
right
,
pr
+
!
rassoc
);
APPEND_STR_IF
(
level
>
pr
,
")"
);
return
0
;
}
static
int
append_ast_unaryop
(
_PyUnicodeWriter
*
writer
,
expr_ty
e
,
bool
omit_parens
)
append_ast_unaryop
(
_PyUnicodeWriter
*
writer
,
expr_ty
e
,
int
level
)
{
const
char
*
op
;
int
pr
;
if
(
!
omit_parens
&&
-
1
==
append_charp
(
writer
,
"("
))
{
return
-
1
;
}
switch
(
e
->
v
.
UnaryOp
.
op
)
{
case
Invert
:
op
=
"~"
;
break
;
case
Not
:
op
=
"not "
;
break
;
case
UAdd
:
op
=
"+"
;
break
;
case
USub
:
op
=
"-"
;
break
;
switch
(
e
->
v
.
UnaryOp
.
op
)
{
case
Invert
:
op
=
"~"
;
pr
=
PR_FACTOR
;
break
;
case
Not
:
op
=
"not "
;
pr
=
PR_NOT
;
break
;
case
UAdd
:
op
=
"+"
;
pr
=
PR_FACTOR
;
break
;
case
USub
:
op
=
"-"
;
pr
=
PR_FACTOR
;
break
;
default:
Py_UNREACHABLE
();
}
if
(
-
1
==
append_charp
(
writer
,
op
))
{
return
-
1
;
}
if
(
-
1
==
append_ast_expr
(
writer
,
e
->
v
.
UnaryOp
.
operand
,
false
))
{
PyErr_SetString
(
PyExc_SystemError
,
"unknown unary operator"
);
return
-
1
;
}
return
omit_parens
?
0
:
append_charp
(
writer
,
")"
);
APPEND_STR_IF
(
level
>
pr
,
"("
);
APPEND_STR
(
op
);
APPEND_EXPR
(
e
->
v
.
UnaryOp
.
operand
,
pr
);
APPEND_STR_IF
(
level
>
pr
,
")"
);
return
0
;
}
static
int
...
...
@@ -151,12 +183,8 @@ append_ast_arg(_PyUnicodeWriter *writer, arg_ty arg)
return
-
1
;
}
if
(
arg
->
annotation
)
{
if
(
-
1
==
append_charp
(
writer
,
": "
))
{
return
-
1
;
}
if
(
-
1
==
append_ast_expr
(
writer
,
arg
->
annotation
,
true
))
{
return
-
1
;
}
APPEND_STR
(
": "
);
APPEND_EXPR
(
arg
->
annotation
,
PR_TEST
);
}
return
0
;
}
...
...
@@ -166,8 +194,6 @@ append_ast_args(_PyUnicodeWriter *writer, arguments_ty args)
{
bool
first
;
Py_ssize_t
i
,
di
,
arg_count
,
default_count
;
arg_ty
arg
;
expr_ty
default_
;
first
=
true
;
...
...
@@ -175,47 +201,22 @@ append_ast_args(_PyUnicodeWriter *writer, arguments_ty args)
arg_count
=
asdl_seq_LEN
(
args
->
args
);
default_count
=
asdl_seq_LEN
(
args
->
defaults
);
for
(
i
=
0
;
i
<
arg_count
;
i
++
)
{
if
(
first
)
{
first
=
false
;
}
else
if
(
-
1
==
append_charp
(
writer
,
", "
))
{
return
-
1
;
}
arg
=
(
arg_ty
)
asdl_seq_GET
(
args
->
args
,
i
);
if
(
-
1
==
append_ast_arg
(
writer
,
arg
))
{
return
-
1
;
}
APPEND_STR_IF_NOT_FIRST
(
", "
);
APPEND
(
arg
,
(
arg_ty
)
asdl_seq_GET
(
args
->
args
,
i
));
di
=
i
-
arg_count
+
default_count
;
if
(
di
>=
0
)
{
if
(
-
1
==
append_charp
(
writer
,
"="
))
{
return
-
1
;
}
default_
=
(
expr_ty
)
asdl_seq_GET
(
args
->
defaults
,
di
);
if
(
-
1
==
append_ast_expr
(
writer
,
default_
,
false
))
{
return
-
1
;
}
APPEND_STR
(
"="
);
APPEND_EXPR
((
expr_ty
)
asdl_seq_GET
(
args
->
defaults
,
di
),
PR_TEST
);
}
}
/* vararg, or bare '*' if no varargs but keyword-only arguments present */
if
(
args
->
vararg
||
args
->
kwonlyargs
)
{
if
(
first
)
{
first
=
false
;
}
else
if
(
-
1
==
append_charp
(
writer
,
", "
))
{
return
-
1
;
}
if
(
-
1
==
append_charp
(
writer
,
"*"
))
{
return
-
1
;
}
APPEND_STR_IF_NOT_FIRST
(
", "
);
APPEND_STR
(
"*"
);
if
(
args
->
vararg
)
{
if
(
-
1
==
append_ast_arg
(
writer
,
args
->
vararg
))
{
return
-
1
;
}
APPEND
(
arg
,
args
->
vararg
);
}
}
...
...
@@ -223,223 +224,127 @@ append_ast_args(_PyUnicodeWriter *writer, arguments_ty args)
arg_count
=
asdl_seq_LEN
(
args
->
kwonlyargs
);
default_count
=
asdl_seq_LEN
(
args
->
kw_defaults
);
for
(
i
=
0
;
i
<
arg_count
;
i
++
)
{
if
(
first
)
{
first
=
false
;
}
else
if
(
-
1
==
append_charp
(
writer
,
", "
))
{
return
-
1
;
}
arg
=
(
arg_ty
)
asdl_seq_GET
(
args
->
kwonlyargs
,
i
);
if
(
-
1
==
append_ast_arg
(
writer
,
arg
))
{
return
-
1
;
}
APPEND_STR_IF_NOT_FIRST
(
", "
);
APPEND
(
arg
,
(
arg_ty
)
asdl_seq_GET
(
args
->
kwonlyargs
,
i
));
di
=
i
-
arg_count
+
default_count
;
if
(
di
>=
0
)
{
if
(
-
1
==
append_charp
(
writer
,
"="
))
{
return
-
1
;
}
default_
=
(
expr_ty
)
asdl_seq_GET
(
args
->
kw_defaults
,
di
);
if
(
-
1
==
append_ast_expr
(
writer
,
default_
,
false
))
{
return
-
1
;
}
APPEND_STR
(
"="
);
APPEND_EXPR
((
expr_ty
)
asdl_seq_GET
(
args
->
kw_defaults
,
di
),
PR_TEST
);
}
}
/* **kwargs */
if
(
args
->
kwarg
)
{
if
(
first
)
{
first
=
false
;
}
else
if
(
-
1
==
append_charp
(
writer
,
", "
))
{
return
-
1
;
}
if
(
-
1
==
append_charp
(
writer
,
"**"
))
{
return
-
1
;
}
if
(
-
1
==
append_ast_arg
(
writer
,
args
->
kwarg
))
{
return
-
1
;
}
APPEND_STR_IF_NOT_FIRST
(
", "
);
APPEND_STR
(
"**"
);
APPEND
(
arg
,
args
->
kwarg
);
}
return
0
;
}
static
int
append_ast_lambda
(
_PyUnicodeWriter
*
writer
,
expr_ty
e
,
bool
omit_parens
)
append_ast_lambda
(
_PyUnicodeWriter
*
writer
,
expr_ty
e
,
int
level
)
{
if
(
!
omit_parens
&&
-
1
==
append_charp
(
writer
,
"("
))
{
return
-
1
;
}
if
(
-
1
==
append_charp
(
writer
,
"lambda "
))
{
return
-
1
;
}
if
(
-
1
==
append_ast_args
(
writer
,
e
->
v
.
Lambda
.
args
))
{
return
-
1
;
}
if
(
-
1
==
append_charp
(
writer
,
": "
))
{
return
-
1
;
}
if
(
-
1
==
append_ast_expr
(
writer
,
e
->
v
.
Lambda
.
body
,
true
))
{
return
-
1
;
}
return
omit_parens
?
0
:
append_charp
(
writer
,
")"
);
APPEND_STR_IF
(
level
>
PR_TEST
,
"("
);
APPEND_STR
(
"lambda "
);
APPEND
(
args
,
e
->
v
.
Lambda
.
args
);
APPEND_STR
(
": "
);
APPEND_EXPR
(
e
->
v
.
Lambda
.
body
,
PR_TEST
);
APPEND_STR_IF
(
level
>
PR_TEST
,
")"
);
return
0
;
}
static
int
append_ast_ifexp
(
_PyUnicodeWriter
*
writer
,
expr_ty
e
,
bool
omit_parens
)
append_ast_ifexp
(
_PyUnicodeWriter
*
writer
,
expr_ty
e
,
int
level
)
{
if
(
!
omit_parens
&&
-
1
==
append_charp
(
writer
,
"("
))
{
return
-
1
;
}
if
(
-
1
==
append_ast_expr
(
writer
,
e
->
v
.
IfExp
.
body
,
false
))
{
return
-
1
;
}
if
(
-
1
==
append_charp
(
writer
,
" if "
))
{
return
-
1
;
}
if
(
-
1
==
append_ast_expr
(
writer
,
e
->
v
.
IfExp
.
test
,
false
))
{
return
-
1
;
}
if
(
-
1
==
append_charp
(
writer
,
" else "
))
{
return
-
1
;
}
if
(
-
1
==
append_ast_expr
(
writer
,
e
->
v
.
IfExp
.
orelse
,
false
))
{
return
-
1
;
}
return
omit_parens
?
0
:
append_charp
(
writer
,
")"
);
APPEND_STR_IF
(
level
>
PR_TEST
,
"("
);
APPEND_EXPR
(
e
->
v
.
IfExp
.
body
,
PR_TEST
+
1
);
APPEND_STR
(
" if "
);
APPEND_EXPR
(
e
->
v
.
IfExp
.
test
,
PR_TEST
+
1
);
APPEND_STR
(
" else "
);
APPEND_EXPR
(
e
->
v
.
IfExp
.
orelse
,
PR_TEST
);
APPEND_STR_IF
(
level
>
PR_TEST
,
")"
);
return
0
;
}
static
int
append_ast_dict
(
_PyUnicodeWriter
*
writer
,
expr_ty
e
)
{
Py_ssize_t
i
,
value_count
;
expr_ty
key_node
,
value_node
;
if
(
-
1
==
append_charp
(
writer
,
"{"
))
{
return
-
1
;
}
expr_ty
key_node
;
APPEND_STR
(
"{"
);
value_count
=
asdl_seq_LEN
(
e
->
v
.
Dict
.
values
);
for
(
i
=
0
;
i
<
value_count
;
i
++
)
{
if
(
i
>
0
&&
-
1
==
append_charp
(
writer
,
", "
))
{
return
-
1
;
}
APPEND_STR_IF
(
i
>
0
,
", "
);
key_node
=
(
expr_ty
)
asdl_seq_GET
(
e
->
v
.
Dict
.
keys
,
i
);
if
(
key_node
!=
NULL
)
{
if
(
-
1
==
append_ast_expr
(
writer
,
key_node
,
false
))
{
return
-
1
;
}
if
(
-
1
==
append_charp
(
writer
,
": "
))
{
return
-
1
;
}
}
else
if
(
-
1
==
append_charp
(
writer
,
"**"
))
{
return
-
1
;
APPEND_EXPR
(
key_node
,
PR_TEST
);
APPEND_STR
(
": "
);
APPEND_EXPR
((
expr_ty
)
asdl_seq_GET
(
e
->
v
.
Dict
.
values
,
i
),
PR_TEST
);
}
value_node
=
(
expr_ty
)
asdl_seq_GET
(
e
->
v
.
Dict
.
values
,
i
);
if
(
-
1
==
append_ast_expr
(
writer
,
value_node
,
false
))
{
return
-
1
;
else
{
APPEND_STR
(
"**"
);
APPEND_EXPR
((
expr_ty
)
asdl_seq_GET
(
e
->
v
.
Dict
.
values
,
i
),
PR_EXPR
);
}
}
return
append_charp
(
writer
,
"}"
);
APPEND_STR_FINISH
(
"}"
);
}
static
int
append_ast_set
(
_PyUnicodeWriter
*
writer
,
expr_ty
e
)
{
Py_ssize_t
i
,
elem_count
;
expr_ty
elem_node
;
if
(
-
1
==
append_charp
(
writer
,
"{"
))
{
return
-
1
;
}
APPEND_STR
(
"{"
);
elem_count
=
asdl_seq_LEN
(
e
->
v
.
Set
.
elts
);
for
(
i
=
0
;
i
<
elem_count
;
i
++
)
{
if
(
i
>
0
&&
-
1
==
append_charp
(
writer
,
", "
))
{
return
-
1
;
}
elem_node
=
(
expr_ty
)
asdl_seq_GET
(
e
->
v
.
Set
.
elts
,
i
);
if
(
-
1
==
append_ast_expr
(
writer
,
elem_node
,
false
))
{
return
-
1
;
}
APPEND_STR_IF
(
i
>
0
,
", "
);
APPEND_EXPR
((
expr_ty
)
asdl_seq_GET
(
e
->
v
.
Set
.
elts
,
i
),
PR_TEST
);
}
return
append_charp
(
writer
,
"}"
);
APPEND_STR_FINISH
(
"}"
);
}
static
int
append_ast_list
(
_PyUnicodeWriter
*
writer
,
expr_ty
e
)
{
Py_ssize_t
i
,
elem_count
;
expr_ty
elem_node
;
if
(
-
1
==
append_charp
(
writer
,
"["
))
{
return
-
1
;
}
APPEND_STR
(
"["
);
elem_count
=
asdl_seq_LEN
(
e
->
v
.
List
.
elts
);
for
(
i
=
0
;
i
<
elem_count
;
i
++
)
{
if
(
i
>
0
&&
-
1
==
append_charp
(
writer
,
", "
))
{
return
-
1
;
}
elem_node
=
(
expr_ty
)
asdl_seq_GET
(
e
->
v
.
List
.
elts
,
i
);
if
(
-
1
==
append_ast_expr
(
writer
,
elem_node
,
false
))
{
return
-
1
;
}
APPEND_STR_IF
(
i
>
0
,
", "
);
APPEND_EXPR
((
expr_ty
)
asdl_seq_GET
(
e
->
v
.
List
.
elts
,
i
),
PR_TEST
);
}
return
append_charp
(
writer
,
"]"
);
APPEND_STR_FINISH
(
"]"
);
}
static
int
append_ast_tuple
(
_PyUnicodeWriter
*
writer
,
expr_ty
e
,
bool
omit_parens
)
append_ast_tuple
(
_PyUnicodeWriter
*
writer
,
expr_ty
e
,
int
level
)
{
Py_ssize_t
i
,
elem_count
;
expr_ty
elem_node
;
elem_count
=
asdl_seq_LEN
(
e
->
v
.
Tuple
.
elts
);
if
(
!
omit_parens
||
elem_count
<
2
)
{
if
(
-
1
==
append_charp
(
writer
,
"("
))
{
return
-
1
;
}
if
(
elem_count
==
0
)
{
APPEND_STR_FINISH
(
"()"
);
}
for
(
i
=
0
;
i
<
elem_count
;
i
++
)
{
if
((
i
>
0
||
elem_count
==
1
)
&&
-
1
==
append_charp
(
writer
,
", "
))
{
return
-
1
;
}
elem_node
=
(
expr_ty
)
asdl_seq_GET
(
e
->
v
.
Tuple
.
elts
,
i
);
if
(
-
1
==
append_ast_expr
(
writer
,
elem_node
,
false
))
{
return
-
1
;
}
}
APPEND_STR_IF
(
level
>
PR_TUPLE
,
"("
);
if
(
!
omit_parens
||
elem_count
<
2
)
{
return
append_charp
(
writer
,
")"
);
for
(
i
=
0
;
i
<
elem_count
;
i
++
)
{
APPEND_STR_IF
(
i
>
0
,
", "
);
APPEND_EXPR
((
expr_ty
)
asdl_seq_GET
(
e
->
v
.
Tuple
.
elts
,
i
),
PR_TEST
);
}
APPEND_STR_IF
(
elem_count
==
1
,
","
);
APPEND_STR_IF
(
level
>
PR_TUPLE
,
")"
);
return
0
;
}
...
...
@@ -448,33 +353,15 @@ append_ast_comprehension(_PyUnicodeWriter *writer, comprehension_ty gen)
{
Py_ssize_t
i
,
if_count
;
if
(
-
1
==
append_charp
(
writer
,
gen
->
is_async
?
" async for "
:
" for "
))
{
return
-
1
;
}
if
(
-
1
==
append_ast_expr
(
writer
,
gen
->
target
,
true
))
{
return
-
1
;
}
if
(
-
1
==
append_charp
(
writer
,
" in "
))
{
return
-
1
;
}
if
(
-
1
==
append_ast_expr
(
writer
,
gen
->
iter
,
false
))
{
return
-
1
;
}
APPEND_STR
(
gen
->
is_async
?
" async for "
:
" for "
);
APPEND_EXPR
(
gen
->
target
,
PR_TUPLE
);
APPEND_STR
(
" in "
);
APPEND_EXPR
(
gen
->
iter
,
PR_TEST
+
1
);
if_count
=
asdl_seq_LEN
(
gen
->
ifs
);
for
(
i
=
0
;
i
<
if_count
;
i
++
)
{
if
(
-
1
==
append_charp
(
writer
,
" if "
))
{
return
-
1
;
}
if
(
-
1
==
append_ast_expr
(
writer
,
(
expr_ty
)
asdl_seq_GET
(
gen
->
ifs
,
i
),
false
))
{
return
-
1
;
}
APPEND_STR
(
" if "
);
APPEND_EXPR
((
expr_ty
)
asdl_seq_GET
(
gen
->
ifs
,
i
),
PR_TEST
+
1
);
}
return
0
;
}
...
...
@@ -483,110 +370,62 @@ static int
append_ast_comprehensions
(
_PyUnicodeWriter
*
writer
,
asdl_seq
*
comprehensions
)
{
Py_ssize_t
i
,
gen_count
;
comprehension_ty
comp_node
;
gen_count
=
asdl_seq_LEN
(
comprehensions
);
for
(
i
=
0
;
i
<
gen_count
;
i
++
)
{
comp_node
=
(
comprehension_ty
)
asdl_seq_GET
(
comprehensions
,
i
);
if
(
-
1
==
append_ast_comprehension
(
writer
,
comp_node
))
{
return
-
1
;
}
APPEND
(
comprehension
,
(
comprehension_ty
)
asdl_seq_GET
(
comprehensions
,
i
));
}
return
0
;
}
static
int
append_ast_genexp
(
_PyUnicodeWriter
*
writer
,
expr_ty
e
,
bool
omit_parens
)
append_ast_genexp
(
_PyUnicodeWriter
*
writer
,
expr_ty
e
)
{
if
(
!
omit_parens
&&
-
1
==
append_charp
(
writer
,
"("
))
{
return
-
1
;
}
if
(
-
1
==
append_ast_expr
(
writer
,
e
->
v
.
GeneratorExp
.
elt
,
false
))
{
return
-
1
;
}
if
(
-
1
==
append_ast_comprehensions
(
writer
,
e
->
v
.
GeneratorExp
.
generators
))
{
return
-
1
;
}
return
omit_parens
?
0
:
append_charp
(
writer
,
")"
);
APPEND_STR
(
"("
);
APPEND_EXPR
(
e
->
v
.
GeneratorExp
.
elt
,
PR_TEST
);
APPEND
(
comprehensions
,
e
->
v
.
GeneratorExp
.
generators
);
APPEND_STR_FINISH
(
")"
);
}
static
int
append_ast_listcomp
(
_PyUnicodeWriter
*
writer
,
expr_ty
e
)
{
if
(
-
1
==
append_charp
(
writer
,
"["
))
{
return
-
1
;
}
if
(
-
1
==
append_ast_expr
(
writer
,
e
->
v
.
ListComp
.
elt
,
false
))
{
return
-
1
;
}
if
(
-
1
==
append_ast_comprehensions
(
writer
,
e
->
v
.
ListComp
.
generators
))
{
return
-
1
;
}
return
append_charp
(
writer
,
"]"
);
APPEND_STR
(
"["
);
APPEND_EXPR
(
e
->
v
.
ListComp
.
elt
,
PR_TEST
);
APPEND
(
comprehensions
,
e
->
v
.
ListComp
.
generators
);
APPEND_STR_FINISH
(
"]"
);
}
static
int
append_ast_setcomp
(
_PyUnicodeWriter
*
writer
,
expr_ty
e
)
{
if
(
-
1
==
append_charp
(
writer
,
"{"
))
{
return
-
1
;
}
if
(
-
1
==
append_ast_expr
(
writer
,
e
->
v
.
SetComp
.
elt
,
false
))
{
return
-
1
;
}
if
(
-
1
==
append_ast_comprehensions
(
writer
,
e
->
v
.
SetComp
.
generators
))
{
return
-
1
;
}
return
append_charp
(
writer
,
"}"
);
APPEND_STR
(
"{"
);
APPEND_EXPR
(
e
->
v
.
SetComp
.
elt
,
PR_TEST
);
APPEND
(
comprehensions
,
e
->
v
.
SetComp
.
generators
);
APPEND_STR_FINISH
(
"}"
);
}
static
int
append_ast_dictcomp
(
_PyUnicodeWriter
*
writer
,
expr_ty
e
)
{
if
(
-
1
==
append_charp
(
writer
,
"{"
))
{
return
-
1
;
}
if
(
-
1
==
append_ast_expr
(
writer
,
e
->
v
.
DictComp
.
key
,
false
))
{
return
-
1
;
}
if
(
-
1
==
append_charp
(
writer
,
": "
))
{
return
-
1
;
}
if
(
-
1
==
append_ast_expr
(
writer
,
e
->
v
.
DictComp
.
value
,
false
))
{
return
-
1
;
}
if
(
-
1
==
append_ast_comprehensions
(
writer
,
e
->
v
.
DictComp
.
generators
))
{
return
-
1
;
}
return
append_charp
(
writer
,
"}"
);
APPEND_STR
(
"{"
);
APPEND_EXPR
(
e
->
v
.
DictComp
.
key
,
PR_TEST
);
APPEND_STR
(
": "
);
APPEND_EXPR
(
e
->
v
.
DictComp
.
value
,
PR_TEST
);
APPEND
(
comprehensions
,
e
->
v
.
DictComp
.
generators
);
APPEND_STR_FINISH
(
"}"
);
}
static
int
append_ast_compare
(
_PyUnicodeWriter
*
writer
,
expr_ty
e
,
bool
omit_parens
)
append_ast_compare
(
_PyUnicodeWriter
*
writer
,
expr_ty
e
,
int
level
)
{
const
char
*
op
;
Py_ssize_t
i
,
comparator_count
;
asdl_seq
*
comparators
;
asdl_int_seq
*
ops
;
if
(
!
omit_parens
&&
-
1
==
append_charp
(
writer
,
"("
))
{
return
-
1
;
}
APPEND_STR_IF
(
level
>
PR_CMP
,
"("
);
comparators
=
e
->
v
.
Compare
.
comparators
;
ops
=
e
->
v
.
Compare
.
ops
;
...
...
@@ -594,9 +433,7 @@ append_ast_compare(_PyUnicodeWriter *writer, expr_ty e, bool omit_parens)
assert
(
comparator_count
>
0
);
assert
(
comparator_count
==
asdl_seq_LEN
(
ops
));
if
(
-
1
==
append_ast_expr
(
writer
,
e
->
v
.
Compare
.
left
,
false
))
{
return
-
1
;
}
APPEND_EXPR
(
e
->
v
.
Compare
.
left
,
PR_CMP
+
1
);
for
(
i
=
0
;
i
<
comparator_count
;
i
++
)
{
switch
((
cmpop_ty
)
asdl_seq_GET
(
ops
,
i
))
{
...
...
@@ -636,39 +473,30 @@ append_ast_compare(_PyUnicodeWriter *writer, expr_ty e, bool omit_parens)
return
-
1
;
}
if
(
-
1
==
append_charp
(
writer
,
op
))
{
return
-
1
;
}
if
(
-
1
==
append_ast_expr
(
writer
,
(
expr_ty
)
asdl_seq_GET
(
comparators
,
i
),
false
))
{
return
-
1
;
}
APPEND_STR
(
op
);
APPEND_EXPR
((
expr_ty
)
asdl_seq_GET
(
comparators
,
i
),
PR_CMP
+
1
);
}
return
omit_parens
?
0
:
append_charp
(
writer
,
")"
);
APPEND_STR_IF
(
level
>
PR_CMP
,
")"
);
return
0
;
}
static
int
append_ast_keyword
(
_PyUnicodeWriter
*
writer
,
keyword_ty
kw
)
{
if
(
kw
->
arg
==
NULL
)
{
if
(
-
1
==
append_charp
(
writer
,
"**"
))
{
return
-
1
;
}
APPEND_STR
(
"**"
);
}
else
{
if
(
-
1
==
_PyUnicodeWriter_WriteStr
(
writer
,
kw
->
arg
))
{
return
-
1
;
}
if
(
-
1
==
append_charp
(
writer
,
"="
))
{
return
-
1
;
}
APPEND_STR
(
"="
);
}
return
append_ast_expr
(
writer
,
kw
->
value
,
false
);
APPEND_EXPR
(
kw
->
value
,
PR_TEST
);
return
0
;
}
static
int
...
...
@@ -677,48 +505,33 @@ append_ast_call(_PyUnicodeWriter *writer, expr_ty e)
bool
first
;
Py_ssize_t
i
,
arg_count
,
kw_count
;
expr_ty
expr
;
keyword_ty
kw
;
if
(
-
1
==
append_ast_expr
(
writer
,
e
->
v
.
Call
.
func
,
false
))
{
return
-
1
;
}
APPEND_EXPR
(
e
->
v
.
Call
.
func
,
PR_ATOM
);
if
(
-
1
==
append_charp
(
writer
,
"("
))
{
return
-
1
;
arg_count
=
asdl_seq_LEN
(
e
->
v
.
Call
.
args
);
kw_count
=
asdl_seq_LEN
(
e
->
v
.
Call
.
keywords
);
if
(
arg_count
==
1
&&
kw_count
==
0
)
{
expr
=
(
expr_ty
)
asdl_seq_GET
(
e
->
v
.
Call
.
args
,
0
);
if
(
expr
->
kind
==
GeneratorExp_kind
)
{
/* Special case: a single generator expression. */
return
append_ast_genexp
(
writer
,
expr
);
}
}
APPEND_STR
(
"("
);
first
=
true
;
arg_count
=
asdl_seq_LEN
(
e
->
v
.
Call
.
args
);
for
(
i
=
0
;
i
<
arg_count
;
i
++
)
{
if
(
first
)
{
first
=
false
;
}
else
if
(
-
1
==
append_charp
(
writer
,
", "
))
{
return
-
1
;
}
expr
=
(
expr_ty
)
asdl_seq_GET
(
e
->
v
.
Call
.
args
,
i
);
if
(
-
1
==
append_ast_expr
(
writer
,
expr
,
false
))
{
return
-
1
;
}
APPEND_STR_IF_NOT_FIRST
(
", "
);
APPEND_EXPR
((
expr_ty
)
asdl_seq_GET
(
e
->
v
.
Call
.
args
,
i
),
PR_TEST
);
}
kw_count
=
asdl_seq_LEN
(
e
->
v
.
Call
.
keywords
);
for
(
i
=
0
;
i
<
kw_count
;
i
++
)
{
if
(
first
)
{
first
=
false
;
}
else
if
(
-
1
==
append_charp
(
writer
,
", "
))
{
return
-
1
;
}
kw
=
(
keyword_ty
)
asdl_seq_GET
(
e
->
v
.
Call
.
keywords
,
i
);
if
(
-
1
==
append_ast_keyword
(
writer
,
kw
))
{
return
-
1
;
}
APPEND_STR_IF_NOT_FIRST
(
", "
);
APPEND
(
keyword
,
(
keyword_ty
)
asdl_seq_GET
(
e
->
v
.
Call
.
keywords
,
i
));
}
return
append_charp
(
writer
,
")"
);
APPEND_STR_FINISH
(
")"
);
}
static
PyObject
*
...
...
@@ -778,9 +591,8 @@ build_fstring_body(asdl_seq *values, bool is_format_spec)
body_writer
.
min_length
=
256
;
body_writer
.
overallocate
=
1
;
value_count
=
asdl_seq_LEN
(
values
)
-
1
;
assert
(
value_count
>=
0
);
for
(
i
=
0
;
i
<=
value_count
;
++
i
)
{
value_count
=
asdl_seq_LEN
(
values
);
for
(
i
=
0
;
i
<
value_count
;
++
i
)
{
if
(
-
1
==
append_fstring_element
(
&
body_writer
,
(
expr_ty
)
asdl_seq_GET
(
values
,
i
),
is_format_spec
...
...
@@ -819,9 +631,11 @@ append_joinedstr(_PyUnicodeWriter *writer, expr_ty e, bool is_format_spec)
static
int
append_formattedvalue
(
_PyUnicodeWriter
*
writer
,
expr_ty
e
,
bool
is_format_spec
)
{
char
*
conversion
;
char
*
outer_brace
=
"{"
;
PyObject
*
temp_fv_str
=
expr_as_unicode
(
e
->
v
.
FormattedValue
.
value
,
true
);
const
char
*
conversion
;
const
char
*
outer_brace
=
"{"
;
/* Grammar allows PR_TUPLE, but use >PR_TEST for adding parenthesis
around a lambda with ':' */
PyObject
*
temp_fv_str
=
expr_as_unicode
(
e
->
v
.
FormattedValue
.
value
,
PR_TEST
+
1
);
if
(
!
temp_fv_str
)
{
return
-
1
;
}
...
...
@@ -842,13 +656,13 @@ append_formattedvalue(_PyUnicodeWriter *writer, expr_ty e, bool is_format_spec)
if
(
e
->
v
.
FormattedValue
.
conversion
>
0
)
{
switch
(
e
->
v
.
FormattedValue
.
conversion
)
{
case
97
:
case
'a'
:
conversion
=
"!a"
;
break
;
case
114
:
case
'r'
:
conversion
=
"!r"
;
break
;
case
115
:
case
's'
:
conversion
=
"!s"
;
break
;
default:
...
...
@@ -856,9 +670,7 @@ append_formattedvalue(_PyUnicodeWriter *writer, expr_ty e, bool is_format_spec)
"unknown f-value conversion kind"
);
return
-
1
;
}
if
(
-
1
==
append_charp
(
writer
,
conversion
))
{
return
-
1
;
}
APPEND_STR
(
conversion
);
}
if
(
e
->
v
.
FormattedValue
.
format_spec
)
{
if
(
-
1
==
_PyUnicodeWriter_WriteASCIIString
(
writer
,
":"
,
1
)
||
...
...
@@ -870,16 +682,15 @@ append_formattedvalue(_PyUnicodeWriter *writer, expr_ty e, bool is_format_spec)
return
-
1
;
}
}
return
append_charp
(
writer
,
"}"
);
APPEND_STR_FINISH
(
"}"
);
}
static
int
append_ast_attribute
(
_PyUnicodeWriter
*
writer
,
expr_ty
e
)
{
const
char
*
period
;
if
(
-
1
==
append_ast_expr
(
writer
,
e
->
v
.
Attribute
.
value
,
false
))
{
return
-
1
;
}
APPEND_EXPR
(
e
->
v
.
Attribute
.
value
,
PR_ATOM
);
/* Special case: integers require a space for attribute access to be
unambiguous. Floats and complex numbers don't but work with it, too. */
...
...
@@ -891,9 +702,7 @@ append_ast_attribute(_PyUnicodeWriter *writer, expr_ty e)
else
{
period
=
"."
;
}
if
(
-
1
==
append_charp
(
writer
,
period
))
{
return
-
1
;
}
APPEND_STR
(
period
);
return
_PyUnicodeWriter_WriteStr
(
writer
,
e
->
v
.
Attribute
.
attr
);
}
...
...
@@ -902,28 +711,18 @@ static int
append_ast_simple_slice
(
_PyUnicodeWriter
*
writer
,
slice_ty
slice
)
{
if
(
slice
->
v
.
Slice
.
lower
)
{
if
(
-
1
==
append_ast_expr
(
writer
,
slice
->
v
.
Slice
.
lower
,
false
))
{
return
-
1
;
}
APPEND_EXPR
(
slice
->
v
.
Slice
.
lower
,
PR_TEST
);
}
if
(
-
1
==
append_charp
(
writer
,
":"
))
{
return
-
1
;
}
APPEND_STR
(
":"
);
if
(
slice
->
v
.
Slice
.
upper
)
{
if
(
-
1
==
append_ast_expr
(
writer
,
slice
->
v
.
Slice
.
upper
,
false
))
{
return
-
1
;
}
APPEND_EXPR
(
slice
->
v
.
Slice
.
upper
,
PR_TEST
);
}
if
(
slice
->
v
.
Slice
.
step
)
{
if
(
-
1
==
append_charp
(
writer
,
":"
))
{
return
-
1
;
}
if
(
-
1
==
append_ast_expr
(
writer
,
slice
->
v
.
Slice
.
step
,
false
))
{
return
-
1
;
}
APPEND_STR
(
":"
);
APPEND_EXPR
(
slice
->
v
.
Slice
.
step
,
PR_TEST
);
}
return
0
;
}
...
...
@@ -934,28 +733,23 @@ append_ast_ext_slice(_PyUnicodeWriter *writer, slice_ty slice)
Py_ssize_t
i
,
dims_count
;
dims_count
=
asdl_seq_LEN
(
slice
->
v
.
ExtSlice
.
dims
);
for
(
i
=
0
;
i
<
dims_count
;
i
++
)
{
if
(
i
>
0
&&
-
1
==
append_charp
(
writer
,
", "
))
{
return
-
1
;
}
if
(
-
1
==
append_ast_expr
(
writer
,
(
expr_ty
)
asdl_seq_GET
(
slice
->
v
.
ExtSlice
.
dims
,
i
),
false
))
{
return
-
1
;
}
APPEND_STR_IF
(
i
>
0
,
", "
);
APPEND
(
slice
,
(
slice_ty
)
asdl_seq_GET
(
slice
->
v
.
ExtSlice
.
dims
,
i
));
}
return
0
;
}
static
int
append_ast_slice
(
_PyUnicodeWriter
*
writer
,
slice_ty
slice
,
bool
omit_parens
)
append_ast_slice
(
_PyUnicodeWriter
*
writer
,
slice_ty
slice
)
{
switch
(
slice
->
kind
)
{
switch
(
slice
->
kind
)
{
case
Slice_kind
:
return
append_ast_simple_slice
(
writer
,
slice
);
case
ExtSlice_kind
:
return
append_ast_ext_slice
(
writer
,
slice
);
case
Index_kind
:
return
append_ast_expr
(
writer
,
slice
->
v
.
Index
.
value
,
omit_parens
);
APPEND_EXPR
(
slice
->
v
.
Index
.
value
,
PR_TUPLE
);
return
0
;
default:
PyErr_SetString
(
PyExc_SystemError
,
"unexpected slice kind"
);
...
...
@@ -966,109 +760,70 @@ append_ast_slice(_PyUnicodeWriter *writer, slice_ty slice, bool omit_parens)
static
int
append_ast_subscript
(
_PyUnicodeWriter
*
writer
,
expr_ty
e
)
{
if
(
-
1
==
append_ast_expr
(
writer
,
e
->
v
.
Subscript
.
value
,
false
))
{
return
-
1
;
}
if
(
-
1
==
append_charp
(
writer
,
"["
))
{
return
-
1
;
}
if
(
-
1
==
append_ast_slice
(
writer
,
e
->
v
.
Subscript
.
slice
,
true
))
{
return
-
1
;
}
return
append_charp
(
writer
,
"]"
);
APPEND_EXPR
(
e
->
v
.
Subscript
.
value
,
PR_ATOM
);
APPEND_STR
(
"["
);
APPEND
(
slice
,
e
->
v
.
Subscript
.
slice
);
APPEND_STR_FINISH
(
"]"
);
}
static
int
append_ast_starred
(
_PyUnicodeWriter
*
writer
,
expr_ty
e
)
{
if
(
-
1
==
append_charp
(
writer
,
"*"
))
{
return
-
1
;
}
return
append_ast_expr
(
writer
,
e
->
v
.
Starred
.
value
,
false
);
APPEND_STR
(
"*"
);
APPEND_EXPR
(
e
->
v
.
Starred
.
value
,
PR_EXPR
);
return
0
;
}
static
int
append_ast_yield
(
_PyUnicodeWriter
*
writer
,
expr_ty
e
,
bool
omit_parens
)
append_ast_yield
(
_PyUnicodeWriter
*
writer
,
expr_ty
e
)
{
if
(
!
omit_parens
&&
-
1
==
append_charp
(
writer
,
"("
))
{
return
-
1
;
}
if
(
-
1
==
append_charp
(
writer
,
e
->
v
.
Yield
.
value
?
"yield "
:
"yield"
))
{
return
-
1
;
if
(
!
e
->
v
.
Yield
.
value
)
{
APPEND_STR_FINISH
(
"(yield)"
);
}
if
(
e
->
v
.
Yield
.
value
)
{
if
(
-
1
==
append_ast_expr
(
writer
,
e
->
v
.
Yield
.
value
,
false
))
{
return
-
1
;
}
}
return
omit_parens
?
0
:
append_charp
(
writer
,
")"
);
APPEND_STR
(
"(yield "
);
APPEND_EXPR
(
e
->
v
.
Yield
.
value
,
PR_TEST
);
APPEND_STR_FINISH
(
")"
);
}
static
int
append_ast_yield_from
(
_PyUnicodeWriter
*
writer
,
expr_ty
e
,
bool
omit_parens
)
append_ast_yield_from
(
_PyUnicodeWriter
*
writer
,
expr_ty
e
)
{
if
(
!
omit_parens
&&
-
1
==
append_charp
(
writer
,
"("
))
{
return
-
1
;
}
if
(
-
1
==
append_charp
(
writer
,
e
->
v
.
YieldFrom
.
value
?
"yield from "
:
"yield from"
))
{
return
-
1
;
}
if
(
e
->
v
.
YieldFrom
.
value
)
{
if
(
-
1
==
append_ast_expr
(
writer
,
e
->
v
.
YieldFrom
.
value
,
false
))
{
return
-
1
;
}
}
return
omit_parens
?
0
:
append_charp
(
writer
,
")"
);
APPEND_STR
(
"(yield from "
);
APPEND_EXPR
(
e
->
v
.
YieldFrom
.
value
,
PR_TEST
);
APPEND_STR_FINISH
(
")"
);
}
static
int
append_ast_await
(
_PyUnicodeWriter
*
writer
,
expr_ty
e
,
bool
omit_parens
)
append_ast_await
(
_PyUnicodeWriter
*
writer
,
expr_ty
e
,
int
level
)
{
if
(
!
omit_parens
&&
-
1
==
append_charp
(
writer
,
"("
))
{
return
-
1
;
}
if
(
-
1
==
append_charp
(
writer
,
e
->
v
.
Await
.
value
?
"await "
:
"await"
))
{
return
-
1
;
}
if
(
e
->
v
.
Await
.
value
)
{
if
(
-
1
==
append_ast_expr
(
writer
,
e
->
v
.
Await
.
value
,
false
))
{
return
-
1
;
}
}
return
omit_parens
?
0
:
append_charp
(
writer
,
")"
);
APPEND_STR_IF
(
level
>
PR_AWAIT
,
"("
);
APPEND_STR
(
"await "
);
APPEND_EXPR
(
e
->
v
.
Await
.
value
,
PR_ATOM
);
APPEND_STR_IF
(
level
>
PR_AWAIT
,
")"
);
return
0
;
}
static
int
append_ast_expr
(
_PyUnicodeWriter
*
writer
,
expr_ty
e
,
bool
omit_parens
)
append_ast_expr
(
_PyUnicodeWriter
*
writer
,
expr_ty
e
,
int
level
)
{
switch
(
e
->
kind
)
{
case
BoolOp_kind
:
return
append_ast_boolop
(
writer
,
e
,
omit_parens
);
return
append_ast_boolop
(
writer
,
e
,
level
);
case
BinOp_kind
:
return
append_ast_binop
(
writer
,
e
,
omit_parens
);
return
append_ast_binop
(
writer
,
e
,
level
);
case
UnaryOp_kind
:
return
append_ast_unaryop
(
writer
,
e
,
omit_parens
);
return
append_ast_unaryop
(
writer
,
e
,
level
);
case
Lambda_kind
:
return
append_ast_lambda
(
writer
,
e
,
omit_parens
);
return
append_ast_lambda
(
writer
,
e
,
level
);
case
IfExp_kind
:
return
append_ast_ifexp
(
writer
,
e
,
omit_parens
);
return
append_ast_ifexp
(
writer
,
e
,
level
);
case
Dict_kind
:
return
append_ast_dict
(
writer
,
e
);
case
Set_kind
:
return
append_ast_set
(
writer
,
e
);
case
GeneratorExp_kind
:
return
append_ast_genexp
(
writer
,
e
,
omit_parens
);
return
append_ast_genexp
(
writer
,
e
);
case
ListComp_kind
:
return
append_ast_listcomp
(
writer
,
e
);
case
SetComp_kind
:
...
...
@@ -1076,13 +831,13 @@ append_ast_expr(_PyUnicodeWriter *writer, expr_ty e, bool omit_parens)
case
DictComp_kind
:
return
append_ast_dictcomp
(
writer
,
e
);
case
Yield_kind
:
return
append_ast_yield
(
writer
,
e
,
omit_parens
);
return
append_ast_yield
(
writer
,
e
);
case
YieldFrom_kind
:
return
append_ast_yield_from
(
writer
,
e
,
omit_parens
);
return
append_ast_yield_from
(
writer
,
e
);
case
Await_kind
:
return
append_ast_await
(
writer
,
e
,
omit_parens
);
return
append_ast_await
(
writer
,
e
,
level
);
case
Compare_kind
:
return
append_ast_compare
(
writer
,
e
,
omit_parens
);
return
append_ast_compare
(
writer
,
e
,
level
);
case
Call_kind
:
return
append_ast_call
(
writer
,
e
);
case
Constant_kind
:
...
...
@@ -1098,7 +853,7 @@ append_ast_expr(_PyUnicodeWriter *writer, expr_ty e, bool omit_parens)
case
Bytes_kind
:
return
append_repr
(
writer
,
e
->
v
.
Bytes
.
s
);
case
Ellipsis_kind
:
return
append_charp
(
writer
,
"..."
);
APPEND_STR_FINISH
(
"..."
);
case
NameConstant_kind
:
return
append_repr
(
writer
,
e
->
v
.
NameConstant
.
value
);
/* The following exprs can be assignment targets. */
...
...
@@ -1110,11 +865,10 @@ append_ast_expr(_PyUnicodeWriter *writer, expr_ty e, bool omit_parens)
return
append_ast_starred
(
writer
,
e
);
case
Name_kind
:
return
_PyUnicodeWriter_WriteStr
(
writer
,
e
->
v
.
Name
.
id
);
/* child nodes of List and Tuple will have expr_context set */
case
List_kind
:
return
append_ast_list
(
writer
,
e
);
case
Tuple_kind
:
return
append_ast_tuple
(
writer
,
e
,
omit_parens
);
return
append_ast_tuple
(
writer
,
e
,
level
);
default:
PyErr_SetString
(
PyExc_SystemError
,
"unknown expression kind"
);
...
...
@@ -1145,14 +899,14 @@ maybe_init_static_strings(void)
}
static
PyObject
*
expr_as_unicode
(
expr_ty
e
,
bool
omit_parens
)
expr_as_unicode
(
expr_ty
e
,
int
level
)
{
_PyUnicodeWriter
writer
;
_PyUnicodeWriter_Init
(
&
writer
);
writer
.
min_length
=
256
;
writer
.
overallocate
=
1
;
if
(
-
1
==
maybe_init_static_strings
()
||
-
1
==
append_ast_expr
(
&
writer
,
e
,
omit_parens
))
-
1
==
append_ast_expr
(
&
writer
,
e
,
level
))
{
_PyUnicodeWriter_Dealloc
(
&
writer
);
return
NULL
;
...
...
@@ -1161,7 +915,7 @@ expr_as_unicode(expr_ty e, bool omit_parens)
}
PyObject
*
_PyAST_ExprAsUnicode
(
expr_ty
e
,
bool
omit_parens
)
_PyAST_ExprAsUnicode
(
expr_ty
e
)
{
return
expr_as_unicode
(
e
,
omit_parens
);
return
expr_as_unicode
(
e
,
PR_TEST
);
}
Python/compile.c
View file @
64fddc42
...
...
@@ -1822,7 +1822,7 @@ error:
static
int
compiler_visit_annexpr
(
struct
compiler
*
c
,
expr_ty
annotation
)
{
ADDOP_LOAD_CONST_NEW
(
c
,
_PyAST_ExprAsUnicode
(
annotation
,
1
));
ADDOP_LOAD_CONST_NEW
(
c
,
_PyAST_ExprAsUnicode
(
annotation
));
return
1
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment