Blair <bidih...@gmail.com> added the comment:
I'd like to add a few more observations to the mix.
I have run the following in both 2.6.6 and in 2.7
class xfloat(float):
def __new__(cls,x):
return float.__new__(cls,x)
def __radd__(self,lhs):
print "__radd__ got: %s" % type(lhs)
if isinstance(lhs,(int,float)):
return xfloat( float(self) + lhs )
else:
return NotImplemented
xf = xfloat(9.0)
cases = dict(int=1,float=1.0,complex=1.0+1j)
for k,v in cases.items():
y = v + xf
print "%s + xfloat" % k
print type(y)
print y
In 2.7 this gives:
__radd__ got: <type 'int'>
int + xfloat
<class '__main__.xfloat'>
10.0
__radd__ got: <type 'float'>
float + xfloat
<class '__main__.xfloat'>
10.0
complex + xfloat
<type 'complex'>
(10+1j)
In 2.6.6 I get:
__radd__ got: <type 'int'>
int + xfloat
<class '__main__.xfloat'>
10.0
__radd__ got: <type 'float'>
float + xfloat
<class '__main__.xfloat'>
10.0
__radd__ got: <type 'complex'>
complex + xfloat
<type 'complex'>
(10+1j)
They are the same except for the last case.
My feeling is that the behaviour of 2.6.6 (for subclassing float) is
correct.
The behaviour of 2.6.6 is needed to enable you to implement the commutative
property of addition (ie, you expect to get the same outcome from x+y or
y+x), which I would say is a pretty fundamental requirement.
I have also tried the following
class xint(int):
def __new__(cls,x):
return int.__new__(cls,x)
def __radd__(self,lhs):
print "__radd__ got: %s" % type(lhs)
if isinstance(lhs,(int,)):
return xint( float(self) + lhs )
else:
return NotImplemented
print
print "-------------------"
xf = xint(9)
cases = dict(int=1,float=1.0,complex=1.0+1j)
for k,v in cases.items():
y = v + xf
print "%s + xint" % k
print type(y)
print y
In 2.6.6 I get
__radd__ got: <type 'int'>
int + xint
<class '__main__.xint'>
10
float + xint
<type 'float'>
10.0
__radd__ got: <type 'complex'>
complex + xint
<type 'complex'>
(10+1j)
and in 2.7
-------------------
__radd__ got: <type 'int'>
int + xint
<class '__main__.xint'>
10
float + xint
<type 'float'>
10.0
complex + xint
<type 'complex'>
(10+1j)
In my opinion, 2.6.6 was faulty in the float + xint case, for the same
reasons as above, and 2.7 is faulty in both float + xint and complex + xint.
----------
Added file: http://bugs.python.org/file19832/unnamed
_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue5211>
_______________________________________
I'd like to add a few more observations to the mix.<br><br>I have run the
following in both 2.6.6 and in 2.7<br><br>class xfloat(float):<br>Â Â Â def
__new__(cls,x):<br>Â Â Â Â Â Â Â return float.__new__(cls,x)<br><br>Â Â Â def
__radd__(self,lhs):<br>
       print "__radd__ got: %s" % type(lhs)<br>      Â
if isinstance(lhs,(int,float)):<br>Â Â Â Â Â Â Â Â Â Â Â return xfloat(
float(self) + lhs )<br>Â Â Â Â Â Â Â else:<br>Â Â Â Â Â Â Â Â Â Â Â return
NotImplemented<br><br><br>xf = xfloat(9.0)<br>
<br>cases = dict(int=1,float=1.0,complex=1.0+1j)<br>for k,v in
cases.items():<br>Â Â Â y = v + xf<br>Â Â Â print "%s + xfloat" %
k<br>Â Â Â print type(y)<br>Â Â Â print y<br><br>In 2.7 this
gives:<br><br>__radd__ got: <type 'int'><br>
int + xfloat<br><class '__main__.xfloat'><br>10.0<br>__radd__
got: <type 'float'><br>float + xfloat<br><class
'__main__.xfloat'><br>10.0<br>complex + xfloat<br><type
'complex'><br>
(10+1j)<br><br>In 2.6.6 I get:<br><br>__radd__ got: <type
'int'><br>int + xfloat<br><class
'__main__.xfloat'><br>10.0<br>__radd__ got: <type
'float'><br>float + xfloat<br><class
'__main__.xfloat'><br>
10.0<br>__radd__ got: <type 'complex'><br>complex +
xfloat<br><type 'complex'><br>(10+1j)<br><br>They are the same
except for the last case.<br><br>My feeling is that the behaviour of 2.6.6 (for
subclassing float) is correct.<br>
<br>The behaviour of 2.6.6 is needed to enable you to implement the commutative
property of addition (ie, you expect to get the same outcome from x+y or y+x),
which I would say is a pretty fundamental requirement.<br><br>
I have also tried the following<br><br>class xint(int):<br>Â Â Â def
__new__(cls,x):<br>Â Â Â Â Â Â Â return int.__new__(cls,x)Â Â Â Â Â Â Â
<br><br>Â Â Â def __radd__(self,lhs):<br>Â Â Â Â Â Â Â print "__radd__
got: %s" % type(lhs)<br>
       if isinstance(lhs,(int,)):<br>           return
xint( float(self) + lhs )<br>Â Â Â Â Â Â Â else:<br>Â Â Â Â Â Â Â Â Â Â Â
return NotImplemented<br><br>print<br>print
"-------------------"<br>xf = xint(9)<br><br>cases =
dict(int=1,float=1.0,complex=1.0+1j)<br>
for k,v in cases.items():<br>Â Â Â y = v + xf<br>Â Â Â print "%s +
xint" % k<br>Â Â Â print type(y)<br>Â Â Â print y<br>Â Â Â <br>In 2.6.6
I get<br><br>__radd__ got: <type 'int'><br>int +
xint<br><class '__main__.xint'><br>
10<br>float + xint<br><type 'float'><br>10.0<br>__radd__ got:
<type 'complex'><br>complex + xint<br><type
'complex'><br>(10+1j)<br><br>and in
2.7<br><br>-------------------<br>__radd__ got: <type 'int'><br>
int + xint<br><class '__main__.xint'><br>10<br>float +
xint<br><type 'float'><br>10.0<br>complex + xint<br><type
'complex'><br>(10+1j)<br><br>In my opinion, 2.6.6 was faulty in the
float + xint case, for the same reasons as above, and 2.7 is faulty in both
float + xint and complex + xint.<br>
<br>
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com