diff options
author | Benjamin Peterson <benjamin@python.org> | 2009-05-25 02:40:21 (GMT) |
---|---|---|
committer | Benjamin Peterson <benjamin@python.org> | 2009-05-25 02:40:21 (GMT) |
commit | 87e5006d8c5974597df9e3074b95227187d32be3 (patch) | |
tree | 82f8ff2dae761cdf19eeec36806f3bbb35b439e1 | |
parent | 176a56c69b1563c4a8ac0d8f974b4271177c80ee (diff) | |
download | cpython-87e5006d8c5974597df9e3074b95227187d32be3.zip cpython-87e5006d8c5974597df9e3074b95227187d32be3.tar.gz cpython-87e5006d8c5974597df9e3074b95227187d32be3.tar.bz2 |
handle errors from _PyObject_LookupSpecial when __get__ fails
-rw-r--r-- | Lib/test/test_descr.py | 18 | ||||
-rw-r--r-- | Objects/abstract.c | 13 | ||||
-rw-r--r-- | Objects/enumobject.c | 5 | ||||
-rw-r--r-- | Objects/object.c | 2 | ||||
-rw-r--r-- | Python/sysmodule.c | 10 |
5 files changed, 40 insertions, 8 deletions
diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py index f3c216a..c7989b1 100644 --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -1722,7 +1722,11 @@ order (MRO) for bases """ def __get__(self, obj, owner): record.append(1) return self.impl.__get__(obj, owner) - + class MyException(Exception): + pass + class ErrDescr(object): + def __get__(self, obj, owner): + raise MyException for name, runner, meth_impl, ok, env in specials: class X(Checker): @@ -1741,6 +1745,18 @@ order (MRO) for bases """ runner(X()) self.assertEqual(record, [1], name) + class X(Checker): + pass + for attr, obj in env.iteritems(): + setattr(X, attr, obj) + setattr(X, name, ErrDescr()) + try: + runner(X()) + except MyException: + pass + else: + self.fail("{0!r} didn't raise".format(name)) + def test_specials(self): # Testing special operators... # Test operators like __hash__ for which a built-in default exists diff --git a/Objects/abstract.c b/Objects/abstract.c index 63b2041..5eb7b28 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -111,8 +111,12 @@ _PyObject_LengthHint(PyObject *o, Py_ssize_t defaultvalue) return defaultvalue; /* try o.__length_hint__() */ hintmeth = _PyObject_LookupSpecial(o, "__length_hint__", &hintstrobj); - if (hintmeth == NULL) - return defaultvalue; + if (hintmeth == NULL) { + if (PyErr_Occurred()) + return -1; + else + return defaultvalue; + } ro = PyObject_CallFunctionObjArgs(hintmeth, NULL); Py_DECREF(hintmeth); if (ro == NULL) { @@ -2945,6 +2949,8 @@ PyObject_IsInstance(PyObject *inst, PyObject *cls) } return ok; } + else if (PyErr_Occurred()) + return -1; } return recursive_isinstance(inst, cls); } @@ -3021,6 +3027,9 @@ PyObject_IsSubclass(PyObject *derived, PyObject *cls) } return ok; } + else if (PyErr_Occurred()) { + return -1; + } } return recursive_issubclass(derived, cls); } diff --git a/Objects/enumobject.c b/Objects/enumobject.c index 65d4633..0dc4eef 100644 --- a/Objects/enumobject.c +++ b/Objects/enumobject.c @@ -241,9 +241,12 @@ reversed_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return NULL; } } - else + else { reversed_meth = _PyObject_LookupSpecial(seq, "__reversed__", &reversed_cache); + if (reversed_meth == NULL && PyErr_Occurred()) + return NULL; + } if (reversed_meth != NULL) { PyObject *res = PyObject_CallFunctionObjArgs(reversed_meth, NULL); Py_DECREF(reversed_meth); diff --git a/Objects/object.c b/Objects/object.c index 08abe71..95072af 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -509,6 +509,8 @@ PyObject_Unicode(PyObject *v) res = PyObject_CallFunctionObjArgs(func, NULL); Py_DECREF(func); } + else if (PyErr_Occurred()) + return NULL; } /* Didn't find __unicode__ */ diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 1146746..6eb6b62 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -669,10 +669,12 @@ sys_getsizeof(PyObject *self, PyObject *args, PyObject *kwds) else { PyObject *method = _PyObject_LookupSpecial(o, "__sizeof__", &str__sizeof__); - if (method == NULL) - PyErr_Format(PyExc_TypeError, - "Type %.100s doesn't define __sizeof__", - Py_TYPE(o)->tp_name); + if (method == NULL) { + if (!PyErr_Occurred()) + PyErr_Format(PyExc_TypeError, + "Type %.100s doesn't define __sizeof__", + Py_TYPE(o)->tp_name); + } else { res = PyObject_CallFunctionObjArgs(method, NULL); Py_DECREF(method); |