Left: | ||
Right: |
OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 } |
OLD | NEW |