tags:

views:

50

answers:

1

I am writing a binding system that exposes classes and functions to python in a slightly unusual way. Normally one would create a python type and provide a list of functions that represent the methods of that type, and then allow python to use its generic tp_getattro function to select the right one. For reasons I wont go into here, I can't do it this way, and must provide my own tp_getattro function, that selects methods from elsewhere and returns my own `bound method' wrapper. This works fine, but means that a types methods are not listed in its dictionary (so dir(MyType()) doesn't show anything interesting).

The problem is that I cannot seem to get __add__ methods working. see the following sample:

>>> from mymod import Vec3
>>> v=Vec3()
>>> v.__add__
<Bound Method of a mymod Class object at 0xb754e080>
>>> v.__add__(v)
<mymod.Vec3 object at 0xb751d710>
>>> v+v
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'mymod.Vec3' and 'mymod.Vec3'

As you can see, Vec3 has an __add__ method which can be called, but python's + refuses to use it. How can I get python to use it? How does the + operator actually work in python, and what method does it use to see if you can add two arbitrary objects?

Thanks.

(P.S. I am aware of other systems such as Boost.Python and SWIG which do this automatically, and I have good reason for not using them, however wonderful they may be.)

+3  A: 

Do you have an nb_add in your type's number methods structure (pointed by field tp_as_number of your type object)?

Alex Martelli
Bingo, that did it. Somewhat annoying that it doesn't just do something like `PyObject_CallMethodObjArgs(obj1,"__add__",obj2,NULL)` if nb_add is not there. Thanks!
DaedalusFall
@DaedalusFall, it's a matter of speed -- by relying on the slots in the type object (and auxiliary ones that may be pointed from it), lookup of special methods is nearly instantaneous. In normal Python classes the slots are filled in as part of the `class` statement operation.
Alex Martelli