summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTres Seaver <tseaver@palladion.com>2015-05-19 15:03:58 -0400
committerTres Seaver <tseaver@palladion.com>2015-05-19 15:03:58 -0400
commitd178d29bf9b59b33ed048b44e9f06cd98d65d05a (patch)
treee09f33474d1819eb112bbd9e7c440eff9bfa3c21
parent37e9ea6ac5d00f2974490b8d68a9d6137ce5acff (diff)
parent0523a7e35ff8b358f212fb595b3c28c6436c4ad1 (diff)
downloadzope-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.py6
-rw-r--r--src/zope/proxy/_zope_proxy_proxy.c52
-rw-r--r--src/zope/proxy/tests/test_proxy.py64
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'