From 8fbf4fa9edcb9efd1ca5d650ed235eb4770dea3a Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Thu, 6 Dec 2012 17:41:04 -0500 Subject: create NameConstant AST class for None, True, and False literals (closes #16619) --- Python/compile.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'Python/compile.c') diff --git a/Python/compile.c b/Python/compile.c index 3cf71ef09e..3e960ccbfe 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -3194,12 +3194,18 @@ expr_constant(struct compiler *c, expr_ty e) case Name_kind: /* optimize away names that can't be reassigned */ id = PyUnicode_AsUTF8(e->v.Name.id); - if (strcmp(id, "True") == 0) return 1; - if (strcmp(id, "False") == 0) return 0; - if (strcmp(id, "None") == 0) return 0; - if (strcmp(id, "__debug__") == 0) - return ! c->c_optimize; - /* fall through */ + if (id && strcmp(id, "__debug__") == 0) + return !c->c_optimize; + return -1; + case NameConstant_kind: { + PyObject *o = e->v.NameConstant.value; + if (o == Py_None) + return 0; + else if (o == Py_True) + return 1; + else if (o == Py_False) + return 0; + } default: return -1; } @@ -3375,6 +3381,9 @@ compiler_visit_expr(struct compiler *c, expr_ty e) case Ellipsis_kind: ADDOP_O(c, LOAD_CONST, Py_Ellipsis, consts); break; + case NameConstant_kind: + ADDOP_O(c, LOAD_CONST, e->v.NameConstant.value, consts); + break; /* The following exprs can be assignment targets. */ case Attribute_kind: if (e->v.Attribute.ctx != AugStore) -- cgit v1.2.1 From 114832065bf0892650154c391093095d8d950c25 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Thu, 6 Dec 2012 17:49:58 -0500 Subject: assert than we never try to deal with True, False, or None as a name --- Python/compile.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'Python/compile.c') diff --git a/Python/compile.c b/Python/compile.c index 3e960ccbfe..8f876a6d0d 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -2635,6 +2635,10 @@ compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx) if (!mangled) return 0; + assert(PyUnicode_CompareWithASCIIString(name, "None") && + PyUnicode_CompareWithASCIIString(name, "True") && + PyUnicode_CompareWithASCIIString(name, "False")); + op = 0; optype = OP_NAME; scope = PyST_GetScope(c->u->u_ste, mangled); -- cgit v1.2.1 From 3519d4fdaa0875b231d459d2bbe948aeb6761af3 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sun, 10 Feb 2013 09:29:59 -0500 Subject: evaluate positional defaults before keyword-only defaults (closes #16967) --- Python/compile.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Python/compile.c') diff --git a/Python/compile.c b/Python/compile.c index 8f876a6d0d..a0df40c323 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -1565,6 +1565,8 @@ compiler_function(struct compiler *c, stmt_ty s) if (!compiler_decorators(c, decos)) return 0; + if (args->defaults) + VISIT_SEQ(c, expr, args->defaults); if (args->kwonlyargs) { int res = compiler_visit_kwonlydefaults(c, args->kwonlyargs, args->kw_defaults); @@ -1572,8 +1574,6 @@ compiler_function(struct compiler *c, stmt_ty s) return 0; kw_default_count = res; } - if (args->defaults) - VISIT_SEQ(c, expr, args->defaults); num_annotations = compiler_visit_annotations(c, args, returns); if (num_annotations < 0) return 0; -- cgit v1.2.1 From 7ca707eaa6c4fb73690a0ef904261a63fd0c6385 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sun, 10 Feb 2013 09:48:22 -0500 Subject: evaluate lambda keyword-only defaults after positional defaults (#16967 again) --- Python/compile.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Python/compile.c') diff --git a/Python/compile.c b/Python/compile.c index a0df40c323..61f35f82cd 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -1794,14 +1794,14 @@ compiler_lambda(struct compiler *c, expr_ty e) return 0; } + if (args->defaults) + VISIT_SEQ(c, expr, args->defaults); if (args->kwonlyargs) { int res = compiler_visit_kwonlydefaults(c, args->kwonlyargs, args->kw_defaults); if (res < 0) return 0; kw_default_count = res; } - if (args->defaults) - VISIT_SEQ(c, expr, args->defaults); if (!compiler_enter_scope(c, name, COMPILER_SCOPE_FUNCTION, (void *)e, e->lineno)) return 0; -- cgit v1.2.1 From 7eadff200c3acb1286b95d417edfcc56cee617ee Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Mon, 18 Mar 2013 10:48:58 -0700 Subject: unify some ast.argument's attrs; change Attribute column offset (closes #16795) Patch from Sven Brauch. --- Python/compile.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'Python/compile.c') diff --git a/Python/compile.c b/Python/compile.c index 61f35f82cd..0aca8bd2e9 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -1498,15 +1498,15 @@ compiler_visit_annotations(struct compiler *c, arguments_ty args, if (compiler_visit_argannotations(c, args->args, names)) goto error; - if (args->varargannotation && - compiler_visit_argannotation(c, args->vararg, - args->varargannotation, names)) + if (args->vararg && args->vararg->annotation && + compiler_visit_argannotation(c, args->vararg->arg, + args->vararg->annotation, names)) goto error; if (compiler_visit_argannotations(c, args->kwonlyargs, names)) goto error; - if (args->kwargannotation && - compiler_visit_argannotation(c, args->kwarg, - args->kwargannotation, names)) + if (args->kwarg && args->kwarg->annotation && + compiler_visit_argannotation(c, args->kwarg->arg, + args->kwarg->annotation, names)) goto error; if (!return_str) { -- cgit v1.2.1 From a2fc2ebe3d645e60d26996b51d8b33a1fe177d5c Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Tue, 30 Apr 2013 09:41:40 -0400 Subject: check local class namespace before reaching for cells (closes #17853) --- Python/compile.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'Python/compile.c') diff --git a/Python/compile.c b/Python/compile.c index 52e8188d41..1ecbae8181 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -970,6 +970,7 @@ opcode_stack_effect(int opcode, int oparg) case LOAD_CLOSURE: return 1; case LOAD_DEREF: + case LOAD_CLASSDEREF: return 1; case STORE_DEREF: return -1; @@ -2677,7 +2678,9 @@ compiler_nameop(struct compiler *c, identifier name, expr_context_ty ctx) switch (optype) { case OP_DEREF: switch (ctx) { - case Load: op = LOAD_DEREF; break; + case Load: + op = (c->u->u_ste->ste_type == ClassBlock) ? LOAD_CLASSDEREF : LOAD_DEREF; + break; case Store: op = STORE_DEREF; break; case AugLoad: case AugStore: -- cgit v1.2.1 From f773ed5048253f3e3d86b28e47f8245c2542027c Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Wed, 15 May 2013 15:26:42 -0500 Subject: hide the __class__ closure from the class body (#12370) --- Python/compile.c | 64 +++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 49 insertions(+), 15 deletions(-) (limited to 'Python/compile.c') diff --git a/Python/compile.c b/Python/compile.c index 1ecbae8181..24ff61f8a9 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -535,6 +535,37 @@ compiler_enter_scope(struct compiler *c, identifier name, compiler_unit_free(u); return 0; } + if (u->u_ste->ste_needs_class_closure) { + /* Cook up a implicit __class__ cell. */ + _Py_IDENTIFIER(__class__); + PyObject *tuple, *name, *zero; + int res; + assert(u->u_scope_type == COMPILER_SCOPE_CLASS); + assert(PyDict_Size(u->u_cellvars) == 0); + name = _PyUnicode_FromId(&PyId___class__); + if (!name) { + compiler_unit_free(u); + return 0; + } + tuple = PyTuple_Pack(2, name, Py_TYPE(name)); + if (!tuple) { + compiler_unit_free(u); + return 0; + } + zero = PyLong_FromLong(0); + if (!zero) { + Py_DECREF(tuple); + compiler_unit_free(u); + return 0; + } + res = PyDict_SetItem(u->u_cellvars, tuple, zero); + Py_DECREF(tuple); + Py_DECREF(zero); + if (res < 0) { + compiler_unit_free(u); + return 0; + } + } u->u_freevars = dictbytype(u->u_ste->ste_symbols, FREE, DEF_FREE_CLASS, PyDict_Size(u->u_cellvars)); @@ -1331,6 +1362,9 @@ compiler_mod(struct compiler *c, mod_ty mod) static int get_ref_type(struct compiler *c, PyObject *name) { + if (c->u->u_scope_type == COMPILER_SCOPE_CLASS && + !PyUnicode_CompareWithASCIIString(name, "__class__")) + return CELL; int scope = PyST_GetScope(c->u->u_ste, name); if (scope == 0) { char buf[350]; @@ -1704,24 +1738,24 @@ compiler_class(struct compiler *c, stmt_ty s) compiler_exit_scope(c); return 0; } - /* return the (empty) __class__ cell */ - str = PyUnicode_InternFromString("__class__"); - if (str == NULL) { - compiler_exit_scope(c); - return 0; - } - i = compiler_lookup_arg(c->u->u_cellvars, str); - Py_DECREF(str); - if (i == -1) { - /* This happens when nobody references the cell */ - PyErr_Clear(); - /* Return None */ - ADDOP_O(c, LOAD_CONST, Py_None, consts); - } - else { + if (c->u->u_ste->ste_needs_class_closure) { + /* return the (empty) __class__ cell */ + str = PyUnicode_InternFromString("__class__"); + if (str == NULL) { + compiler_exit_scope(c); + return 0; + } + i = compiler_lookup_arg(c->u->u_cellvars, str); + Py_DECREF(str); + assert(i == 0); /* Return the cell where to store __class__ */ ADDOP_I(c, LOAD_CLOSURE, i); } + else { + assert(PyDict_Size(c->u->u_cellvars) == 0); + /* This happens when nobody references the cell. Return None. */ + ADDOP_O(c, LOAD_CONST, Py_None, consts); + } ADDOP_IN_SCOPE(c, RETURN_VALUE); /* create the code object */ co = assemble(c, 1); -- cgit v1.2.1 From df197a8dcb7f4aba4ba0e6b28f910cb28088549e Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Thu, 16 May 2013 14:37:25 -0500 Subject: rather than passing locals to the class body, just execute the class body in the proper environment --- Python/compile.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) (limited to 'Python/compile.c') diff --git a/Python/compile.c b/Python/compile.c index 24ff61f8a9..65043e4396 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -893,8 +893,6 @@ opcode_stack_effect(int opcode, int oparg) return 7; case WITH_CLEANUP: return -1; /* XXX Sometimes more */ - case STORE_LOCALS: - return -1; case RETURN_VALUE: return -1; case IMPORT_STAR: @@ -1696,12 +1694,6 @@ compiler_class(struct compiler *c, stmt_ty s) Py_INCREF(s->v.ClassDef.name); Py_XDECREF(c->u->u_private); c->u->u_private = s->v.ClassDef.name; - /* force it to have one mandatory argument */ - c->u->u_argcount = 1; - /* load the first argument (__locals__) ... */ - ADDOP_I(c, LOAD_FAST, 0); - /* ... and store it into f_locals */ - ADDOP_IN_SCOPE(c, STORE_LOCALS); /* load (global) __name__ ... */ str = PyUnicode_InternFromString("__name__"); if (!str || !compiler_nameop(c, str, Load)) { @@ -4110,9 +4102,8 @@ compute_code_flags(struct compiler *c) { PySTEntryObject *ste = c->u->u_ste; int flags = 0, n; - if (ste->ste_type != ModuleBlock) - flags |= CO_NEWLOCALS; if (ste->ste_type == FunctionBlock) { + flags |= CO_NEWLOCALS; if (!ste->ste_unoptimized) flags |= CO_OPTIMIZED; if (ste->ste_nested) -- cgit v1.2.1 From 3be142c560917a899230a0695dccb1052bda0f3a Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 16 May 2013 22:17:17 +0200 Subject: fix compilation on Windows --- Python/compile.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'Python/compile.c') diff --git a/Python/compile.c b/Python/compile.c index 65043e4396..4fc7575926 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -1360,10 +1360,11 @@ compiler_mod(struct compiler *c, mod_ty mod) static int get_ref_type(struct compiler *c, PyObject *name) { + int scope; if (c->u->u_scope_type == COMPILER_SCOPE_CLASS && !PyUnicode_CompareWithASCIIString(name, "__class__")) return CELL; - int scope = PyST_GetScope(c->u->u_ste, name); + scope = PyST_GetScope(c->u->u_ste, name); if (scope == 0) { char buf[350]; PyOS_snprintf(buf, sizeof(buf), -- cgit v1.2.1 From 3d0056f5b1d38eeecacd4e905a25d9ff0130e322 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 11 Jul 2013 22:50:45 +0200 Subject: Issue #18408: Fix compiler_import() to handle PyUnicode_Substring() failure properly --- Python/compile.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'Python/compile.c') diff --git a/Python/compile.c b/Python/compile.c index 4fc7575926..d11e3abeaa 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -2316,8 +2316,11 @@ compiler_import(struct compiler *c, stmt_ty s) identifier tmp = alias->name; Py_ssize_t dot = PyUnicode_FindChar( alias->name, '.', 0, PyUnicode_GET_LENGTH(alias->name), 1); - if (dot != -1) + if (dot != -1) { tmp = PyUnicode_Substring(alias->name, 0, dot); + if (tmp == NULL) + return 0; + } r = compiler_nameop(c, tmp, Store); if (dot != -1) { Py_DECREF(tmp); -- cgit v1.2.1