Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(150878)

Unified Diff: Python/bltinmodule.c

Issue 23722: During metaclass.__init__, super() of the constructed class does not work
Patch Set: Created 3 years ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Objects/typeobject.c ('k') | Python/compile.c » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
--- a/Python/bltinmodule.c Sat Dec 03 15:57:00 2016 -0800
+++ b/Python/bltinmodule.c Sun Dec 04 22:38:04 2016 +1000
@@ -54,8 +54,8 @@
static PyObject *
builtin___build_class__(PyObject *self, PyObject *args, PyObject *kwds)
{
- PyObject *func, *name, *bases, *mkw, *meta, *winner, *prep, *ns, *none;
- PyObject *cls = NULL;
+ PyObject *func, *name, *bases, *mkw, *meta, *winner, *prep, *ns;
+ PyObject *cls = NULL, *cell = NULL;
Py_ssize_t nargs;
int isclass = 0; /* initialize to prevent gcc warning */
@@ -167,14 +167,44 @@
Py_DECREF(bases);
return NULL;
}
- none = PyEval_EvalCodeEx(PyFunction_GET_CODE(func), PyFunction_GET_GLOBALS(func), ns,
+ cell = PyEval_EvalCodeEx(PyFunction_GET_CODE(func), PyFunction_GET_GLOBALS(func), ns,
NULL, 0, NULL, 0, NULL, 0, NULL,
PyFunction_GET_CLOSURE(func));
- if (none != NULL) {
+ if (cell != NULL) {
PyObject *margs[3] = {name, bases, ns};
cls = _PyObject_FastCallDict(meta, margs, 3, mkw);
- Py_DECREF(none);
+ if (cls != NULL && PyType_Check(cls) && PyCell_Check(cell)) {
+ PyObject *cell_cls = PyCell_GET(cell);
+ if (cell_cls != cls) {
+ /* TODO: In 3.7, the deprecation warning becomes a RuntimeError
storchaka 2016/12/04 14:10:59 A dot is needed since the next line is a different
+ * At that point, cell_error won't be needed.
+ */
+ int cell_error;
+ if (cell_cls == NULL) {
+ const char *msg =
+ "__class__ not set defining %.200R as %.200R. "
+ "Was __classcell__ propagated to type.__new__?";
+ cell_error = PyErr_WarnFormat(
+ PyExc_DeprecationWarning, 1, msg, name, cls);
+ } else {
+ const char *msg =
+ "__class__ set to %.200R defining %.200R as %.200R.";
storchaka 2016/12/04 14:10:59 What about the ending dot? It usually is not used
+ PyErr_Format(PyExc_TypeError, msg, cell_cls, name, cls);
+ cell_error = 1;
+ }
+ if (cell_error) {
+ Py_DECREF(cls);
+ cls = NULL;
+ goto error;
+ } else {
+ /* Fill in the cell, since type.__new__ didn't do it */
+ PyCell_Set(cell, cls);
+ }
+ }
+ }
}
+error:
+ Py_XDECREF(cell);
Py_DECREF(ns);
Py_DECREF(meta);
Py_XDECREF(mkw);
« no previous file with comments | « Objects/typeobject.c ('k') | Python/compile.c » ('j') | no next file with comments »

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+