From 11c2cbb304265b13bf7564bd2523c18bbc7121b9 Mon Sep 17 00:00:00 2001 From: Graham Dumpleton Date: Thu, 22 Aug 2013 22:28:52 +1000 Subject: [PATCH] Fixes to number methods and addition of tests for same. --- src/_wrappers.c | 323 ++++++++++++++++++++++++------------- src/wrappers.py | 51 +++--- tests/test_object_proxy.py | 297 ++++++++++++++++++++++++++++++++++ 3 files changed, 542 insertions(+), 129 deletions(-) diff --git a/src/_wrappers.c b/src/_wrappers.c index 2baa15b..cbec7aa 100644 --- a/src/_wrappers.c +++ b/src/_wrappers.c @@ -159,95 +159,97 @@ static PyObject *WraptObjectProxy_call( /* ------------------------------------------------------------------------- */ -static PyObject *WraptObjectProxy_add(WraptObjectProxyObject *self, - PyObject *other) +static PyObject *WraptObjectProxy_add(PyObject *o1, PyObject *o2) { - if (!self->wrapped) { - PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised"); - return NULL; - } + if (PyObject_IsInstance(o1, (PyObject *)&WraptObjectProxy_Type)) + o1 = ((WraptObjectProxyObject *)o1)->wrapped; - return PyNumber_Add(self->wrapped, other); + if (PyObject_IsInstance(o2, (PyObject *)&WraptObjectProxy_Type)) + o2 = ((WraptObjectProxyObject *)o2)->wrapped; + + return PyNumber_Add(o1, o2); } /* ------------------------------------------------------------------------- */ -static PyObject *WraptObjectProxy_subtract(WraptObjectProxyObject *self, - PyObject *other) +static PyObject *WraptObjectProxy_subtract(PyObject *o1, PyObject *o2) { - if (!self->wrapped) { - PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised"); - return NULL; - } + if (PyObject_IsInstance(o1, (PyObject *)&WraptObjectProxy_Type)) + o1 = ((WraptObjectProxyObject *)o1)->wrapped; - return PyNumber_Subtract(self->wrapped, other); + if (PyObject_IsInstance(o2, (PyObject *)&WraptObjectProxy_Type)) + o2 = ((WraptObjectProxyObject *)o2)->wrapped; + + + return PyNumber_Subtract(o1, o2); } /* ------------------------------------------------------------------------- */ -static PyObject *WraptObjectProxy_multiply(WraptObjectProxyObject *self, - PyObject *other) +static PyObject *WraptObjectProxy_multiply(PyObject *o1, PyObject *o2) { - if (!self->wrapped) { - PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised"); - return NULL; - } + if (PyObject_IsInstance(o1, (PyObject *)&WraptObjectProxy_Type)) + o1 = ((WraptObjectProxyObject *)o1)->wrapped; - return PyNumber_Multiply(self->wrapped, other); + if (PyObject_IsInstance(o2, (PyObject *)&WraptObjectProxy_Type)) + o2 = ((WraptObjectProxyObject *)o2)->wrapped; + + return PyNumber_Multiply(o1, o2); } /* ------------------------------------------------------------------------- */ #if PY_MAJOR_VERSION < 3 -static PyObject *WraptObjectProxy_divide(WraptObjectProxyObject *self, - PyObject *other) +static PyObject *WraptObjectProxy_divide(PyObject *o1, PyObject *o2) { - if (!self->wrapped) { - PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised"); - return NULL; - } + if (PyObject_IsInstance(o1, (PyObject *)&WraptObjectProxy_Type)) + o1 = ((WraptObjectProxyObject *)o1)->wrapped; - return PyNumber_Divide(self->wrapped, other); + if (PyObject_IsInstance(o2, (PyObject *)&WraptObjectProxy_Type)) + o2 = ((WraptObjectProxyObject *)o2)->wrapped; + + return PyNumber_Divide(o1, o2); } #endif /* ------------------------------------------------------------------------- */ -static PyObject *WraptObjectProxy_remainder(WraptObjectProxyObject *self, - PyObject *other) +static PyObject *WraptObjectProxy_remainder(PyObject *o1, PyObject *o2) { - if (!self->wrapped) { - PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised"); - return NULL; - } + if (PyObject_IsInstance(o1, (PyObject *)&WraptObjectProxy_Type)) + o1 = ((WraptObjectProxyObject *)o1)->wrapped; - return PyNumber_Remainder(self->wrapped, other); + if (PyObject_IsInstance(o2, (PyObject *)&WraptObjectProxy_Type)) + o2 = ((WraptObjectProxyObject *)o2)->wrapped; + + return PyNumber_Remainder(o1, o2); } /* ------------------------------------------------------------------------- */ -static PyObject *WraptObjectProxy_divmod(WraptObjectProxyObject *self, - PyObject *other) +static PyObject *WraptObjectProxy_divmod(PyObject *o1, PyObject *o2) { - if (!self->wrapped) { - PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised"); - return NULL; - } + if (PyObject_IsInstance(o1, (PyObject *)&WraptObjectProxy_Type)) + o1 = ((WraptObjectProxyObject *)o1)->wrapped; - return PyNumber_Divmod(self->wrapped, other); + if (PyObject_IsInstance(o2, (PyObject *)&WraptObjectProxy_Type)) + o2 = ((WraptObjectProxyObject *)o2)->wrapped; + + return PyNumber_Divmod(o1, o2); } /* ------------------------------------------------------------------------- */ -static PyObject *WraptObjectProxy_power(WraptObjectProxyObject *self, - PyObject *other, PyObject *modulo) +static PyObject *WraptObjectProxy_power(PyObject *o1, PyObject *o2, + PyObject *modulo) { - if (!self->wrapped) { - PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised"); - return NULL; - } + if (PyObject_IsInstance(o1, (PyObject *)&WraptObjectProxy_Type)) + o1 = ((WraptObjectProxyObject *)o1)->wrapped; - return PyNumber_Power(self->wrapped, other, modulo); + if (PyObject_IsInstance(o2, (PyObject *)&WraptObjectProxy_Type)) + o2 = ((WraptObjectProxyObject *)o2)->wrapped; + + return PyNumber_Power(o1, o2, modulo); } /* ------------------------------------------------------------------------- */ @@ -312,71 +314,119 @@ static PyObject *WraptObjectProxy_invert(WraptObjectProxyObject *self) /* ------------------------------------------------------------------------- */ -static PyObject *WraptObjectProxy_lshift(WraptObjectProxyObject *self, - PyObject *other) +static PyObject *WraptObjectProxy_lshift(PyObject *o1, PyObject *o2) { - if (!self->wrapped) { - PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised"); - return NULL; - } + if (PyObject_IsInstance(o1, (PyObject *)&WraptObjectProxy_Type)) + o1 = ((WraptObjectProxyObject *)o1)->wrapped; - return PyNumber_Lshift(self->wrapped, other); + if (PyObject_IsInstance(o2, (PyObject *)&WraptObjectProxy_Type)) + o2 = ((WraptObjectProxyObject *)o2)->wrapped; + + return PyNumber_Lshift(o1, o2); } /* ------------------------------------------------------------------------- */ -static PyObject *WraptObjectProxy_rshift(WraptObjectProxyObject *self, - PyObject *other) +static PyObject *WraptObjectProxy_rshift(PyObject *o1, PyObject *o2) { - if (!self->wrapped) { - PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised"); - return NULL; - } + if (PyObject_IsInstance(o1, (PyObject *)&WraptObjectProxy_Type)) + o1 = ((WraptObjectProxyObject *)o1)->wrapped; - return PyNumber_Rshift(self->wrapped, other); + if (PyObject_IsInstance(o2, (PyObject *)&WraptObjectProxy_Type)) + o2 = ((WraptObjectProxyObject *)o2)->wrapped; + + return PyNumber_Rshift(o1, o2); } /* ------------------------------------------------------------------------- */ -static PyObject *WraptObjectProxy_and(WraptObjectProxyObject *self, - PyObject *other) +static PyObject *WraptObjectProxy_and(PyObject *o1, PyObject *o2) { - if (!self->wrapped) { - PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised"); - return NULL; - } + if (PyObject_IsInstance(o1, (PyObject *)&WraptObjectProxy_Type)) + o1 = ((WraptObjectProxyObject *)o1)->wrapped; - return PyNumber_And(self->wrapped, other); + if (PyObject_IsInstance(o2, (PyObject *)&WraptObjectProxy_Type)) + o2 = ((WraptObjectProxyObject *)o2)->wrapped; + + return PyNumber_And(o1, o2); } /* ------------------------------------------------------------------------- */ -static PyObject *WraptObjectProxy_xor(WraptObjectProxyObject *self, - PyObject *other) +static PyObject *WraptObjectProxy_xor(PyObject *o1, PyObject *o2) { - if (!self->wrapped) { - PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised"); - return NULL; - } + if (PyObject_IsInstance(o1, (PyObject *)&WraptObjectProxy_Type)) + o1 = ((WraptObjectProxyObject *)o1)->wrapped; - return PyNumber_Xor(self->wrapped, other); + if (PyObject_IsInstance(o2, (PyObject *)&WraptObjectProxy_Type)) + o2 = ((WraptObjectProxyObject *)o2)->wrapped; + + return PyNumber_Xor(o1, o2); } /* ------------------------------------------------------------------------- */ -static PyObject *WraptObjectProxy_or(WraptObjectProxyObject *self, - PyObject *other) +static PyObject *WraptObjectProxy_or(PyObject *o1, PyObject *o2) { - if (!self->wrapped) { - PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised"); - return NULL; - } + if (PyObject_IsInstance(o1, (PyObject *)&WraptObjectProxy_Type)) + o1 = ((WraptObjectProxyObject *)o1)->wrapped; - return PyNumber_Or(self->wrapped, other); + if (PyObject_IsInstance(o2, (PyObject *)&WraptObjectProxy_Type)) + o2 = ((WraptObjectProxyObject *)o2)->wrapped; + + return PyNumber_Or(o1, o2); } /* ------------------------------------------------------------------------- */ +#if 0 +#if PY_MAJOR_VERSION < 3 +static int WraptObjectProxy_coerce(PyObject **p1, PyObject **p2) +{ + PyObject *w1 = NULL; + PyObject *w2 = NULL; + + PyObject *o1 = NULL; + PyObject *o2 = NULL; + + int result = 0; + + /* + * If we get here, then one or the other of the arguments, but + * not both, is going to be an instance of our wrapper. We have + * to unwrap which ever it is and then try the coercion again. + */ + + if (PyObject_IsInstance(*p1, (PyObject *)&WraptObjectProxy_Type)) + w1 = ((WraptObjectProxyObject *)*p1)->wrapped; + + if (PyObject_IsInstance(*p2, (PyObject *)&WraptObjectProxy_Type)) + w2 = ((WraptObjectProxyObject *)*p2)->wrapped; + + Py_XINCREF(w1); + Py_XINCREF(w2); + + o1 = w1 ? w1 : *p1; + o2 = w2 ? w2 : *p2; + + result = PyNumber_CoerceEx(&o1, &o2); + + if (result == 0) { + Py_XDECREF(w1); + Py_XDECREF(w2); + + *p1 = o1; + *p2 = o2; + } + + return result; +} +#endif +#endif + +/* ------------------------------------------------------------------------- */ + +#if PY_MAJOR_VERSION < 3 static PyObject *WraptObjectProxy_int(WraptObjectProxyObject *self) { if (!self->wrapped) { @@ -386,10 +436,10 @@ static PyObject *WraptObjectProxy_int(WraptObjectProxyObject *self) return PyNumber_Int(self->wrapped); } +#endif /* ------------------------------------------------------------------------- */ -#if PY_MAJOR_VERSION < 3 static PyObject *WraptObjectProxy_long(WraptObjectProxyObject *self) { if (!self->wrapped) { @@ -399,7 +449,6 @@ static PyObject *WraptObjectProxy_long(WraptObjectProxyObject *self) return PyNumber_Long(self->wrapped); } -#endif /* ------------------------------------------------------------------------- */ @@ -469,6 +518,9 @@ static PyObject *WraptObjectProxy_inplace_add(WraptObjectProxyObject *self, return NULL; } + if (PyObject_IsInstance(other, (PyObject *)&WraptObjectProxy_Type)) + other = ((WraptObjectProxyObject *)other)->wrapped; + return PyNumber_InPlaceAdd(self->wrapped, other); } @@ -482,6 +534,9 @@ static PyObject *WraptObjectProxy_inplace_subtract( return NULL; } + if (PyObject_IsInstance(other, (PyObject *)&WraptObjectProxy_Type)) + other = ((WraptObjectProxyObject *)other)->wrapped; + return PyNumber_InPlaceSubtract(self->wrapped, other); } @@ -495,6 +550,9 @@ static PyObject *WraptObjectProxy_inplace_multiply( return NULL; } + if (PyObject_IsInstance(other, (PyObject *)&WraptObjectProxy_Type)) + other = ((WraptObjectProxyObject *)other)->wrapped; + return PyNumber_InPlaceMultiply(self->wrapped, other); } @@ -509,6 +567,9 @@ static PyObject *WraptObjectProxy_inplace_divide( return NULL; } + if (PyObject_IsInstance(other, (PyObject *)&WraptObjectProxy_Type)) + other = ((WraptObjectProxyObject *)other)->wrapped; + return PyNumber_InPlaceDivide(self->wrapped, other); } #endif @@ -523,6 +584,9 @@ static PyObject *WraptObjectProxy_inplace_remainder( return NULL; } + if (PyObject_IsInstance(other, (PyObject *)&WraptObjectProxy_Type)) + other = ((WraptObjectProxyObject *)other)->wrapped; + return PyNumber_InPlaceRemainder(self->wrapped, other); } @@ -536,6 +600,9 @@ static PyObject *WraptObjectProxy_inplace_power(WraptObjectProxyObject *self, return NULL; } + if (PyObject_IsInstance(other, (PyObject *)&WraptObjectProxy_Type)) + other = ((WraptObjectProxyObject *)other)->wrapped; + return PyNumber_InPlacePower(self->wrapped, other, modulo); } @@ -549,6 +616,9 @@ static PyObject *WraptObjectProxy_inplace_lshift(WraptObjectProxyObject *self, return NULL; } + if (PyObject_IsInstance(other, (PyObject *)&WraptObjectProxy_Type)) + other = ((WraptObjectProxyObject *)other)->wrapped; + return PyNumber_InPlaceLshift(self->wrapped, other); } @@ -562,6 +632,9 @@ static PyObject *WraptObjectProxy_inplace_rshift(WraptObjectProxyObject *self, return NULL; } + if (PyObject_IsInstance(other, (PyObject *)&WraptObjectProxy_Type)) + other = ((WraptObjectProxyObject *)other)->wrapped; + return PyNumber_InPlaceRshift(self->wrapped, other); } @@ -575,6 +648,9 @@ static PyObject *WraptObjectProxy_inplace_and(WraptObjectProxyObject *self, return NULL; } + if (PyObject_IsInstance(other, (PyObject *)&WraptObjectProxy_Type)) + other = ((WraptObjectProxyObject *)other)->wrapped; + return PyNumber_InPlaceAnd(self->wrapped, other); } @@ -588,6 +664,9 @@ static PyObject *WraptObjectProxy_inplace_xor(WraptObjectProxyObject *self, return NULL; } + if (PyObject_IsInstance(other, (PyObject *)&WraptObjectProxy_Type)) + other = ((WraptObjectProxyObject *)other)->wrapped; + return PyNumber_InPlaceXor(self->wrapped, other); } @@ -601,33 +680,36 @@ static PyObject *WraptObjectProxy_inplace_or(WraptObjectProxyObject *self, return NULL; } + if (PyObject_IsInstance(other, (PyObject *)&WraptObjectProxy_Type)) + other = ((WraptObjectProxyObject *)other)->wrapped; + return PyNumber_InPlaceOr(self->wrapped, other); } /* ------------------------------------------------------------------------- */ -static PyObject *WraptObjectProxy_floor_divide(WraptObjectProxyObject *self, - PyObject *other) +static PyObject *WraptObjectProxy_floor_divide(PyObject *o1, PyObject *o2) { - if (!self->wrapped) { - PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised"); - return NULL; - } + if (PyObject_IsInstance(o1, (PyObject *)&WraptObjectProxy_Type)) + o1 = ((WraptObjectProxyObject *)o1)->wrapped; - return PyNumber_FloorDivide(self->wrapped, other); + if (PyObject_IsInstance(o2, (PyObject *)&WraptObjectProxy_Type)) + o2 = ((WraptObjectProxyObject *)o2)->wrapped; + + return PyNumber_FloorDivide(o1, o2); } /* ------------------------------------------------------------------------- */ -static PyObject *WraptObjectProxy_true_divide(WraptObjectProxyObject *self, - PyObject *other) +static PyObject *WraptObjectProxy_true_divide(PyObject *o1, PyObject *o2) { - if (!self->wrapped) { - PyErr_SetString(PyExc_ValueError, "wrapper has not been initialised"); - return NULL; - } + if (PyObject_IsInstance(o1, (PyObject *)&WraptObjectProxy_Type)) + o1 = ((WraptObjectProxyObject *)o1)->wrapped; - return PyNumber_TrueDivide(self->wrapped, other); + if (PyObject_IsInstance(o2, (PyObject *)&WraptObjectProxy_Type)) + o2 = ((WraptObjectProxyObject *)o2)->wrapped; + + return PyNumber_TrueDivide(o1, o2); } /* ------------------------------------------------------------------------- */ @@ -640,6 +722,9 @@ static PyObject *WraptObjectProxy_inplace_floor_divide( return NULL; } + if (PyObject_IsInstance(other, (PyObject *)&WraptObjectProxy_Type)) + other = ((WraptObjectProxyObject *)other)->wrapped; + return PyNumber_InPlaceFloorDivide(self->wrapped, other); } @@ -653,6 +738,9 @@ static PyObject *WraptObjectProxy_inplace_true_divide( return NULL; } + if (PyObject_IsInstance(other, (PyObject *)&WraptObjectProxy_Type)) + other = ((WraptObjectProxyObject *)other)->wrapped; + return PyNumber_InPlaceTrueDivide(self->wrapped, other); } @@ -993,10 +1081,11 @@ static PyNumberMethods WraptObjectProxy_as_number = { #if PY_MAJOR_VERSION < 3 0, /*nb_coerce*/ #endif - (unaryfunc)WraptObjectProxy_int, /*nb_int*/ #if PY_MAJOR_VERSION < 3 + (unaryfunc)WraptObjectProxy_int, /*nb_int*/ (unaryfunc)WraptObjectProxy_long, /*nb_long*/ #else + (unaryfunc)WraptObjectProxy_long, /*nb_int*/ 0, /*nb_long/nb_reserved*/ #endif (unaryfunc)WraptObjectProxy_float, /*nb_float*/ @@ -1070,8 +1159,12 @@ PyTypeObject WraptObjectProxy_Type = { (getattrofunc)WraptObjectProxy_getattro, /*tp_getattro*/ (setattrofunc)WraptObjectProxy_setattro, /*tp_setattro*/ 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | - Py_TPFLAGS_BASETYPE, /*tp_flags*/ +#if PY_MAJOR_VERSION < 3 + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_CHECKTYPES, /*tp_flags*/ +#else + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ +#endif 0, /*tp_doc*/ 0, /*tp_traverse*/ 0, /*tp_clear*/ @@ -1321,8 +1414,12 @@ PyTypeObject WraptFunctionWrapper_Type = { 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | - Py_TPFLAGS_BASETYPE, /*tp_flags*/ +#if PY_MAJOR_VERSION < 3 + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_CHECKTYPES, /*tp_flags*/ +#else + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ +#endif 0, /*tp_doc*/ 0, /*tp_traverse*/ 0, /*tp_clear*/ @@ -1542,8 +1639,12 @@ PyTypeObject WraptBoundFunctionWrapper_Type = { 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | - Py_TPFLAGS_BASETYPE, /*tp_flags*/ +#if PY_MAJOR_VERSION < 3 + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_CHECKTYPES, /*tp_flags*/ +#else + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ +#endif 0, /*tp_doc*/ 0, /*tp_traverse*/ 0, /*tp_clear*/ @@ -1815,8 +1916,12 @@ PyTypeObject WraptBoundMethodWrapper_Type = { 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | - Py_TPFLAGS_BASETYPE, /*tp_flags*/ +#if PY_MAJOR_VERSION < 3 + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_CHECKTYPES, /*tp_flags*/ +#else + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ +#endif 0, /*tp_doc*/ 0, /*tp_traverse*/ 0, /*tp_clear*/ diff --git a/src/wrappers.py b/src/wrappers.py index 9d0e4db..4efae1c 100644 --- a/src/wrappers.py +++ b/src/wrappers.py @@ -166,7 +166,7 @@ class ObjectProxy(six.with_metaclass(_ObjectProxyMetaType)): return self._self_wrapped ^ other def __divmod__(self, other): - return operator.__divmod__(self._self_wrapped, other) + return divmod(self._self_wrapped, other) def __pow__(self, other, *args): return pow(self._self_wrapped, other, *args) @@ -187,85 +187,96 @@ class ObjectProxy(six.with_metaclass(_ObjectProxyMetaType)): return self._self_wrapped | other def __radd__(self, other): - return operator.__radd__(self._self_wrapped, other) + return other + self._self_wrapped def __rsub__(self, other): - return operator.__rsub__(self._self_wrapped, other) + return other - self._self_wrapped def __rmul__(self, other): - return operator.__rmul__(self._self_wrapped, other) + return other * self._self_wrapped def __rdiv__(self, other): - return operator.__rdiv__(self._self_wrapped, other) + return operator.__div__(other, self._self_wrapped) def __rtruediv__(self, other): - return operator.__rtruediv__(self._self_wrapped, other) + return operator.__truediv__(other, self._self_wrapped) def __rfloordiv__(self, other): - return operator.__rfloordiv__(self._self_wrapped, other) + return other // self._self_wrapped def __rmod__(self, other): - return operator.__rmod__(self._self_wrapped, other) + return other % self._self_wrapped def __rdivmod__(self, other): - return operator.__rdivmod__(self._self_wrapped, other) + return divmod(other, self._self_wrapped) - def __rpow__(self, other): - return operator.__rpow__(self._self_wrapped, other) + def __rpow__(self, other, *args): + return pow(other, self._self_wrapped, *args) def __rlshift__(self, other): - return operator.__rlshift__(self._self_wrapped, other) + return other << self._self_wrapped def __rrshift__(self, other): - return operator.__rrshift__(self._self_wrapped, other) + return other >> self._self_wrapped def __rand__(self, other): - return operator.__rand__(self._self_wrapped, other) + return other & self._self_wrapped def __rxor__(self, other): - return operator.__rxor__(self._self_wrapped, other) + return other ^ self._self_wrapped def __ror__(self, other): - return operator.__ror__(self._self_wrapped, other) + return other | self._self_wrapped def __iadd__(self, other): self._self_wrapped += other + return self def __isub__(self, other): self._self_wrapped -= other + return self def __imul__(self, other): self._self_wrapped *= other + return self def __idiv__(self, other): - operator.__idiv__(self._self_wrapped, other) + return operator.__idiv__(self._self_wrapped, other) def __itruediv__(self, other): - operator.__itruediv__(self._self_wrapped, other) + return operator.__itruediv__(self._self_wrapped, other) def __ifloordiv__(self, other): self._self_wrapped //= other + return self def __imod__(self, other): self._self_wrapped %= other + return self - def __ipow__(self, other, *args): - self._self_wrapped.__ipow__(other, *args) + def __ipow__(self, other): + self._self_wrapped **= other + return self def __ilshift__(self, other): self._self_wrapped <<= other + return self def __irshift__(self, other): self._self_wrapped >>= other + return self def __iand__(self, other): self._self_wrapped &= other + return self def __ixor__(self, other): self._self_wrapped ^= other + return self def __ior__(self, other): self._self_wrapped |= other + return self def __neg__(self): return -self._self_wrapped diff --git a/tests/test_object_proxy.py b/tests/test_object_proxy.py index 80214e4..2b334b9 100644 --- a/tests/test_object_proxy.py +++ b/tests/test_object_proxy.py @@ -2,6 +2,10 @@ from __future__ import print_function import unittest import imp +import operator +import sys + +is_pypy = '__pypy__' in sys.builtin_module_names import wrapt @@ -729,5 +733,298 @@ class TestAsNumberObjectProxy(unittest.TestCase): self.assertTrue(not false) self.assertFalse(not true) + def test_int(self): + one = wrapt.ObjectProxy(1) + + self.assertEqual(int(one), 1) + + if not six.PY3: + self.assertEqual(long(one), 1) + + def test_float(self): + one = wrapt.ObjectProxy(1) + + self.assertEqual(float(one), 1.0) + + def test_add(self): + one = wrapt.ObjectProxy(1) + two = wrapt.ObjectProxy(2) + + self.assertEqual(one+two, 1+2) + self.assertEqual(1+two, 1+2) + self.assertEqual(one+2, 1+2) + + def test_sub(self): + one = wrapt.ObjectProxy(1) + two = wrapt.ObjectProxy(2) + + self.assertEqual(one-two, 1-2) + self.assertEqual(1-two, 1-2) + self.assertEqual(one-2, 1-2) + + def test_mul(self): + two = wrapt.ObjectProxy(2) + three = wrapt.ObjectProxy(3) + + self.assertEqual(two*three, 2*3) + self.assertEqual(2*three, 2*3) + self.assertEqual(two*3, 2*3) + + def test_div(self): + # On Python 2 this will pick up div and on Python + # 3 it will pick up truediv. + + two = wrapt.ObjectProxy(2) + three = wrapt.ObjectProxy(3) + + self.assertEqual(two/three, 2/3) + self.assertEqual(2/three, 2/3) + self.assertEqual(two/3, 2/3) + + def test_mod(self): + two = wrapt.ObjectProxy(2) + three = wrapt.ObjectProxy(3) + + self.assertEqual(three//two, 3//2) + self.assertEqual(3//two, 3//2) + self.assertEqual(three//2, 3//2) + + def test_mod(self): + two = wrapt.ObjectProxy(2) + three = wrapt.ObjectProxy(3) + + self.assertEqual(three%two, 3%2) + self.assertEqual(3%two, 3%2) + self.assertEqual(three%2, 3%2) + + def test_divmod(self): + two = wrapt.ObjectProxy(2) + three = wrapt.ObjectProxy(3) + + self.assertEqual(divmod(three, two), divmod(3, 2)) + self.assertEqual(divmod(3, two), divmod(3, 2)) + self.assertEqual(divmod(three, 2), divmod(3, 2)) + + def test_pow(self): + two = wrapt.ObjectProxy(2) + three = wrapt.ObjectProxy(3) + + self.assertEqual(three**two, pow(3, 2)) + self.assertEqual(3**two, pow(3, 2)) + self.assertEqual(three**2, pow(3, 2)) + + self.assertEqual(pow(three, two), pow(3, 2)) + self.assertEqual(pow(3, two), pow(3, 2)) + self.assertEqual(pow(three, 2), pow(3, 2)) + + # Only PyPy implements __rpow__ for ternary pow(). + + if is_pypy: + self.assertEqual(pow(three, two, 2), pow(3, 2, 2)) + self.assertEqual(pow(3, two, 2), pow(3, 2, 2)) + + self.assertEqual(pow(three, 2, 2), pow(3, 2, 2)) + + def test_lshift(self): + two = wrapt.ObjectProxy(2) + three = wrapt.ObjectProxy(3) + + self.assertEqual(three<>two, 3>>2) + self.assertEqual(3>>two, 3>>2) + self.assertEqual(three>>2, 3>>2) + + def test_and(self): + two = wrapt.ObjectProxy(2) + three = wrapt.ObjectProxy(3) + + self.assertEqual(three&two, 3&2) + self.assertEqual(3&two, 3&2) + self.assertEqual(three&2, 3&2) + + def test_xor(self): + two = wrapt.ObjectProxy(2) + three = wrapt.ObjectProxy(3) + + self.assertEqual(three^two, 3^2) + self.assertEqual(3^two, 3^2) + self.assertEqual(three^2, 3^2) + + def test_or(self): + two = wrapt.ObjectProxy(2) + three = wrapt.ObjectProxy(3) + + self.assertEqual(three|two, 3|2) + self.assertEqual(3|two, 3|2) + self.assertEqual(three|2, 3|2) + + def test_iadd(self): + value = wrapt.ObjectProxy(1) + one = wrapt.ObjectProxy(1) + + value += 1 + self.assertEqual(value, 2) + + value += one + self.assertEqual(value, 3) + + def test_isub(self): + value = wrapt.ObjectProxy(1) + one = wrapt.ObjectProxy(1) + + value -= 1 + self.assertEqual(value, 0) + + value -= one + self.assertEqual(value, -1) + + def test_imul(self): + value = wrapt.ObjectProxy(2) + two = wrapt.ObjectProxy(2) + + value *= 2 + self.assertEqual(value, 4) + + value *= two + self.assertEqual(value, 8) + + def test_idiv(self): + # On Python 2 this will pick up div and on Python + # 3 it will pick up truediv. + + value = wrapt.ObjectProxy(2) + two = wrapt.ObjectProxy(2) + + value /= 2 + self.assertEqual(value, 2/2) + + value /= two + self.assertEqual(value, 2/2/2) + + def test_ifloordiv(self): + value = wrapt.ObjectProxy(2) + two = wrapt.ObjectProxy(2) + + value //= 2 + self.assertEqual(value, 2//2) + + value //= two + self.assertEqual(value, 2//2//2) + + def test_imod(self): + value = wrapt.ObjectProxy(10) + two = wrapt.ObjectProxy(2) + + value %= 2 + self.assertEqual(value, 10%2) + + value %= two + self.assertEqual(value, 10%2%2) + + def test_ipow(self): + value = wrapt.ObjectProxy(10) + two = wrapt.ObjectProxy(2) + + value **= 2 + self.assertEqual(value, 10**2) + + value **= two + self.assertEqual(value, 10**2**2) + + def test_ilshift(self): + value = wrapt.ObjectProxy(256) + two = wrapt.ObjectProxy(2) + + value <<= 2 + self.assertEqual(value, 256<<2) + + value <<= two + self.assertEqual(value, 256<<2<<2) + + def test_irshift(self): + value = wrapt.ObjectProxy(2) + two = wrapt.ObjectProxy(2) + + value >>= 2 + self.assertEqual(value, 2>>2) + + value >>= two + self.assertEqual(value, 2>>2>>2) + + def test_iand(self): + value = wrapt.ObjectProxy(1) + two = wrapt.ObjectProxy(2) + + value &= 2 + self.assertEqual(value, 1&2) + + value &= two + self.assertEqual(value, 1&2&2) + + def test_ixor(self): + value = wrapt.ObjectProxy(1) + two = wrapt.ObjectProxy(2) + + value ^= 2 + self.assertEqual(value, 1^2) + + value ^= two + self.assertEqual(value, 1^2^2) + + def test_ior(self): + value = wrapt.ObjectProxy(1) + two = wrapt.ObjectProxy(2) + + value |= 2 + self.assertEqual(value, 1|2) + + value |= two + self.assertEqual(value, 1|2|2) + + def test_neg(self): + value = wrapt.ObjectProxy(1) + + self.assertEqual(-value, -1) + + def test_pos(self): + value = wrapt.ObjectProxy(1) + + self.assertEqual(+value, 1) + + def test_abs(self): + value = wrapt.ObjectProxy(-1) + + self.assertEqual(abs(value), 1) + + def test_invert(self): + value = wrapt.ObjectProxy(1) + + self.assertEqual(~value, ~1) + + def test_oct(self): + value = wrapt.ObjectProxy(20) + + self.assertEqual(oct(value), oct(20)) + + def test_hex(self): + value = wrapt.ObjectProxy(20) + + self.assertEqual(hex(value), hex(20)) + + def test_index(self): + value = wrapt.ObjectProxy(20) + + # PyPy doesn't implement operator.__index__(). + + if not is_pypy: + self.assertEqual(value.__index__(), operator.__index__(20)) + if __name__ == '__main__': unittest.main()