Commit 64fddc42 authored by Serhiy Storchaka's avatar Serhiy Storchaka Committed by Łukasz Langa

bpo-33475: Fix and improve converting annotations to strings. (GH-6774)

parent d852142c
......@@ -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 */
......
......@@ -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__":
......
Fixed miscellaneous bugs in converting annotations to strings and optimized
parentheses in the string representation.
......@@ -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);
}
......@@ -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;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment