[Python-checkins] cpython: type_call() now detect bugs in type new and init
victor.stinner
python-checkins at python.org
Thu Sep 3 12:18:00 CEST 2015
https://hg.python.org/cpython/rev/40c659ec4d18
changeset: 97620:40c659ec4d18
user: Victor Stinner <victor.stinner at gmail.com>
date: Thu Sep 03 12:16:49 2015 +0200
summary:
type_call() now detect bugs in type new and init
* Call _Py_CheckFunctionResult() to check for bugs in type
constructors (tp_new)
* Add assertions to ensure an exception was raised if tp_init failed
or that no exception was raised if tp_init succeed
Refactor also the function to have less indentation.
files:
Objects/typeobject.c | 46 ++++++++++++++++++-------------
1 files changed, 27 insertions(+), 19 deletions(-)
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -906,25 +906,33 @@
#endif
obj = type->tp_new(type, args, kwds);
- if (obj != NULL) {
- /* Ugly exception: when the call was type(something),
- don't call tp_init on the result. */
- if (type == &PyType_Type &&
- PyTuple_Check(args) && PyTuple_GET_SIZE(args) == 1 &&
- (kwds == NULL ||
- (PyDict_Check(kwds) && PyDict_Size(kwds) == 0)))
- return obj;
- /* If the returned object is not an instance of type,
- it won't be initialized. */
- if (!PyType_IsSubtype(Py_TYPE(obj), type))
- return obj;
- type = Py_TYPE(obj);
- if (type->tp_init != NULL) {
- int res = type->tp_init(obj, args, kwds);
- if (res < 0) {
- Py_DECREF(obj);
- obj = NULL;
- }
+ obj = _Py_CheckFunctionResult((PyObject*)type, obj, NULL);
+ if (obj == NULL)
+ return NULL;
+
+ /* Ugly exception: when the call was type(something),
+ don't call tp_init on the result. */
+ if (type == &PyType_Type &&
+ PyTuple_Check(args) && PyTuple_GET_SIZE(args) == 1 &&
+ (kwds == NULL ||
+ (PyDict_Check(kwds) && PyDict_Size(kwds) == 0)))
+ return obj;
+
+ /* If the returned object is not an instance of type,
+ it won't be initialized. */
+ if (!PyType_IsSubtype(Py_TYPE(obj), type))
+ return obj;
+
+ type = Py_TYPE(obj);
+ if (type->tp_init != NULL) {
+ int res = type->tp_init(obj, args, kwds);
+ if (res < 0) {
+ assert(PyErr_Occurred());
+ Py_DECREF(obj);
+ obj = NULL;
+ }
+ else {
+ assert(!PyErr_Occurred());
}
}
return obj;
--
Repository URL: https://hg.python.org/cpython
More information about the Python-checkins
mailing list