Python reverse operators (like __radd__) are not working with 'swig -builtin'
Closed this issue · 2 comments
Description
Python allows to overload operators in normal and reverse fashion.
Given, x=dc.arange(5)
, y=x+1
calls dnnc tensor operator+ (aka __add__ operator), whereas y=1+x
calls dnnc tensor reverse operator + (aka __radd__ operator).
If you compile with swig -builtin
OR make FAST_SWIG=n
for performance reasons, reverse operators stop working.
How to Reproduce
Script: bug.py
import dnnc as dc
x=dc.arange(4)
y=x+1; # works
y=1+x; # fails with swig -builtin
print("PASS :-)")
% make clean; make
% python bug.py
Traceback (most recent call last):
File "bug.py", line 5, in <module>
y=1+x; #fails with swig -builtin
TypeError: unsupported operand type(s) for +: 'int' and 'dnnc.fTensor'
% make clean ; make FAST_SWIG=n
% python bug.py
PASS :-)
Swig doesn't support __radd__
if you are using -bulitin
Mentioned here, SWIG (Python builtin limitations)
Reverse binary operators (e.g., radd) are not supported.
To illustrate this point, if you have a wrapped class called MyString, and you want to use instances of MyString interchangeably with native python strings, you can define an 'operator+ (const char*)' method :
class MyString {
public:
MyString (const char *init);
MyString operator+ (const char *other) const;
...
};
SWIG will automatically create an operator overload in python that will allow this:
from MyModule import MyString
mystr = MyString("No one expects")
episode = mystr + " the Spanish Inquisition"
This works because the first operand (mystr) defines a way to add a native string to itself. However, the following will not work:
from MyModule import MyString
mystr = MyString("Parrot")
episode = "Dead " + mystr
The above code fails, because the first operand -- a native python string -- doesn't know how to add an instance of MyString to itself.