summaryrefslogtreecommitdiff
path: root/Python/compile.c
diff options
context:
space:
mode:
authorNick Coghlan <ncoghlan@gmail.com>2016-12-05 16:47:55 +1000
committerNick Coghlan <ncoghlan@gmail.com>2016-12-05 16:47:55 +1000
commit19d246745d9d013c12e9560dd020d778381780fb (patch)
treea296697991d1f411c3ee76690c6549985744e85a /Python/compile.c
parent71c62e14aa27d73623427a0a626b1f20df309e43 (diff)
downloadcpython-git-19d246745d9d013c12e9560dd020d778381780fb.tar.gz
Issue #23722: improve __classcell__ compatibility
Handling zero-argument super() in __init_subclass__ and __set_name__ involved moving __class__ initialisation to type.__new__. This requires cooperation from custom metaclasses to ensure that the new __classcell__ entry is passed along appropriately. The initial implementation of that change resulted in abruptly broken zero-argument super() support in metaclasses that didn't adhere to the new requirements (such as Django's metaclass for Model definitions). The updated approach adopted here instead emits a deprecation warning for those cases, and makes them work the same way they did in Python 3.5. This patch also improves the related class machinery documentation to cover these details and to include more reader-friendly cross-references and index entries.
Diffstat (limited to 'Python/compile.c')
-rw-r--r--Python/compile.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/Python/compile.c b/Python/compile.c
index a8d7fcd717..35151cdd59 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -1967,8 +1967,9 @@ compiler_class(struct compiler *c, stmt_ty s)
compiler_exit_scope(c);
return 0;
}
+ /* Return __classcell__ if it is referenced, otherwise return None */
if (c->u->u_ste->ste_needs_class_closure) {
- /* store __classcell__ into class namespace */
+ /* Store __classcell__ into class namespace & return it */
str = PyUnicode_InternFromString("__class__");
if (str == NULL) {
compiler_exit_scope(c);
@@ -1983,6 +1984,7 @@ compiler_class(struct compiler *c, stmt_ty s)
assert(i == 0);
ADDOP_I(c, LOAD_CLOSURE, i);
+ ADDOP(c, DUP_TOP);
str = PyUnicode_InternFromString("__classcell__");
if (!str || !compiler_nameop(c, str, Store)) {
Py_XDECREF(str);
@@ -1992,9 +1994,11 @@ compiler_class(struct compiler *c, stmt_ty s)
Py_DECREF(str);
}
else {
- /* This happens when nobody references the cell. */
+ /* No methods referenced __class__, so just return None */
assert(PyDict_Size(c->u->u_cellvars) == 0);
+ ADDOP_O(c, LOAD_CONST, Py_None, consts);
}
+ ADDOP_IN_SCOPE(c, RETURN_VALUE);
/* create the code object */
co = assemble(c, 1);
}