Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 3d9e481

Browse files
committed
give explicitly global functions and classes a global __qualname__ (closes #19301)
1 parent 3586673 commit 3d9e481

6 files changed

Lines changed: 3261 additions & 3451 deletions

File tree

Lib/importlib/_bootstrap.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -369,12 +369,13 @@ def _call_with_frames_removed(f, *args, **kwds):
369369
# free vars)
370370
# Python 3.4a1 3270 (various tweaks to the __class__ closure)
371371
# Python 3.4a1 3280 (remove implicit class argument)
372+
# Python 3.4a4 3290 (changes to __qualname__ computation)
372373
#
373374
# MAGIC must change whenever the bytecode emitted by the compiler may no
374375
# longer be understood by older implementations of the eval loop (usually
375376
# due to the addition of new opcodes).
376377

377-
MAGIC_NUMBER = (3280).to_bytes(2, 'little') + b'\r\n'
378+
MAGIC_NUMBER = (3290).to_bytes(2, 'little') + b'\r\n'
378379
_RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c
379380

380381
_PYCACHE = '__pycache__'

Lib/test/test_descr.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4517,6 +4517,11 @@ class X:
45174517
self.assertRaises(TypeError, type.__dict__['__qualname__'].__set__,
45184518
str, 'Oink')
45194519

4520+
global Y
4521+
class Y:
4522+
pass
4523+
self.assertEqual(Y.__qualname__, 'Y')
4524+
45204525
def test_qualname_dict(self):
45214526
ns = {'__qualname__': 'some.name'}
45224527
tp = type('Foo', (), ns)

Lib/test/test_funcattrs.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ def global_function():
77
def inner_function():
88
class LocalClass:
99
pass
10+
global inner_global_function
11+
def inner_global_function():
12+
pass
1013
return LocalClass
1114
return lambda: inner_function
1215

@@ -116,6 +119,7 @@ def test___qualname__(self):
116119
'global_function.<locals>.inner_function')
117120
self.assertEqual(global_function()()().__qualname__,
118121
'global_function.<locals>.inner_function.<locals>.LocalClass')
122+
self.assertEqual(inner_global_function.__qualname__, 'inner_global_function')
119123
self.b.__qualname__ = 'c'
120124
self.assertEqual(self.b.__qualname__, 'c')
121125
self.b.__qualname__ = 'd'

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ Projected release date: 2013-10-20
1010
Core and Builtins
1111
-----------------
1212

13+
- Issue #19301: Give classes and functions that are explicitly marked global a
14+
global qualname.
15+
1316
- Issue #19279: UTF-7 decoder no more produces illegal strings.
1417

1518
- Issue #16612: Add "Argument Clinic", a compile-time preprocessor for

Python/compile.c

Lines changed: 37 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -650,9 +650,10 @@ compiler_exit_scope(struct compiler *c)
650650
}
651651

652652
static PyObject *
653-
compiler_scope_qualname(struct compiler *c)
653+
compiler_scope_qualname(struct compiler *c, identifier scope_name)
654654
{
655-
Py_ssize_t stack_size, i;
655+
Py_ssize_t stack_size;
656+
int global_scope;
656657
_Py_static_string(dot, ".");
657658
_Py_static_string(locals, "<locals>");
658659
struct compiler_unit *u;
@@ -669,22 +670,41 @@ compiler_scope_qualname(struct compiler *c)
669670
return NULL;
670671

671672
stack_size = PyList_GET_SIZE(c->c_stack);
672-
for (i = 0; i < stack_size; i++) {
673-
capsule = PyList_GET_ITEM(c->c_stack, i);
673+
global_scope = stack_size <= 1;
674+
if (scope_name != NULL && !global_scope) {
675+
int scope;
676+
PyObject *mangled;
677+
capsule = PyList_GET_ITEM(c->c_stack, stack_size - 1);
674678
u = (struct compiler_unit *)PyCapsule_GetPointer(capsule, COMPILER_CAPSULE_NAME_COMPILER_UNIT);
675679
assert(u);
676-
if (u->u_scope_type == COMPILER_SCOPE_MODULE)
677-
continue;
678-
if (PyList_Append(seq, u->u_name))
679-
goto _error;
680-
if (u->u_scope_type == COMPILER_SCOPE_FUNCTION) {
681-
locals_str = _PyUnicode_FromId(&locals);
682-
if (locals_str == NULL)
683-
goto _error;
684-
if (PyList_Append(seq, locals_str))
680+
mangled = _Py_Mangle(u->u_private, scope_name);
681+
if (!mangled)
682+
return NULL;
683+
scope = PyST_GetScope(u->u_ste, mangled);
684+
Py_DECREF(mangled);
685+
assert(scope != GLOBAL_IMPLICIT);
686+
if (scope == GLOBAL_EXPLICIT)
687+
global_scope = 1;
688+
}
689+
if (!global_scope) {
690+
Py_ssize_t i;
691+
for (i = 1; i < stack_size; i++) {
692+
capsule = PyList_GET_ITEM(c->c_stack, i);
693+
u = (struct compiler_unit *)PyCapsule_GetPointer(capsule, COMPILER_CAPSULE_NAME_COMPILER_UNIT);
694+
assert(u);
695+
assert(u->u_scope_type != COMPILER_SCOPE_MODULE);
696+
if (PyList_Append(seq, u->u_name))
685697
goto _error;
698+
if (u->u_scope_type == COMPILER_SCOPE_FUNCTION) {
699+
locals_str = _PyUnicode_FromId(&locals);
700+
if (locals_str == NULL)
701+
goto _error;
702+
if (PyList_Append(seq, locals_str))
703+
goto _error;
704+
}
686705
}
687706
}
707+
688708
u = c->u;
689709
if (PyList_Append(seq, u->u_name))
690710
goto _error;
@@ -1649,7 +1669,7 @@ compiler_function(struct compiler *c, stmt_ty s)
16491669
VISIT_IN_SCOPE(c, stmt, st);
16501670
}
16511671
co = assemble(c, 1);
1652-
qualname = compiler_scope_qualname(c);
1672+
qualname = compiler_scope_qualname(c, s->v.FunctionDef.name);
16531673
compiler_exit_scope(c);
16541674
if (qualname == NULL || co == NULL) {
16551675
Py_XDECREF(qualname);
@@ -1722,7 +1742,7 @@ compiler_class(struct compiler *c, stmt_ty s)
17221742
}
17231743
Py_DECREF(str);
17241744
/* store the __qualname__ */
1725-
str = compiler_scope_qualname(c);
1745+
str = compiler_scope_qualname(c, s->v.ClassDef.name);
17261746
if (!str) {
17271747
compiler_exit_scope(c);
17281748
return 0;
@@ -1862,7 +1882,7 @@ compiler_lambda(struct compiler *c, expr_ty e)
18621882
ADDOP_IN_SCOPE(c, RETURN_VALUE);
18631883
}
18641884
co = assemble(c, 1);
1865-
qualname = compiler_scope_qualname(c);
1885+
qualname = compiler_scope_qualname(c, NULL);
18661886
compiler_exit_scope(c);
18671887
if (qualname == NULL || co == NULL)
18681888
return 0;
@@ -3139,7 +3159,7 @@ compiler_comprehension(struct compiler *c, expr_ty e, int type, identifier name,
31393159
}
31403160

31413161
co = assemble(c, 1);
3142-
qualname = compiler_scope_qualname(c);
3162+
qualname = compiler_scope_qualname(c, NULL);
31433163
compiler_exit_scope(c);
31443164
if (qualname == NULL || co == NULL)
31453165
goto error;

0 commit comments

Comments
 (0)