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&#39;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 &quot;__radd__ got: %s&quot; % 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 &quot;%s + xfloat&quot; % 
k<br>    print type(y)<br>    print y<br><br>In 2.7 this 
gives:<br><br>__radd__ got: &lt;type &#39;int&#39;&gt;<br>
int + xfloat<br>&lt;class &#39;__main__.xfloat&#39;&gt;<br>10.0<br>__radd__ 
got: &lt;type &#39;float&#39;&gt;<br>float + xfloat<br>&lt;class 
&#39;__main__.xfloat&#39;&gt;<br>10.0<br>complex + xfloat<br>&lt;type 
&#39;complex&#39;&gt;<br>
(10+1j)<br><br>In 2.6.6 I get:<br><br>__radd__ got: &lt;type 
&#39;int&#39;&gt;<br>int + xfloat<br>&lt;class 
&#39;__main__.xfloat&#39;&gt;<br>10.0<br>__radd__ got: &lt;type 
&#39;float&#39;&gt;<br>float + xfloat<br>&lt;class 
&#39;__main__.xfloat&#39;&gt;<br>
10.0<br>__radd__ got: &lt;type &#39;complex&#39;&gt;<br>complex + 
xfloat<br>&lt;type &#39;complex&#39;&gt;<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 &quot;__radd__ 
got: %s&quot; % type(lhs)<br>
        if isinstance(lhs,(int,)):<br>            return 
xint( float(self) + lhs )<br>        else:<br>            
return NotImplemented<br><br>print<br>print 
&quot;-------------------&quot;<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 &quot;%s + 
xint&quot; % k<br>    print type(y)<br>    print y<br>    <br>In 2.6.6 
I get<br><br>__radd__ got: &lt;type &#39;int&#39;&gt;<br>int + 
xint<br>&lt;class &#39;__main__.xint&#39;&gt;<br>
10<br>float + xint<br>&lt;type &#39;float&#39;&gt;<br>10.0<br>__radd__ got: 
&lt;type &#39;complex&#39;&gt;<br>complex + xint<br>&lt;type 
&#39;complex&#39;&gt;<br>(10+1j)<br><br>and in 
2.7<br><br>-------------------<br>__radd__ got: &lt;type &#39;int&#39;&gt;<br>
int + xint<br>&lt;class &#39;__main__.xint&#39;&gt;<br>10<br>float + 
xint<br>&lt;type &#39;float&#39;&gt;<br>10.0<br>complex + xint<br>&lt;type 
&#39;complex&#39;&gt;<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

Reply via email to