From 1371e8b9345d3500bc536150e6bfd684dc6c9c9d Mon Sep 17 00:00:00 2001 From: "Eric V. Smith" Date: Sat, 19 Sep 2015 14:51:32 -0400 Subject: Issue #24965: Implement PEP 498 "Literal String Interpolation". Documentation is still needed, I'll open an issue for that. --- Python/compile.c | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 116 insertions(+), 1 deletion(-) (limited to 'Python/compile.c') diff --git a/Python/compile.c b/Python/compile.c index a6884ec211..3a49ecec28 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -731,6 +731,7 @@ compiler_set_qualname(struct compiler *c) return 1; } + /* Allocate a new block and return a pointer to it. Returns NULL on error. */ @@ -3209,6 +3210,117 @@ compiler_call(struct compiler *c, expr_ty e) e->v.Call.keywords); } +static int +compiler_joined_str(struct compiler *c, expr_ty e) +{ + /* Concatenate parts of a string using ''.join(parts). There are + probably better ways of doing this. + + This is used for constructs like "'x=' f'{42}'", which have to + be evaluated at compile time. */ + + static PyObject *empty_string; + static PyObject *join_string; + + if (!empty_string) { + empty_string = PyUnicode_FromString(""); + if (!empty_string) + return 0; + } + if (!join_string) { + join_string = PyUnicode_FromString("join"); + if (!join_string) + return 0; + } + + ADDOP_O(c, LOAD_CONST, empty_string, consts); + ADDOP_NAME(c, LOAD_ATTR, join_string, names); + VISIT_SEQ(c, expr, e->v.JoinedStr.values); + ADDOP_I(c, BUILD_LIST, asdl_seq_LEN(e->v.JoinedStr.values)); + ADDOP_I(c, CALL_FUNCTION, 1); + return 1; +} + +/* Note that this code uses the builtin functions format(), str(), + repr(), and ascii(). You can break this code, or make it do odd + things, by redefining those functions. */ +static int +compiler_formatted_value(struct compiler *c, expr_ty e) +{ + PyObject *conversion_name = NULL; + + static PyObject *format_string; + static PyObject *str_string; + static PyObject *repr_string; + static PyObject *ascii_string; + + if (!format_string) { + format_string = PyUnicode_InternFromString("format"); + if (!format_string) + return 0; + } + + if (!str_string) { + str_string = PyUnicode_InternFromString("str"); + if (!str_string) + return 0; + } + + if (!repr_string) { + repr_string = PyUnicode_InternFromString("repr"); + if (!repr_string) + return 0; + } + if (!ascii_string) { + ascii_string = PyUnicode_InternFromString("ascii"); + if (!ascii_string) + return 0; + } + + ADDOP_NAME(c, LOAD_GLOBAL, format_string, names); + + /* If needed, convert via str, repr, or ascii. */ + if (e->v.FormattedValue.conversion != -1) { + switch (e->v.FormattedValue.conversion) { + case 's': + conversion_name = str_string; + break; + case 'r': + conversion_name = repr_string; + break; + case 'a': + conversion_name = ascii_string; + break; + default: + PyErr_SetString(PyExc_SystemError, + "Unrecognized conversion character"); + return 0; + } + ADDOP_NAME(c, LOAD_GLOBAL, conversion_name, names); + } + + /* Evaluate the value. */ + VISIT(c, expr, e->v.FormattedValue.value); + + /* If needed, convert via str, repr, or ascii. */ + if (conversion_name) { + /* Call the function we previously pushed. */ + ADDOP_I(c, CALL_FUNCTION, 1); + } + + /* If we have a format spec, use format(value, format_spec). Otherwise, + use the single argument form. */ + if (e->v.FormattedValue.format_spec) { + VISIT(c, expr, e->v.FormattedValue.format_spec); + ADDOP_I(c, CALL_FUNCTION, 2); + } else { + /* No format spec specified, call format(value). */ + ADDOP_I(c, CALL_FUNCTION, 1); + } + + return 1; +} + /* shared code between compiler_call and compiler_class */ static int compiler_call_helper(struct compiler *c, @@ -3878,6 +3990,10 @@ compiler_visit_expr(struct compiler *c, expr_ty e) case Str_kind: ADDOP_O(c, LOAD_CONST, e->v.Str.s, consts); break; + case JoinedStr_kind: + return compiler_joined_str(c, e); + case FormattedValue_kind: + return compiler_formatted_value(c, e); case Bytes_kind: ADDOP_O(c, LOAD_CONST, e->v.Bytes.s, consts); break; @@ -4784,4 +4900,3 @@ PyAST_Compile(mod_ty mod, const char *filename, PyCompilerFlags *flags, { return PyAST_CompileEx(mod, filename, flags, -1, arena); } - -- cgit v1.2.1 From 008499d3f1761db65815faebb31bf95ab7ef9cd4 Mon Sep 17 00:00:00 2001 From: "Eric V. Smith" Date: Tue, 3 Nov 2015 12:45:05 -0500 Subject: Issue 25483: Add an opcode to make f-string formatting more robust. --- Python/compile.c | 98 +++++++++++++++++++------------------------------------- 1 file changed, 33 insertions(+), 65 deletions(-) (limited to 'Python/compile.c') diff --git a/Python/compile.c b/Python/compile.c index 5b53de3ee7..030afedd29 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -1067,6 +1067,10 @@ PyCompile_OpcodeStackEffect(int opcode, int oparg) return 1; case GET_YIELD_FROM_ITER: return 0; + case FORMAT_VALUE: + /* If there's a fmt_spec on the stack, we go from 2->1, + else 1->1. */ + return (oparg & FVS_MASK) == FVS_HAVE_SPEC ? -1 : 0; default: return PY_INVALID_STACK_EFFECT; } @@ -3241,83 +3245,47 @@ compiler_joined_str(struct compiler *c, expr_ty e) return 1; } -/* Note that this code uses the builtin functions format(), str(), - repr(), and ascii(). You can break this code, or make it do odd - things, by redefining those functions. */ +/* Used to implement f-strings. Format a single value. */ static int compiler_formatted_value(struct compiler *c, expr_ty e) { - PyObject *conversion_name = NULL; - - static PyObject *format_string; - static PyObject *str_string; - static PyObject *repr_string; - static PyObject *ascii_string; - - if (!format_string) { - format_string = PyUnicode_InternFromString("format"); - if (!format_string) - return 0; - } - - if (!str_string) { - str_string = PyUnicode_InternFromString("str"); - if (!str_string) - return 0; - } - - if (!repr_string) { - repr_string = PyUnicode_InternFromString("repr"); - if (!repr_string) - return 0; - } - if (!ascii_string) { - ascii_string = PyUnicode_InternFromString("ascii"); - if (!ascii_string) - return 0; - } + /* Our oparg encodes 2 pieces of information: the conversion + character, and whether or not a format_spec was provided. + + Convert the conversion char to 2 bits: + None: 000 0x0 FVC_NONE + !s : 001 0x1 FVC_STR + !r : 010 0x2 FVC_REPR + !a : 011 0x3 FVC_ASCII + + next bit is whether or not we have a format spec: + yes : 100 0x4 + no : 000 0x0 + */ - ADDOP_NAME(c, LOAD_GLOBAL, format_string, names); + int oparg; - /* If needed, convert via str, repr, or ascii. */ - if (e->v.FormattedValue.conversion != -1) { - switch (e->v.FormattedValue.conversion) { - case 's': - conversion_name = str_string; - break; - case 'r': - conversion_name = repr_string; - break; - case 'a': - conversion_name = ascii_string; - break; - default: - PyErr_SetString(PyExc_SystemError, - "Unrecognized conversion character"); - return 0; - } - ADDOP_NAME(c, LOAD_GLOBAL, conversion_name, names); - } - - /* Evaluate the value. */ + /* Evaluate the expression to be formatted. */ VISIT(c, expr, e->v.FormattedValue.value); - /* If needed, convert via str, repr, or ascii. */ - if (conversion_name) { - /* Call the function we previously pushed. */ - ADDOP_I(c, CALL_FUNCTION, 1); + switch (e->v.FormattedValue.conversion) { + case 's': oparg = FVC_STR; break; + case 'r': oparg = FVC_REPR; break; + case 'a': oparg = FVC_ASCII; break; + case -1: oparg = FVC_NONE; break; + default: + PyErr_SetString(PyExc_SystemError, + "Unrecognized conversion character"); + return 0; } - - /* If we have a format spec, use format(value, format_spec). Otherwise, - use the single argument form. */ if (e->v.FormattedValue.format_spec) { + /* Evaluate the format spec, and update our opcode arg. */ VISIT(c, expr, e->v.FormattedValue.format_spec); - ADDOP_I(c, CALL_FUNCTION, 2); - } else { - /* No format spec specified, call format(value). */ - ADDOP_I(c, CALL_FUNCTION, 1); + oparg |= FVS_HAVE_SPEC; } + /* And push our opcode and oparg */ + ADDOP_I(c, FORMAT_VALUE, oparg); return 1; } -- cgit v1.2.1 From fd429314d44df33056e2b10999b9d383a1967ee2 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 20 Jan 2016 12:16:21 +0100 Subject: co_lnotab supports negative line number delta Issue #26107: The format of the co_lnotab attribute of code objects changes to support negative line number delta. Changes: * assemble_lnotab(): if line number delta is less than -128 or greater than 127, emit multiple (offset_delta, lineno_delta) in co_lnotab * update functions decoding co_lnotab to use signed 8-bit integers - dis.findlinestarts() - PyCode_Addr2Line() - _PyCode_CheckLineNumber() - frame_setlineno() * update lnotab_notes.txt * increase importlib MAGIC_NUMBER to 3361 * document the change in What's New in Python 3.6 * cleanup also PyCode_Optimize() to use better variable names --- Python/compile.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) (limited to 'Python/compile.c') diff --git a/Python/compile.c b/Python/compile.c index 0f619c4535..f362ac6bda 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -4452,7 +4452,6 @@ assemble_lnotab(struct assembler *a, struct instr *i) d_lineno = i->i_lineno - a->a_lineno; assert(d_bytecode >= 0); - assert(d_lineno >= 0); if(d_bytecode == 0 && d_lineno == 0) return 1; @@ -4482,9 +4481,21 @@ assemble_lnotab(struct assembler *a, struct instr *i) d_bytecode -= ncodes * 255; a->a_lnotab_off += ncodes * 2; } - assert(d_bytecode <= 255); - if (d_lineno > 255) { - int j, nbytes, ncodes = d_lineno / 255; + assert(0 <= d_bytecode && d_bytecode <= 255); + + if (d_lineno < -128 || 127 < d_lineno) { + int j, nbytes, ncodes, k; + if (d_lineno < 0) { + k = -128; + /* use division on positive numbers */ + ncodes = (-d_lineno) / 128; + } + else { + k = 127; + ncodes = d_lineno / 127; + } + d_lineno -= ncodes * k; + assert(ncodes >= 1); nbytes = a->a_lnotab_off + 2 * ncodes; len = PyBytes_GET_SIZE(a->a_lnotab); if (nbytes >= len) { @@ -4502,15 +4513,15 @@ assemble_lnotab(struct assembler *a, struct instr *i) lnotab = (unsigned char *) PyBytes_AS_STRING(a->a_lnotab) + a->a_lnotab_off; *lnotab++ = d_bytecode; - *lnotab++ = 255; + *lnotab++ = k; d_bytecode = 0; for (j = 1; j < ncodes; j++) { *lnotab++ = 0; - *lnotab++ = 255; + *lnotab++ = k; } - d_lineno -= ncodes * 255; a->a_lnotab_off += ncodes * 2; } + assert(-128 <= d_lineno && d_lineno <= 127); len = PyBytes_GET_SIZE(a->a_lnotab); if (a->a_lnotab_off + 2 >= len) { -- cgit v1.2.1 From 402b06649e29d500412af7a1ffe52ea762b31efd Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 22 Jan 2016 12:33:12 +0100 Subject: code_richcompare() now uses the constants types Issue #25843: When compiling code, don't merge constants if they are equal but have a different types. For example, "f1, f2 = lambda: 1, lambda: 1.0" is now correctly compiled to two different functions: f1() returns 1 (int) and f2() returns 1.0 (int), even if 1 and 1.0 are equal. Add a new _PyCode_ConstantKey() private function. --- Python/compile.c | 58 ++++++++++---------------------------------------------- 1 file changed, 10 insertions(+), 48 deletions(-) (limited to 'Python/compile.c') diff --git a/Python/compile.c b/Python/compile.c index f362ac6bda..a710e82693 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -393,7 +393,7 @@ list2dict(PyObject *list) return NULL; } k = PyList_GET_ITEM(list, i); - k = PyTuple_Pack(2, k, k->ob_type); + k = _PyCode_ConstantKey(k); if (k == NULL || PyDict_SetItem(dict, k, v) < 0) { Py_XDECREF(k); Py_DECREF(v); @@ -456,7 +456,7 @@ dictbytype(PyObject *src, int scope_type, int flag, Py_ssize_t offset) return NULL; } i++; - tuple = PyTuple_Pack(2, k, k->ob_type); + tuple = _PyCode_ConstantKey(k); if (!tuple || PyDict_SetItem(dest, tuple, item) < 0) { Py_DECREF(sorted_keys); Py_DECREF(item); @@ -559,7 +559,7 @@ compiler_enter_scope(struct compiler *c, identifier name, compiler_unit_free(u); return 0; } - tuple = PyTuple_Pack(2, name, Py_TYPE(name)); + tuple = _PyCode_ConstantKey(name); if (!tuple) { compiler_unit_free(u); return 0; @@ -1105,47 +1105,8 @@ compiler_add_o(struct compiler *c, PyObject *dict, PyObject *o) { PyObject *t, *v; Py_ssize_t arg; - double d; - - /* necessary to make sure types aren't coerced (e.g., float and complex) */ - /* _and_ to distinguish 0.0 from -0.0 e.g. on IEEE platforms */ - if (PyFloat_Check(o)) { - d = PyFloat_AS_DOUBLE(o); - /* all we need is to make the tuple different in either the 0.0 - * or -0.0 case from all others, just to avoid the "coercion". - */ - if (d == 0.0 && copysign(1.0, d) < 0.0) - t = PyTuple_Pack(3, o, o->ob_type, Py_None); - else - t = PyTuple_Pack(2, o, o->ob_type); - } - else if (PyComplex_Check(o)) { - Py_complex z; - int real_negzero, imag_negzero; - /* For the complex case we must make complex(x, 0.) - different from complex(x, -0.) and complex(0., y) - different from complex(-0., y), for any x and y. - All four complex zeros must be distinguished.*/ - z = PyComplex_AsCComplex(o); - real_negzero = z.real == 0.0 && copysign(1.0, z.real) < 0.0; - imag_negzero = z.imag == 0.0 && copysign(1.0, z.imag) < 0.0; - if (real_negzero && imag_negzero) { - t = PyTuple_Pack(5, o, o->ob_type, - Py_None, Py_None, Py_None); - } - else if (imag_negzero) { - t = PyTuple_Pack(4, o, o->ob_type, Py_None, Py_None); - } - else if (real_negzero) { - t = PyTuple_Pack(3, o, o->ob_type, Py_None); - } - else { - t = PyTuple_Pack(2, o, o->ob_type); - } - } - else { - t = PyTuple_Pack(2, o, o->ob_type); - } + + t = _PyCode_ConstantKey(o); if (t == NULL) return -1; @@ -1459,7 +1420,7 @@ static int compiler_lookup_arg(PyObject *dict, PyObject *name) { PyObject *k, *v; - k = PyTuple_Pack(2, name, name->ob_type); + k = _PyCode_ConstantKey(name); if (k == NULL) return -1; v = PyDict_GetItem(dict, k); @@ -4657,9 +4618,10 @@ dict_keys_inorder(PyObject *dict, Py_ssize_t offset) return NULL; while (PyDict_Next(dict, &pos, &k, &v)) { i = PyLong_AS_LONG(v); - /* The keys of the dictionary are tuples. (see compiler_add_o) - The object we want is always first, though. */ - k = PyTuple_GET_ITEM(k, 0); + /* The keys of the dictionary are tuples. (see compiler_add_o + * and _PyCode_ConstantKey). The object we want is always second, + * though. */ + k = PyTuple_GET_ITEM(k, 1); Py_INCREF(k); assert((i - offset) < size); assert((i - offset) >= 0); -- cgit v1.2.1 From 05b0626e91b9f17c0f0be156917a0d087d5724ae Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 26 Jan 2016 00:40:57 +0100 Subject: Add ast.Constant Issue #26146: Add a new kind of AST node: ast.Constant. It can be used by external AST optimizers, but the compiler does not emit directly such node. An optimizer can replace the following AST nodes with ast.Constant: * ast.NameConstant: None, False, True * ast.Num: int, float, complex * ast.Str: str * ast.Bytes: bytes * ast.Tuple if items are constants too: tuple * frozenset Update code to accept ast.Constant instead of ast.Num and/or ast.Str: * compiler * docstrings * ast.literal_eval() * Tools/parser/unparse.py --- Python/compile.c | 60 ++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 47 insertions(+), 13 deletions(-) (limited to 'Python/compile.c') diff --git a/Python/compile.c b/Python/compile.c index a710e82693..ccb05cf1ac 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -1314,7 +1314,11 @@ compiler_isdocstring(stmt_ty s) { if (s->kind != Expr_kind) return 0; - return s->v.Expr.value->kind == Str_kind; + if (s->v.Expr.value->kind == Str_kind) + return 1; + if (s->v.Expr.value->kind == Constant_kind) + return PyUnicode_CheckExact(s->v.Expr.value->v.Constant.value); + return 0; } /* Compile a sequence of statements, checking for a docstring. */ @@ -1688,8 +1692,12 @@ compiler_function(struct compiler *c, stmt_ty s, int is_async) st = (stmt_ty)asdl_seq_GET(body, 0); docstring = compiler_isdocstring(st); - if (docstring && c->c_optimize < 2) - first_const = st->v.Expr.value->v.Str.s; + if (docstring && c->c_optimize < 2) { + if (st->v.Expr.value->kind == Constant_kind) + first_const = st->v.Expr.value->v.Constant.value; + else + first_const = st->v.Expr.value->v.Str.s; + } if (compiler_add_o(c, c->u->u_consts, first_const) < 0) { compiler_exit_scope(c); return 0; @@ -2599,6 +2607,36 @@ compiler_assert(struct compiler *c, stmt_ty s) return 1; } +static int +compiler_visit_stmt_expr(struct compiler *c, expr_ty value) +{ + if (c->c_interactive && c->c_nestlevel <= 1) { + VISIT(c, expr, value); + ADDOP(c, PRINT_EXPR); + return 1; + } + + if (value->kind == Str_kind || value->kind == Num_kind) { + /* ignore strings and numbers */ + return 1; + } + + if (value->kind == Constant_kind) { + PyObject *cst = value->v.Constant.value; + if (PyUnicode_CheckExact(cst) + || PyLong_CheckExact(cst) + || PyFloat_CheckExact(cst) + || PyComplex_CheckExact(cst)) { + /* ignore strings and numbers */ + return 1; + } + } + + VISIT(c, expr, value); + ADDOP(c, POP_TOP); + return 1; +} + static int compiler_visit_stmt(struct compiler *c, stmt_ty s) { @@ -2669,16 +2707,7 @@ compiler_visit_stmt(struct compiler *c, stmt_ty s) case Nonlocal_kind: break; case Expr_kind: - if (c->c_interactive && c->c_nestlevel <= 1) { - VISIT(c, expr, s->v.Expr.value); - ADDOP(c, PRINT_EXPR); - } - else if (s->v.Expr.value->kind != Str_kind && - s->v.Expr.value->kind != Num_kind) { - VISIT(c, expr, s->v.Expr.value); - ADDOP(c, POP_TOP); - } - break; + return compiler_visit_stmt_expr(c, s->v.Expr.value); case Pass_kind: break; case Break_kind: @@ -3625,6 +3654,8 @@ expr_constant(struct compiler *c, expr_ty e) switch (e->kind) { case Ellipsis_kind: return 1; + case Constant_kind: + return PyObject_IsTrue(e->v.Constant.value); case Num_kind: return PyObject_IsTrue(e->v.Num.n); case Str_kind: @@ -3912,6 +3943,9 @@ compiler_visit_expr(struct compiler *c, expr_ty e) return compiler_compare(c, e); case Call_kind: return compiler_call(c, e); + case Constant_kind: + ADDOP_O(c, LOAD_CONST, e->v.Constant.value, consts); + break; case Num_kind: ADDOP_O(c, LOAD_CONST, e->v.Num.n, consts); break; -- cgit v1.2.1 From 6887064d43421164e67d68d401562206cf5756c7 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 8 Feb 2016 18:17:58 +0100 Subject: compiler now ignores constant statements The compile ignores constant statements and emit a SyntaxWarning warning. Don't emit the warning for string statement because triple quoted string is a common syntax for multiline comments. Don't emit the warning on ellipis neither: 'def f(): ...' is a legit syntax for abstract functions. Changes: * test_ast: ignore SyntaxWarning when compiling test statements. Modify test_load_const() to use assignment expressions rather than constant expression. * test_code: add more kinds of constant statements, ignore SyntaxWarning when testing that the compiler removes constant statements. * test_grammar: ignore SyntaxWarning on the statement "1" --- Python/compile.c | 41 ++++++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 11 deletions(-) (limited to 'Python/compile.c') diff --git a/Python/compile.c b/Python/compile.c index ccb05cf1ac..84b79a2fff 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -2616,20 +2616,39 @@ compiler_visit_stmt_expr(struct compiler *c, expr_ty value) return 1; } - if (value->kind == Str_kind || value->kind == Num_kind) { - /* ignore strings and numbers */ + switch (value->kind) + { + case Str_kind: + case Ellipsis_kind: + /* Issue #26204: ignore string statement, but don't emit a + * SyntaxWarning. Triple quoted strings is a common syntax for + * multiline comments. + * + * Don't emit warning on "def f(): ..." neither. It's a legit syntax + * for abstract function. */ return 1; - } - if (value->kind == Constant_kind) { - PyObject *cst = value->v.Constant.value; - if (PyUnicode_CheckExact(cst) - || PyLong_CheckExact(cst) - || PyFloat_CheckExact(cst) - || PyComplex_CheckExact(cst)) { - /* ignore strings and numbers */ - return 1; + case Bytes_kind: + case Num_kind: + case NameConstant_kind: + case Constant_kind: + { + PyObject *msg = PyUnicode_FromString("ignore constant statement"); + if (msg == NULL) + return 0; + if (PyErr_WarnExplicitObject(PyExc_SyntaxWarning, + msg, + c->c_filename, c->u->u_lineno, + NULL, NULL) == -1) { + Py_DECREF(msg); + return 0; } + Py_DECREF(msg); + return 1; + } + + default: + break; } VISIT(c, expr, value); -- cgit v1.2.1 From 5ceba03e1af31e79d9dc3492bf109538f804f12b Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 8 Feb 2016 22:45:06 +0100 Subject: compiler: don't emit SyntaxWarning on const stmt Issue #26204: the compiler doesn't emit SyntaxWarning warnings anymore when constant statements are ignored. --- Python/compile.c | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) (limited to 'Python/compile.c') diff --git a/Python/compile.c b/Python/compile.c index 84b79a2fff..ca1d8656c7 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -2619,33 +2619,13 @@ compiler_visit_stmt_expr(struct compiler *c, expr_ty value) switch (value->kind) { case Str_kind: + case Num_kind: case Ellipsis_kind: - /* Issue #26204: ignore string statement, but don't emit a - * SyntaxWarning. Triple quoted strings is a common syntax for - * multiline comments. - * - * Don't emit warning on "def f(): ..." neither. It's a legit syntax - * for abstract function. */ - return 1; - case Bytes_kind: - case Num_kind: case NameConstant_kind: case Constant_kind: - { - PyObject *msg = PyUnicode_FromString("ignore constant statement"); - if (msg == NULL) - return 0; - if (PyErr_WarnExplicitObject(PyExc_SyntaxWarning, - msg, - c->c_filename, c->u->u_lineno, - NULL, NULL) == -1) { - Py_DECREF(msg); - return 0; - } - Py_DECREF(msg); + /* ignore constant statement */ return 1; - } default: break; -- cgit v1.2.1 From 4e06cb246c62f0c7c7c95eb18ac5f954a5ccfe13 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Sat, 27 Feb 2016 02:19:22 +0100 Subject: compile.c: inline compiler_use_new_block() * Inline compiler_use_new_block() function into its only callee, compiler_enter_scope() * Remove unused NEW_BLOCK() macro --- Python/compile.c | 35 +++++++++-------------------------- 1 file changed, 9 insertions(+), 26 deletions(-) (limited to 'Python/compile.c') diff --git a/Python/compile.c b/Python/compile.c index ca1d8656c7..568bdfe379 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -171,7 +171,6 @@ static int compiler_addop(struct compiler *, int); static int compiler_addop_o(struct compiler *, int, PyObject *, PyObject *); static int compiler_addop_i(struct compiler *, int, Py_ssize_t); static int compiler_addop_j(struct compiler *, int, basicblock *, int); -static basicblock *compiler_use_new_block(struct compiler *); static int compiler_error(struct compiler *, const char *); static int compiler_nameop(struct compiler *, identifier, expr_context_ty); @@ -523,6 +522,7 @@ compiler_enter_scope(struct compiler *c, identifier name, int scope_type, void *key, int lineno) { struct compiler_unit *u; + basicblock *block; u = (struct compiler_unit *)PyObject_Malloc(sizeof( struct compiler_unit)); @@ -620,8 +620,11 @@ compiler_enter_scope(struct compiler *c, identifier name, c->u = u; c->c_nestlevel++; - if (compiler_use_new_block(c) == NULL) + + block = compiler_new_block(c); + if (block == NULL) return 0; + c->u->u_curblock = block; if (u->u_scope_type != COMPILER_SCOPE_MODULE) { if (!compiler_set_qualname(c)) @@ -755,16 +758,6 @@ compiler_new_block(struct compiler *c) return b; } -static basicblock * -compiler_use_new_block(struct compiler *c) -{ - basicblock *block = compiler_new_block(c); - if (block == NULL) - return NULL; - c->u->u_curblock = block; - return block; -} - static basicblock * compiler_next_block(struct compiler *c) { @@ -1208,22 +1201,12 @@ compiler_addop_j(struct compiler *c, int opcode, basicblock *b, int absolute) return 1; } -/* The distinction between NEW_BLOCK and NEXT_BLOCK is subtle. (I'd - like to find better names.) NEW_BLOCK() creates a new block and sets - it as the current block. NEXT_BLOCK() also creates an implicit jump - from the current block to the new block. -*/ +/* NEXT_BLOCK() creates an implicit jump from the current block + to the new block. -/* The returns inside these macros make it impossible to decref objects - created in the local function. Local objects should use the arena. + The returns inside this macro make it impossible to decref objects + created in the local function. Local objects should use the arena. */ - - -#define NEW_BLOCK(C) { \ - if (compiler_use_new_block((C)) == NULL) \ - return 0; \ -} - #define NEXT_BLOCK(C) { \ if (compiler_next_block((C)) == NULL) \ return 0; \ -- cgit v1.2.1 From d1338f71b177d5b2d5d56b18c4b940f2643abe61 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 1 Mar 2016 23:34:47 +0100 Subject: Update assertion in compiler_addop_i() In practice, bytecode instruction arguments are unsigned. Update the assertion to make it more explicit that argument must be greater or equal than 0. Rewrite also the comment. --- Python/compile.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'Python/compile.c') diff --git a/Python/compile.c b/Python/compile.c index 568bdfe379..e86b293543 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -1163,10 +1163,14 @@ compiler_addop_i(struct compiler *c, int opcode, Py_ssize_t oparg) struct instr *i; int off; - /* Integer arguments are limit to 16-bit. There is an extension for 32-bit - integer arguments. */ - assert((-2147483647-1) <= oparg); - assert(oparg <= 2147483647); + /* oparg value is unsigned, but a signed C int is usually used to store + it in the C code (like Python/ceval.c). + + Limit to 32-bit signed C int (rather than INT_MAX) for portability. + + The argument of a concrete bytecode instruction is limited to 16-bit. + EXTENDED_ARG is used for 32-bit arguments. */ + assert(0 <= oparg && oparg <= 2147483647); off = compiler_next_instr(c, c->u->u_curblock); if (off < 0) -- cgit v1.2.1 From fb3a24f3940c9de27b73ae05430758a8877af4af Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 23 Mar 2016 11:36:19 +0100 Subject: compiler.c: fix compiler warnings on Windows --- Python/compile.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'Python/compile.c') diff --git a/Python/compile.c b/Python/compile.c index e86b293543..92fea3d13c 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -195,7 +195,7 @@ static int expr_constant(struct compiler *, expr_ty); static int compiler_with(struct compiler *, stmt_ty, int); static int compiler_async_with(struct compiler *, stmt_ty, int); static int compiler_async_for(struct compiler *, stmt_ty); -static int compiler_call_helper(struct compiler *c, Py_ssize_t n, +static int compiler_call_helper(struct compiler *c, int n, asdl_seq *args, asdl_seq *keywords); static int compiler_try_except(struct compiler *, stmt_ty); @@ -476,9 +476,9 @@ compiler_unit_check(struct compiler_unit *u) { basicblock *block; for (block = u->u_blocks; block != NULL; block = block->b_list) { - assert((void *)block != (void *)0xcbcbcbcb); - assert((void *)block != (void *)0xfbfbfbfb); - assert((void *)block != (void *)0xdbdbdbdb); + assert((Py_uintptr_t)block != 0xcbcbcbcbU); + assert((Py_uintptr_t)block != 0xfbfbfbfbU); + assert((Py_uintptr_t)block != 0xdbdbdbdbU); if (block->b_instr != NULL) { assert(block->b_ialloc > 0); assert(block->b_iused > 0); @@ -3097,7 +3097,8 @@ compiler_set(struct compiler *c, expr_ty e) static int compiler_dict(struct compiler *c, expr_ty e) { - Py_ssize_t i, n, containers, elements; + Py_ssize_t i, n, elements; + int containers; int is_unpacking = 0; n = asdl_seq_LEN(e->v.Dict.values); containers = 0; @@ -3267,12 +3268,13 @@ compiler_formatted_value(struct compiler *c, expr_ty e) /* shared code between compiler_call and compiler_class */ static int compiler_call_helper(struct compiler *c, - Py_ssize_t n, /* Args already pushed */ + int n, /* Args already pushed */ asdl_seq *args, asdl_seq *keywords) { int code = 0; - Py_ssize_t nelts, i, nseen, nkw; + Py_ssize_t nelts, i, nseen; + int nkw; /* the number of tuples and dictionaries on the stack */ Py_ssize_t nsubargs = 0, nsubkwargs = 0; -- cgit v1.2.1