summaryrefslogtreecommitdiffstats
path: root/Python/compile.c
diff options
context:
space:
mode:
authorBenjamin Peterson <benjamin@python.org>2013-10-19 20:01:13 (GMT)
committerBenjamin Peterson <benjamin@python.org>2013-10-19 20:01:13 (GMT)
commit3d9e481ece356d805ee5658600ef2888e35a5609 (patch)
treef47e7215f5dab6c99da5b0e23872f24a00176137 /Python/compile.c
parent358667370346594c0383f1bfa09e0d650fa8832d (diff)
downloadcpython-3d9e481ece356d805ee5658600ef2888e35a5609.zip
cpython-3d9e481ece356d805ee5658600ef2888e35a5609.tar.gz
cpython-3d9e481ece356d805ee5658600ef2888e35a5609.tar.bz2
give explicitly global functions and classes a global __qualname__ (closes #19301)
Diffstat (limited to 'Python/compile.c')
-rw-r--r--Python/compile.c54
1 files changed, 37 insertions, 17 deletions
diff --git a/Python/compile.c b/Python/compile.c
index 160c6fc..85ea1d0 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -650,9 +650,10 @@ compiler_exit_scope(struct compiler *c)
}
static PyObject *
-compiler_scope_qualname(struct compiler *c)
+compiler_scope_qualname(struct compiler *c, identifier scope_name)
{
- Py_ssize_t stack_size, i;
+ Py_ssize_t stack_size;
+ int global_scope;
_Py_static_string(dot, ".");
_Py_static_string(locals, "<locals>");
struct compiler_unit *u;
@@ -669,22 +670,41 @@ compiler_scope_qualname(struct compiler *c)
return NULL;
stack_size = PyList_GET_SIZE(c->c_stack);
- for (i = 0; i < stack_size; i++) {
- capsule = PyList_GET_ITEM(c->c_stack, i);
+ global_scope = stack_size <= 1;
+ if (scope_name != NULL && !global_scope) {
+ int scope;
+ PyObject *mangled;
+ capsule = PyList_GET_ITEM(c->c_stack, stack_size - 1);
u = (struct compiler_unit *)PyCapsule_GetPointer(capsule, COMPILER_CAPSULE_NAME_COMPILER_UNIT);
assert(u);
- if (u->u_scope_type == COMPILER_SCOPE_MODULE)
- continue;
- if (PyList_Append(seq, u->u_name))
- goto _error;
- if (u->u_scope_type == COMPILER_SCOPE_FUNCTION) {
- locals_str = _PyUnicode_FromId(&locals);
- if (locals_str == NULL)
- goto _error;
- if (PyList_Append(seq, locals_str))
+ mangled = _Py_Mangle(u->u_private, scope_name);
+ if (!mangled)
+ return NULL;
+ scope = PyST_GetScope(u->u_ste, mangled);
+ Py_DECREF(mangled);
+ assert(scope != GLOBAL_IMPLICIT);
+ if (scope == GLOBAL_EXPLICIT)
+ global_scope = 1;
+ }
+ if (!global_scope) {
+ Py_ssize_t i;
+ for (i = 1; i < stack_size; i++) {
+ capsule = PyList_GET_ITEM(c->c_stack, i);
+ u = (struct compiler_unit *)PyCapsule_GetPointer(capsule, COMPILER_CAPSULE_NAME_COMPILER_UNIT);
+ assert(u);
+ assert(u->u_scope_type != COMPILER_SCOPE_MODULE);
+ if (PyList_Append(seq, u->u_name))
goto _error;
+ if (u->u_scope_type == COMPILER_SCOPE_FUNCTION) {
+ locals_str = _PyUnicode_FromId(&locals);
+ if (locals_str == NULL)
+ goto _error;
+ if (PyList_Append(seq, locals_str))
+ goto _error;
+ }
}
}
+
u = c->u;
if (PyList_Append(seq, u->u_name))
goto _error;
@@ -1649,7 +1669,7 @@ compiler_function(struct compiler *c, stmt_ty s)
VISIT_IN_SCOPE(c, stmt, st);
}
co = assemble(c, 1);
- qualname = compiler_scope_qualname(c);
+ qualname = compiler_scope_qualname(c, s->v.FunctionDef.name);
compiler_exit_scope(c);
if (qualname == NULL || co == NULL) {
Py_XDECREF(qualname);
@@ -1722,7 +1742,7 @@ compiler_class(struct compiler *c, stmt_ty s)
}
Py_DECREF(str);
/* store the __qualname__ */
- str = compiler_scope_qualname(c);
+ str = compiler_scope_qualname(c, s->v.ClassDef.name);
if (!str) {
compiler_exit_scope(c);
return 0;
@@ -1862,7 +1882,7 @@ compiler_lambda(struct compiler *c, expr_ty e)
ADDOP_IN_SCOPE(c, RETURN_VALUE);
}
co = assemble(c, 1);
- qualname = compiler_scope_qualname(c);
+ qualname = compiler_scope_qualname(c, NULL);
compiler_exit_scope(c);
if (qualname == NULL || co == NULL)
return 0;
@@ -3139,7 +3159,7 @@ compiler_comprehension(struct compiler *c, expr_ty e, int type, identifier name,
}
co = assemble(c, 1);
- qualname = compiler_scope_qualname(c);
+ qualname = compiler_scope_qualname(c, NULL);
compiler_exit_scope(c);
if (qualname == NULL || co == NULL)
goto error;