Homunculus Reticulli
Homunculus Reticulli

Reputation: 68426

Python C extension using SWIG (adding magic methods using %pythoncode keyword)

I am using SWIG to generate a C extension Python library. I have a C datatype which is essentially a sequence type which maps (conceptually) to the list data type in Python.

I have generated the extension using SWIG, but now, want to improve the SWIG interface so that code written using the library, is more Pythonic.

I am using the %pythoncode keyword in my interface file, in order to add some Python magic functions like __getitem__ etc.

Here is the relevant section of my SWIG interface file:

%pythoncode %{
    def __getitem__(self, key):
        if not isinstance(key, int ):
            raise TypeError('Index value must be integer')
        else:
            datasize = self.size()
            if (key > -1) and (key < datasize):
                return self.getItem(key)
            else:
                raise IndexError('Index out of array bounds')

    def __setitem__(self, key, value):
        if not isinstance(key, int ):
            raise TypeError('Index value must be integer')
        else:
            if not isinstance(value, double) and not isinstance(value, int):
                raise TypeError('Value must be a number')
            else:
                datasize = self.size()
                if (key > -1) and (key < datasize):
                    return self.setItem(key, value)
                else:
                    raise IndexError('Index out of array bounds')


    def __iter__(self):
        return self

    def next(iterator):
        raise StopIteration()
%}

I compile and successfully import the library on Python.

import mylib
temp = mylib.MySequenceDataType(10)
temp[0] = 42

However, when I attempt to assign a value to my sequence data type as shown above, I get the following error:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "myextlib.py", line 195, in __getitem__
    datasize = self.size()
  File "myextlib.py", line 151, in <lambda>
    __getattr__ = lambda self, name: _swig_getattr(self, MySequenceDataType, name)
  File "myextlib.py", line 55, in _swig_getattr
    raise AttributeError(name)
AttributeError: size

How do I fix this?. Those with a sharp eye will also spot that my current implementations for iterations do not work. I would appreciate pointers/help on geting that to work as well.

Upvotes: 3

Views: 875

Answers (1)

cdiggins
cdiggins

Reputation: 18203

The error seems to be at:

else:
   datasize = self.size()

The error indicates you have not defined an attribute named size().

Have you considered implementing the functions __getitem__, __setitem__, __len__ in the C++ and then letting them get exposed to Python? You can use the %extend directive in SWIG for this purpose.

Upvotes: 1

Related Questions