Author: Antonio Cuni <[email protected]>
Branch:
Changeset: r58380:6272fd9c2531
Date: 2012-10-23 18:38 +0200
http://bitbucket.org/pypy/pypy/changeset/6272fd9c2531/
Log: bah, bug-to-bug compatibility to cpython about when it is allowed to
return a non complex from __complex__. This in part reverts
6d1ad31ec914, so it in part reintroduce the behaviour of
f1c048beb436. See test___complex___returning_non_complex for
details.
diff --git a/pypy/objspace/std/complextype.py b/pypy/objspace/std/complextype.py
--- a/pypy/objspace/std/complextype.py
+++ b/pypy/objspace/std/complextype.py
@@ -149,12 +149,12 @@
else:
# non-string arguments
- realval, imagval = unpackcomplex(space, w_real)
+ realval, imagval = unpackcomplex(space, w_real, strict_typing=False)
# now take w_imag into account
if not noarg2:
# complex(x, y) == x+y*j, even if 'y' is already a complex.
- realval2, imagval2 = unpackcomplex(space, w_imag)
+ realval2, imagval2 = unpackcomplex(space, w_imag,
strict_typing=False)
# try to preserve the signs of zeroes of realval and realval2
if imagval2 != 0.0:
@@ -170,7 +170,13 @@
return w_obj
-def unpackcomplex(space, w_complex):
+def unpackcomplex(space, w_complex, strict_typing=True):
+ """
+ convert w_complex into a complex and return the unwrapped (real, imag)
+ tuple. If strict_typing==True, we also typecheck the value returned by
+ __complex__ to actually be a complex (and not e.g. a float).
+ See test___complex___returning_non_complex.
+ """
from pypy.objspace.std.complexobject import W_ComplexObject
if type(w_complex) is W_ComplexObject:
return (w_complex.realval, w_complex.imagval)
@@ -194,15 +200,15 @@
if w_z is not None:
# __complex__() must return a complex or (float,int,long) object
# (XXX should not use isinstance here)
- if (space.isinstance_w(w_z, space.w_int) or
- space.isinstance_w(w_z, space.w_long) or
- space.isinstance_w(w_z, space.w_float)):
+ if not strict_typing and (space.isinstance_w(w_z, space.w_int) or
+ space.isinstance_w(w_z, space.w_long) or
+ space.isinstance_w(w_z, space.w_float)):
return (space.float_w(w_z), 0.0)
elif isinstance(w_z, W_ComplexObject):
return (w_z.realval, w_z.imagval)
raise OperationError(space.w_TypeError,
space.wrap("__complex__() must return"
- " a number"))
+ " a complex number"))
#
# no '__complex__' method, so we assume it is a float,
diff --git a/pypy/objspace/std/test/test_complexobject.py
b/pypy/objspace/std/test/test_complexobject.py
--- a/pypy/objspace/std/test/test_complexobject.py
+++ b/pypy/objspace/std/test/test_complexobject.py
@@ -250,13 +250,6 @@
assert complex(OS(1+10j), 5j) == -4+10j
assert complex(NS(1+10j), 5j) == -4+10j
- assert complex(OS(2.0)) == 2+0j
- assert complex(NS(2.0)) == 2+0j
- assert complex(OS(2)) == 2+0j
- assert complex(NS(2)) == 2+0j
- assert complex(OS(2L)) == 2+0j
- assert complex(NS(2L)) == 2+0j
-
raises(TypeError, complex, OS(None))
raises(TypeError, complex, NS(None))
@@ -363,6 +356,25 @@
assert self.almost_equal(complex(real=float2(17.), imag=float2(23.)),
17+23j)
raises(TypeError, complex, float2(None))
+ def test___complex___returning_non_complex(self):
+ import cmath
+ class Obj(object):
+ def __init__(self, value):
+ self.value = value
+ def __complex__(self):
+ return self.value
+
+ # "bug-to-bug" compatibility to CPython: complex() is more relaxed in
+ # what __complex__ can return. cmath functions really wants a complex
+ # number to be returned by __complex__.
+ assert complex(Obj(2.0)) == 2+0j
+ assert complex(Obj(2)) == 2+0j
+ assert complex(Obj(2L)) == 2+0j
+ #
+ assert cmath.polar(1) == (1.0, 0.0)
+ raises(TypeError, "cmath.polar(Obj(1))")
+
+
def test_hash(self):
for x in xrange(-30, 30):
assert hash(x) == hash(complex(x, 0))
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit