summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2002-06-10 14:30:43 (GMT)
committerGuido van Rossum <guido@python.org>2002-06-10 14:30:43 (GMT)
commit2309498595cb5a69547ad87a66b4574971684ec3 (patch)
tree334b40a27e2613ef4eb20b4b4c8ce5d9ac5d9344
parentf70a0a8471fff12a4be06a2a1d643b32a7d40502 (diff)
downloadcpython-2309498595cb5a69547ad87a66b4574971684ec3.zip
cpython-2309498595cb5a69547ad87a66b4574971684ec3.tar.gz
cpython-2309498595cb5a69547ad87a66b4574971684ec3.tar.bz2
Three's a charm: yet another fix for SF bug 551412. Thinking again
about the test case, slot_nb_power gets called on behalf of its second argument, but with a non-None modulus it wouldn't check this, and believes it is called on behalf of its first argument. Fix this properly, and get rid of the code in _PyType_Lookup() that tries to call _PyType_Ready(). But do leave a check for a NULL tp_mro there, because this can still legitimately occur. I'll fix this in 2.2.x too.
-rw-r--r--Objects/typeobject.c36
1 files changed, 17 insertions, 19 deletions
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index cb2c791..07de6dc 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -1309,22 +1309,13 @@ _PyType_Lookup(PyTypeObject *type, PyObject *name)
/* Look in tp_dict of types in MRO */
mro = type->tp_mro;
- if (mro == NULL) {
- if (PyType_Ready(type) < 0) {
- /* It's not ideal to clear the error condition,
- but this function is documented as not setting
- an exception, and I don't want to change that.
- When PyType_Ready() can't proceed, it won't
- set the "ready" flag, so future attempts to ready
- the same type will call it again -- hopefully
- in a context that propagates the exception out.
- */
- PyErr_Clear();
- return NULL;
- }
- mro = type->tp_mro;
- assert(mro != NULL);
- }
+
+ /* If mro is NULL, the type is either not yet initialized
+ by PyType_Ready(), or already cleared by type_clear().
+ Either way the safest thing to do is to return NULL. */
+ if (mro == NULL)
+ return NULL;
+
assert(PyTuple_Check(mro));
n = PyTuple_GET_SIZE(mro);
for (i = 0; i < n; i++) {
@@ -3099,9 +3090,16 @@ slot_nb_power(PyObject *self, PyObject *other, PyObject *modulus)
if (modulus == Py_None)
return slot_nb_power_binary(self, other);
- /* Three-arg power doesn't use __rpow__ */
- return call_method(self, "__pow__", &pow_str,
- "(OO)", other, modulus);
+ /* Three-arg power doesn't use __rpow__. But ternary_op
+ can call this when the second argument's type uses
+ slot_nb_power, so check before calling self.__pow__. */
+ if (self->ob_type->tp_as_number != NULL &&
+ self->ob_type->tp_as_number->nb_power == slot_nb_power) {
+ return call_method(self, "__pow__", &pow_str,
+ "(OO)", other, modulus);
+ }
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
}
SLOT0(slot_nb_negative, "__neg__")