diff options
author | Tres Seaver <tseaver@palladion.com> | 2015-05-19 15:03:58 -0400 |
---|---|---|
committer | Tres Seaver <tseaver@palladion.com> | 2015-05-19 15:03:58 -0400 |
commit | d178d29bf9b59b33ed048b44e9f06cd98d65d05a (patch) | |
tree | e09f33474d1819eb112bbd9e7c440eff9bfa3c21 | |
parent | 37e9ea6ac5d00f2974490b8d68a9d6137ce5acff (diff) | |
parent | 0523a7e35ff8b358f212fb595b3c28c6436c4ad1 (diff) | |
download | zope-proxy-d178d29bf9b59b33ed048b44e9f06cd98d65d05a.tar.gz |
Merge branch 'int-and-float' of git://github.com/NextThought/zope.proxy into NextThought-int-and-float
-rw-r--r-- | src/zope/proxy/_compat.py | 6 | ||||
-rw-r--r-- | src/zope/proxy/_zope_proxy_proxy.c | 52 | ||||
-rw-r--r-- | src/zope/proxy/tests/test_proxy.py | 64 |
3 files changed, 94 insertions, 28 deletions
diff --git a/src/zope/proxy/_compat.py b/src/zope/proxy/_compat.py index be8d867..4b9ed15 100644 --- a/src/zope/proxy/_compat.py +++ b/src/zope/proxy/_compat.py @@ -2,3 +2,9 @@ import sys PY3 = sys.version_info[0] >= 3 +if PY3: # pragma NO COVER + def _u(s): + return s +else: + def _u(s): + return unicode(s, 'unicode_escape') diff --git a/src/zope/proxy/_zope_proxy_proxy.c b/src/zope/proxy/_zope_proxy_proxy.c index 9166976..0df67b6 100644 --- a/src/zope/proxy/_zope_proxy_proxy.c +++ b/src/zope/proxy/_zope_proxy_proxy.c @@ -420,26 +420,18 @@ wrap_call(PyObject *self, PyObject *args, PyObject *kw) static PyObject * call_int(PyObject *self) { - PyNumberMethods *nb = self->ob_type->tp_as_number; - if (nb == NULL || nb->nb_int == NULL) { - PyErr_SetString(PyExc_TypeError, - "object can't be converted to int"); - return NULL; - } - return nb->nb_int(self); +#if PY_MAJOR_VERSION < 3 + return PyNumber_Int(self); +#else + return PyNumber_Long(self); +#endif } #if PY_MAJOR_VERSION < 3 // Python 3 has no long, oct or hex methods. static PyObject * call_long(PyObject *self) { - PyNumberMethods *nb = self->ob_type->tp_as_number; - if (nb == NULL || nb->nb_long == NULL) { - PyErr_SetString(PyExc_TypeError, - "object can't be converted to long"); - return NULL; - } - return nb->nb_long(self); + return PyNumber_Long(self); } static PyObject * @@ -471,25 +463,13 @@ call_hex(PyObject *self) static PyObject * call_index(PyObject *self) { - PyNumberMethods *nb = self->ob_type->tp_as_number; - if (nb == NULL || nb->nb_index == NULL) { - PyErr_SetString(PyExc_TypeError, - "object can't be converted to index"); - return NULL; - } - return nb->nb_index(self); + return PyNumber_Index(self); } static PyObject * call_float(PyObject *self) { - PyNumberMethods *nb = self->ob_type->tp_as_number; - if (nb == NULL || nb->nb_float== NULL) { - PyErr_SetString(PyExc_TypeError, - "object can't be converted to float"); - return NULL; - } - return nb->nb_float(self); + return PyNumber_Float(self); } static PyObject * @@ -499,6 +479,15 @@ call_ipow(PyObject *self, PyObject *other) return PyNumber_InPlacePower(self, other, Py_None); } +#if PY_MAJOR_VERSION < 3 +static PyObject * +call_unicode(PyObject *self) +{ + return PyObject_Unicode(self); +} +#endif + + typedef PyObject *(*function1)(PyObject *); static PyObject * @@ -691,6 +680,10 @@ INPLACE(floordiv, PyNumber_InPlaceFloorDivide) INPLACE(truediv, PyNumber_InPlaceTrueDivide) UNOP(index, call_index) +#if PY_MAJOR_VERSION < 3 // Python 3 has no __unicode__ method +UNOP(unicode, call_unicode) +#endif + static int wrap_nonzero(PyObject *self) { @@ -874,6 +867,9 @@ wrap_as_mapping = { static PyMethodDef wrap_methods[] = { {"__reduce__", (PyCFunction)wrap_reduce, METH_NOARGS, reduce__doc__}, +#if PY_MAJOR_VERSION < 3 + {"__unicode__", (PyCFunction)wrap_unicode, METH_NOARGS, "" }, +#endif {NULL, NULL}, }; diff --git a/src/zope/proxy/tests/test_proxy.py b/src/zope/proxy/tests/test_proxy.py index aa8088f..5622104 100644 --- a/src/zope/proxy/tests/test_proxy.py +++ b/src/zope/proxy/tests/test_proxy.py @@ -75,6 +75,70 @@ class PyProxyBaseTestCase(unittest.TestCase): proxy = MyProxy3('notused') self.assertEqual(list(proxy), list('another')) + def test_string_to_int(self): + # Strings don't have the tp_number.tp_int pointer + proxy = self._makeOne("14") + self.assertEqual(14, int(proxy)) + + def test_custom_int_to_int(self): + class CustomClass(object): + def __int__(self): + return 42 + proxy = self._makeOne(CustomClass()) + self.assertEqual(42, int(proxy)) + + def test_string_to_float(self): + proxy = self._makeOne("14") + self.assertEqual(float("14"), float(proxy)) + + def test_incorrect_string_to_int(self): + proxy = self._makeOne("") + self.assertRaises(ValueError, int, proxy) + + def test_incorrect_string_to_float(self): + proxy = self._makeOne("") + self.assertRaises(ValueError, float, proxy) + + def test_custom_float_to_float(self): + class CustomClass(object): + def __float__(self): + return 42.0 + proxy = self._makeOne(CustomClass()) + self.assertEqual(42.0, float(proxy)) + + def test___unicode__of_unicode(self): + from zope.proxy._compat import PY3, _u + if PY3: # Gone in Python 3: + return + s = _u('Hello, \u2603') + proxy = self._makeOne(s) + self.assertEqual(unicode(proxy), s) + + def test___unicode__of_custom_class(self): + from zope.proxy._compat import PY3, _u + if PY3: # Gone in Python 3: + return + class CustomClass(object): + def __unicode__(self): + return _u('Hello, \u2603') + cc = CustomClass() + self.assertEqual(unicode(cc), _u('Hello, \u2603')) + proxy = self._makeOne(cc) + self.assertEqual(unicode(proxy), _u('Hello, \u2603')) + + def test___unicode__of_custom_class_no_unicode(self): + # The default behaviour should be preserved + from zope.proxy._compat import PY3, _u + if PY3: # Gone in Python 3: + return + class CustomClass(object): + pass + cc = CustomClass() + cc_unicode = unicode(cc) + self.assertEqual(type(cc_unicode), unicode) + proxy = self._makeOne(cc) + self.assertEqual(unicode(proxy), cc_unicode) + def test___call__(self): def _foo(): return 'FOO' |