It turned out not so difficult to support old-style numbers (those

without the Py_TPFLAGS_CHECKTYPES flag) in the wrappers.  This
required a few changes in test_descr.py to cope with the fact that the
complex type has __int__, __long__ and __float__ methods that always
raise an exception.
This commit is contained in:
Guido van Rossum 2001-10-09 11:07:24 +00:00
parent 1dbce44b91
commit 0eb2a6e974
2 changed files with 30 additions and 12 deletions

View File

@ -365,10 +365,11 @@ def numops(a, b, skip=[]):
res = eval(expr, dict) res = eval(expr, dict)
testbinop(a, b, res, expr, name) testbinop(a, b, res, expr, name)
for name, expr in unops.items(): for name, expr in unops.items():
name = "__%s__" % name if name not in skip:
if hasattr(a, name): name = "__%s__" % name
res = eval(expr, dict) if hasattr(a, name):
testunop(a, res, expr, name) res = eval(expr, dict)
testunop(a, res, expr, name)
def ints(): def ints():
if verbose: print "Testing int operations..." if verbose: print "Testing int operations..."
@ -384,7 +385,7 @@ def floats():
def complexes(): def complexes():
if verbose: print "Testing complex operations..." if verbose: print "Testing complex operations..."
numops(100.0j, 3.0j, skip=['lt', 'le', 'gt', 'ge']) numops(100.0j, 3.0j, skip=['lt', 'le', 'gt', 'ge', 'int', 'long', 'float'])
class Number(complex): class Number(complex):
__slots__ = ['prec'] __slots__ = ['prec']
def __new__(cls, *args, **kwds): def __new__(cls, *args, **kwds):

View File

@ -1978,6 +1978,22 @@ wrap_binaryfunc(PyObject *self, PyObject *args, void *wrapped)
return (*func)(self, other); return (*func)(self, other);
} }
static PyObject *
wrap_binaryfunc_l(PyObject *self, PyObject *args, void *wrapped)
{
binaryfunc func = (binaryfunc)wrapped;
PyObject *other;
if (!PyArg_ParseTuple(args, "O", &other))
return NULL;
if (!(self->ob_type->tp_flags & Py_TPFLAGS_CHECKTYPES) &&
self->ob_type != other->ob_type) {
Py_INCREF(Py_NotImplemented);
return Py_NotImplemented;
}
return (*func)(self, other);
}
static PyObject * static PyObject *
wrap_binaryfunc_r(PyObject *self, PyObject *args, void *wrapped) wrap_binaryfunc_r(PyObject *self, PyObject *args, void *wrapped)
{ {
@ -1986,6 +2002,11 @@ wrap_binaryfunc_r(PyObject *self, PyObject *args, void *wrapped)
if (!PyArg_ParseTuple(args, "O", &other)) if (!PyArg_ParseTuple(args, "O", &other))
return NULL; return NULL;
if (!(self->ob_type->tp_flags & Py_TPFLAGS_CHECKTYPES) &&
self->ob_type != other->ob_type) {
Py_INCREF(Py_NotImplemented);
return Py_NotImplemented;
}
return (*func)(other, self); return (*func)(other, self);
} }
@ -1993,7 +2014,7 @@ wrap_binaryfunc_r(PyObject *self, PyObject *args, void *wrapped)
#define BINARY(NAME, OP) \ #define BINARY(NAME, OP) \
static struct wrapperbase tab_##NAME[] = { \ static struct wrapperbase tab_##NAME[] = { \
{"__" #NAME "__", \ {"__" #NAME "__", \
(wrapperfunc)wrap_binaryfunc, \ (wrapperfunc)wrap_binaryfunc_l, \
"x.__" #NAME "__(y) <==> " #OP}, \ "x.__" #NAME "__(y) <==> " #OP}, \
{"__r" #NAME "__", \ {"__r" #NAME "__", \
(wrapperfunc)wrap_binaryfunc_r, \ (wrapperfunc)wrap_binaryfunc_r, \
@ -2778,11 +2799,7 @@ add_operators(PyTypeObject *type)
ADD(mp->mp_ass_subscript, tab_setitem); ADD(mp->mp_ass_subscript, tab_setitem);
} }
/* We don't support "old-style numbers" because their binary if ((nb = type->tp_as_number) != NULL) {
operators require that both arguments have the same type;
the wrappers here only work for new-style numbers. */
if ((type->tp_flags & Py_TPFLAGS_CHECKTYPES) &&
(nb = type->tp_as_number) != NULL) {
ADD(nb->nb_add, tab_add); ADD(nb->nb_add, tab_add);
ADD(nb->nb_subtract, tab_sub); ADD(nb->nb_subtract, tab_sub);
ADD(nb->nb_multiply, tab_mul); ADD(nb->nb_multiply, tab_mul);
@ -2817,7 +2834,7 @@ add_operators(PyTypeObject *type)
ADD(nb->nb_inplace_and, tab_iand); ADD(nb->nb_inplace_and, tab_iand);
ADD(nb->nb_inplace_xor, tab_ixor); ADD(nb->nb_inplace_xor, tab_ixor);
ADD(nb->nb_inplace_or, tab_ior); ADD(nb->nb_inplace_or, tab_ior);
if (type->tp_flags & Py_TPFLAGS_CHECKTYPES) { if (type->tp_flags & Py_TPFLAGS_HAVE_CLASS) {
ADD(nb->nb_floor_divide, tab_floordiv); ADD(nb->nb_floor_divide, tab_floordiv);
ADD(nb->nb_true_divide, tab_truediv); ADD(nb->nb_true_divide, tab_truediv);
ADD(nb->nb_inplace_floor_divide, tab_ifloordiv); ADD(nb->nb_inplace_floor_divide, tab_ifloordiv);