[pypy-commit] pypy default: Call __int__ or __float__ on item assignment in some cases. Fixes test_assign_object_with_special_methods from 6e2656749ce4
hakanardo
noreply at buildbot.pypy.org
Fri Aug 16 09:56:22 CEST 2013
Author: Hakan Ardo <hakan at debian.org>
Branch:
Changeset: r66171:2abb5e5f6bdf
Date: 2013-08-16 09:55 +0200
http://bitbucket.org/pypy/pypy/changeset/2abb5e5f6bdf/
Log: Call __int__ or __float__ on item assignment in some cases. Fixes
test_assign_object_with_special_methods from 6e2656749ce4
diff --git a/pypy/module/array/interp_array.py b/pypy/module/array/interp_array.py
--- a/pypy/module/array/interp_array.py
+++ b/pypy/module/array/interp_array.py
@@ -11,7 +11,7 @@
from rpython.rlib.unroll import unrolling_iterable
from rpython.rlib.objectmodel import keepalive_until_here
from rpython.rtyper.lltypesystem import lltype, rffi
-
+from pypy.objspace.std.floatobject import W_FloatObject
@unwrap_spec(typecode=str)
def w_array(space, w_cls, typecode, __args__):
@@ -532,7 +532,7 @@
class TypeCode(object):
- def __init__(self, itemtype, unwrap, canoverflow=False, signed=False):
+ def __init__(self, itemtype, unwrap, canoverflow=False, signed=False, method='__int__'):
self.itemtype = itemtype
self.bytes = rffi.sizeof(itemtype)
self.arraytype = lltype.Array(itemtype, hints={'nolength': True})
@@ -540,6 +540,7 @@
self.signed = signed
self.canoverflow = canoverflow
self.w_class = None
+ self.method = method
if self.canoverflow:
assert self.bytes <= rffi.sizeof(rffi.ULONG)
@@ -554,8 +555,8 @@
return True
types = {
- 'c': TypeCode(lltype.Char, 'str_w'),
- 'u': TypeCode(lltype.UniChar, 'unicode_w'),
+ 'c': TypeCode(lltype.Char, 'str_w', method=''),
+ 'u': TypeCode(lltype.UniChar, 'unicode_w', method=''),
'b': TypeCode(rffi.SIGNEDCHAR, 'int_w', True, True),
'B': TypeCode(rffi.UCHAR, 'int_w', True),
'h': TypeCode(rffi.SHORT, 'int_w', True, True),
@@ -567,8 +568,8 @@
# rbigint.touint() which
# corresponds to the
# C-type unsigned long
- 'f': TypeCode(lltype.SingleFloat, 'float_w'),
- 'd': TypeCode(lltype.Float, 'float_w'),
+ 'f': TypeCode(lltype.SingleFloat, 'float_w', method='__float__'),
+ 'd': TypeCode(lltype.Float, 'float_w', method='__float__'),
}
for k, v in types.items():
v.typecode = k
@@ -613,7 +614,19 @@
def item_w(self, w_item):
space = self.space
unwrap = getattr(space, mytype.unwrap)
- item = unwrap(w_item)
+ try:
+ item = unwrap(w_item)
+ except OperationError, e:
+ if isinstance(w_item, W_FloatObject): # Odd special case from cpython
+ raise
+ if mytype.method != '' and e.match(space, space.w_TypeError):
+ try:
+ item = unwrap(space.call_method(w_item, mytype.method))
+ except OperationError:
+ msg = 'array item must be ' + mytype.unwrap[:-2]
+ raise OperationError(space.w_TypeError, space.wrap(msg))
+ else:
+ raise
if mytype.unwrap == 'bigint_w':
try:
item = item.touint()
diff --git a/pypy/module/array/test/test_array.py b/pypy/module/array/test/test_array.py
--- a/pypy/module/array/test/test_array.py
+++ b/pypy/module/array/test/test_array.py
@@ -937,6 +937,13 @@
raises(TypeError, a.__setitem__, Silly())
raises(TypeError, a.__setitem__, OldSilly())
+ a = array('c', 'hi')
+ a[0] = 'b'
+ assert a[0] == 'b'
+
+ a = array('u', u'hi')
+ a[0] = u'b'
+ assert a[0] == u'b'
class TestCPythonsOwnArray(BaseArrayTests):
More information about the pypy-commit
mailing list