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

Side by Side Diff: Python/bltinmodule.c

Issue 23722: During metaclass.__init__, super() of the constructed class does not work
Patch Set: Created 3 years ago
Left:
Right:
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 unified diff | Download patch
OLDNEW
1 /* Built-in functions */ 1 /* Built-in functions */
2 2
3 #include "Python.h" 3 #include "Python.h"
4 #include "Python-ast.h" 4 #include "Python-ast.h"
5 5
6 #include "node.h" 6 #include "node.h"
7 #include "code.h" 7 #include "code.h"
8 8
9 #include "asdl.h" 9 #include "asdl.h"
10 #include "ast.h" 10 #include "ast.h"
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 _Py_IDENTIFIER(stdin); 47 _Py_IDENTIFIER(stdin);
48 _Py_IDENTIFIER(stdout); 48 _Py_IDENTIFIER(stdout);
49 _Py_IDENTIFIER(stderr); 49 _Py_IDENTIFIER(stderr);
50 50
51 #include "clinic/bltinmodule.c.h" 51 #include "clinic/bltinmodule.c.h"
52 52
53 /* AC: cannot convert yet, waiting for *args support */ 53 /* AC: cannot convert yet, waiting for *args support */
54 static PyObject * 54 static PyObject *
55 builtin___build_class__(PyObject *self, PyObject *args, PyObject *kwds) 55 builtin___build_class__(PyObject *self, PyObject *args, PyObject *kwds)
56 { 56 {
57 PyObject *func, *name, *bases, *mkw, *meta, *winner, *prep, *ns, *none; 57 PyObject *func, *name, *bases, *mkw, *meta, *winner, *prep, *ns;
58 PyObject *cls = NULL; 58 PyObject *cls = NULL, *cell = NULL;
59 Py_ssize_t nargs; 59 Py_ssize_t nargs;
60 int isclass = 0; /* initialize to prevent gcc warning */ 60 int isclass = 0; /* initialize to prevent gcc warning */
61 61
62 assert(args != NULL); 62 assert(args != NULL);
63 if (!PyTuple_Check(args)) { 63 if (!PyTuple_Check(args)) {
64 PyErr_SetString(PyExc_TypeError, 64 PyErr_SetString(PyExc_TypeError,
65 "__build_class__: args is not a tuple"); 65 "__build_class__: args is not a tuple");
66 return NULL; 66 return NULL;
67 } 67 }
68 nargs = PyTuple_GET_SIZE(args); 68 nargs = PyTuple_GET_SIZE(args);
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 PyObject *pargs[2] = {name, bases}; 160 PyObject *pargs[2] = {name, bases};
161 ns = _PyObject_FastCallDict(prep, pargs, 2, mkw); 161 ns = _PyObject_FastCallDict(prep, pargs, 2, mkw);
162 Py_DECREF(prep); 162 Py_DECREF(prep);
163 } 163 }
164 if (ns == NULL) { 164 if (ns == NULL) {
165 Py_DECREF(meta); 165 Py_DECREF(meta);
166 Py_XDECREF(mkw); 166 Py_XDECREF(mkw);
167 Py_DECREF(bases); 167 Py_DECREF(bases);
168 return NULL; 168 return NULL;
169 } 169 }
170 none = PyEval_EvalCodeEx(PyFunction_GET_CODE(func), PyFunction_GET_GLOBALS(f unc), ns, 170 cell = PyEval_EvalCodeEx(PyFunction_GET_CODE(func), PyFunction_GET_GLOBALS(f unc), ns,
171 NULL, 0, NULL, 0, NULL, 0, NULL, 171 NULL, 0, NULL, 0, NULL, 0, NULL,
172 PyFunction_GET_CLOSURE(func)); 172 PyFunction_GET_CLOSURE(func));
173 if (none != NULL) { 173 if (cell != NULL) {
174 PyObject *margs[3] = {name, bases, ns}; 174 PyObject *margs[3] = {name, bases, ns};
175 cls = _PyObject_FastCallDict(meta, margs, 3, mkw); 175 cls = _PyObject_FastCallDict(meta, margs, 3, mkw);
storchaka 2016/12/04 11:23:35 Is it worth to check that cls is a type?
Nick Coghlan 2016/12/04 13:39:05 Essential, as it turns out - the missing test case
176 Py_DECREF(none); 176 if (cls != NULL && PyCell_Check(cell)) {
177 PyObject *cell_cls = PyCell_GET(cell);
178 if (cell_cls != cls) {
179 int cell_error = 0;
storchaka 2016/12/04 11:23:35 Initialization is not needed.
Nick Coghlan 2016/12/04 13:39:05 Done.
180 /*TODO: In 3.7, deprecation warning becomes a RuntimeError */
storchaka 2016/12/04 11:23:35 Missed space after "/*".
Nick Coghlan 2016/12/04 13:39:05 Done.
181 if (cell_cls == NULL) {
182 char *msg = "__class__ not set for %.200R. "
storchaka 2016/12/04 11:23:35 It would be better to use "const char *".
Nick Coghlan 2016/12/04 13:39:05 Done.
183 "Was __classcell__ propagated to type.__new__?";
184 cell_error = PyErr_WarnFormat(
185 PyExc_DeprecationWarning, 1, msg, cls);
186 } else {
187 char *msg = "__class__ set to %.200R for %.200R. ";
storchaka 2016/12/04 11:23:35 Redundant space at the end. The dot perhaps is not
Nick Coghlan 2016/12/04 13:39:05 Done.
188 PyErr_Format(PyExc_TypeError, msg, cell_cls, cls);
189 cell_error = 1;
190 }
191 if (cell_error) {
192 Py_DECREF(cls);
193 cls = NULL;
194 goto error;
195 } else {
196 /* Fill in the cell, since type.__new__ didn't do it */
197 PyCell_SET(cell, cls);
storchaka 2016/12/04 11:23:35 Leaks old value of the cell. You can add Py_XDECR
Nick Coghlan 2016/12/04 13:39:05 Done.
198 }
199 }
200 }
177 } 201 }
202 error:
203 Py_XDECREF(cell);
178 Py_DECREF(ns); 204 Py_DECREF(ns);
179 Py_DECREF(meta); 205 Py_DECREF(meta);
180 Py_XDECREF(mkw); 206 Py_XDECREF(mkw);
181 Py_DECREF(bases); 207 Py_DECREF(bases);
182 return cls; 208 return cls;
183 } 209 }
184 210
185 PyDoc_STRVAR(build_class_doc, 211 PyDoc_STRVAR(build_class_doc,
186 "__build_class__(func, name, *bases, metaclass=None, **kwds) -> class\n\ 212 "__build_class__(func, name, *bases, metaclass=None, **kwds) -> class\n\
187 \n\ 213 \n\
(...skipping 2523 matching lines...) Expand 10 before | Expand all | Expand 10 after
2711 if (PyDict_SetItemString(dict, "__debug__", debug) < 0) { 2737 if (PyDict_SetItemString(dict, "__debug__", debug) < 0) {
2712 Py_DECREF(debug); 2738 Py_DECREF(debug);
2713 return NULL; 2739 return NULL;
2714 } 2740 }
2715 Py_DECREF(debug); 2741 Py_DECREF(debug);
2716 2742
2717 return mod; 2743 return mod;
2718 #undef ADD_TO_ALL 2744 #undef ADD_TO_ALL
2719 #undef SETBUILTIN 2745 #undef SETBUILTIN
2720 } 2746 }
OLDNEW
« Objects/typeobject.c ('K') | « Objects/typeobject.c ('k') | Python/compile.c » ('j') | no next file with comments »

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