mirror of https://github.com/python/cpython.git
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:
parent
1dbce44b91
commit
0eb2a6e974
|
@ -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):
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue