subclassing complex

B

BiDi

I have been trying to subclass complex, but I am not able to get the
right-hand arithmetic operators working.

As shown below, if an object of my subclass 'xcomplex' is added on the
right of a 'comlex' object, the type returned is 'complex', not
'xcomplex'.

I've tried subclassing float and it works fine (don't even need to
define __coerce__ in that case)

Is this a bug, or am I missing something?

Here's an example:

class xcomplex( complex ):

def __new__(cls,*args,**kwargs):
return complex.__new__(cls,*args,**kwargs)

def __coerce__(self,other):
t = complex.__coerce__(self,other)
try:
return (self,xcomplex(t[1]))
except TypeError:
return t

def __add__(self,x):
return xcomplex( complex.__add__(self,x) )

def __radd__(self,x):
return xcomplex( complex.__radd__(self,x) )


xz = xcomplex(1+2j)
xy = float(10.0)
z = complex(10+1j)

print type(xz + z) # OK: get xcomplex
print type(xz + xy) # OK: get xcomplex
print type(xz + 10) # OK: get xcomplex
print type(xy + xz) # OK: get xcomplex
print type(10 + xz) # OK: get xcomplex

print type(z + xz) # fails: get complex
 
P

Patrick Maupin

I have been trying to subclass complex, but I am not able to get the
right-hand arithmetic operators working.

As shown below, if an object of my subclass 'xcomplex' is added on the
right of a 'comlex' object, the type returned is 'complex', not
'xcomplex'.

I've tried subclassing float and it works fine (don't even need to
define __coerce__ in that case)

Is this a bug, or am I missing something?

I think the issue is that Python first tries to use the __add__ method
of the left-most object, and only attempts to use __radd__ with the
right-most object if that fails. Because you have subclassed the
complex class, the __add__ method of the complex number will work
fine, returning a complex result.

If you want to keep that from working, you probably want to just
inherit from 'object' rather than 'complex', and reimplement all the
methods you care about (possibly with a very simple wrapper around an
internal complex number).

Regards,
Pat
 
P

Peter Otten

BiDi said:
I have been trying to subclass complex, but I am not able to get the
right-hand arithmetic operators working.

As shown below, if an object of my subclass 'xcomplex' is added on the
right of a 'comlex' object, the type returned is 'complex', not
'xcomplex'.

I've tried subclassing float and it works fine (don't even need to
define __coerce__ in that case)

Is this a bug, or am I missing something?

A minimal example is
.... def __radd__(self, other): print "radd"
....
1j

versus
.... def __radd__(self, other): print "radd"
....radd

I think the complex subclass should behave like the int subclass.
To get an authoritative answer you should file a bug report.

Peter
 
P

Patrick Maupin

A minimal example is


... def __radd__(self, other): print "radd"
...>>> 1j + Complex()

1j

versus


... def __radd__(self, other): print "radd"
...>>> 1 + Int()

radd

I think the complex subclass should behave like the int subclass.
To get an authoritative answer you should file a bug report.


Hmm, good point. I shouldn't look at newsgroups when I'm too tired to
see the whole problem.

According to the documentation at http://docs.python.org/ref/numeric-types.html:

"Note: If the right operand's type is a subclass of the left operand's
type and that subclass provides the reflected method for the
operation, this method will be called before the left operand's non-
reflected method. This behavior allows subclasses to override their
ancestors' operations."

I think this makes it pretty clear that the OP found a bug in how
complex works. (Before I read this note, I would have assumed that
the int() handling was broken, but it looks like a supportable design
decision. Probably whoever implemented it wasn't even thinking about
complex numbers, but for consistency, I would think they should be
made to work the same.)

Regards,
Pat
 
B

BiDi

Hmm, good point.  I shouldn't look at newsgroups when I'm too tired to
see the whole problem.

According to the documentation athttp://docs.python.org/ref/numeric-types..html:

"Note: If the right operand's type is a subclass of the left operand's
type and that subclass provides the reflected method for the
operation, this method will be called before the left operand's non-
reflected method. This behavior allows subclasses to override their
ancestors' operations."

I think this makes it pretty clear that the OP found a bug in how
complex works.  (Before I read this note, I would have assumed that
the int() handling was broken, but it looks like a supportable design
decision.  Probably whoever implemented it wasn't even thinking about
complex numbers, but for consistency, I would think they should be
made to work the same.)

Regards,
Pat

Thanks for the comments. I have filed it as an issue.

Regards

Blair
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,994
Messages
2,570,223
Members
46,813
Latest member
lawrwtwinkle111

Latest Threads

Top