Commit d178d29b authored by Tres Seaver's avatar Tres Seaver

Merge branch 'int-and-float' of git://github.com/NextThought/zope.proxy into...

Merge branch 'int-and-float' of git://github.com/NextThought/zope.proxy into NextThought-int-and-float
parents 37e9ea6a 0523a7e3
...@@ -2,3 +2,9 @@ import sys ...@@ -2,3 +2,9 @@ import sys
PY3 = sys.version_info[0] >= 3 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')
...@@ -420,26 +420,18 @@ wrap_call(PyObject *self, PyObject *args, PyObject *kw) ...@@ -420,26 +420,18 @@ wrap_call(PyObject *self, PyObject *args, PyObject *kw)
static PyObject * static PyObject *
call_int(PyObject *self) call_int(PyObject *self)
{ {
PyNumberMethods *nb = self->ob_type->tp_as_number; #if PY_MAJOR_VERSION < 3
if (nb == NULL || nb->nb_int == NULL) { return PyNumber_Int(self);
PyErr_SetString(PyExc_TypeError, #else
"object can't be converted to int"); return PyNumber_Long(self);
return NULL; #endif
}
return nb->nb_int(self);
} }
#if PY_MAJOR_VERSION < 3 // Python 3 has no long, oct or hex methods. #if PY_MAJOR_VERSION < 3 // Python 3 has no long, oct or hex methods.
static PyObject * static PyObject *
call_long(PyObject *self) call_long(PyObject *self)
{ {
PyNumberMethods *nb = self->ob_type->tp_as_number; return PyNumber_Long(self);
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);
} }
static PyObject * static PyObject *
...@@ -471,25 +463,13 @@ call_hex(PyObject *self) ...@@ -471,25 +463,13 @@ call_hex(PyObject *self)
static PyObject * static PyObject *
call_index(PyObject *self) call_index(PyObject *self)
{ {
PyNumberMethods *nb = self->ob_type->tp_as_number; return PyNumber_Index(self);
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);
} }
static PyObject * static PyObject *
call_float(PyObject *self) call_float(PyObject *self)
{ {
PyNumberMethods *nb = self->ob_type->tp_as_number; return PyNumber_Float(self);
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);
} }
static PyObject * static PyObject *
...@@ -499,6 +479,15 @@ call_ipow(PyObject *self, PyObject *other) ...@@ -499,6 +479,15 @@ call_ipow(PyObject *self, PyObject *other)
return PyNumber_InPlacePower(self, other, Py_None); 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 *); typedef PyObject *(*function1)(PyObject *);
static PyObject * static PyObject *
...@@ -691,6 +680,10 @@ INPLACE(floordiv, PyNumber_InPlaceFloorDivide) ...@@ -691,6 +680,10 @@ INPLACE(floordiv, PyNumber_InPlaceFloorDivide)
INPLACE(truediv, PyNumber_InPlaceTrueDivide) INPLACE(truediv, PyNumber_InPlaceTrueDivide)
UNOP(index, call_index) UNOP(index, call_index)
#if PY_MAJOR_VERSION < 3 // Python 3 has no __unicode__ method
UNOP(unicode, call_unicode)
#endif
static int static int
wrap_nonzero(PyObject *self) wrap_nonzero(PyObject *self)
{ {
...@@ -874,6 +867,9 @@ wrap_as_mapping = { ...@@ -874,6 +867,9 @@ wrap_as_mapping = {
static PyMethodDef static PyMethodDef
wrap_methods[] = { wrap_methods[] = {
{"__reduce__", (PyCFunction)wrap_reduce, METH_NOARGS, reduce__doc__}, {"__reduce__", (PyCFunction)wrap_reduce, METH_NOARGS, reduce__doc__},
#if PY_MAJOR_VERSION < 3
{"__unicode__", (PyCFunction)wrap_unicode, METH_NOARGS, "" },
#endif
{NULL, NULL}, {NULL, NULL},
}; };
......
...@@ -75,6 +75,70 @@ class PyProxyBaseTestCase(unittest.TestCase): ...@@ -75,6 +75,70 @@ class PyProxyBaseTestCase(unittest.TestCase):
proxy = MyProxy3('notused') proxy = MyProxy3('notused')
self.assertEqual(list(proxy), list('another')) 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 test___call__(self):
def _foo(): def _foo():
return 'FOO' return 'FOO'
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment