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.