Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I make dir(obj) return non-function members in swig generated python classes?

Tags:

python

swig

I'm using swig to generate python wrapper for a C++ library. I tend to use the generated python module in an interactive manner using ipython.

Say I have the following C++ class:

class test
{
    int num;
    int foo();
};

Swig wraps this class with a python class:

class test:
    def foo():...
    __swig_getmethods__["num"] = ...
    __swig_setmethods__["num"] = ...
    .
    .
    .

When using interactively with ipython. I have noticed that tab completions will successfully find "foo", but not "num".

After a little digging, I saw that ipython uses the "dir" method for tab completion. The way swig generates non-function class members is by implementing __setattr__ and __getattr__. All they do is check the __swig_set/getmethods__ dictionaries and return the value, if found. This is why members like "num" are not returned when trying dir(test).

Ideally, it would be nice if swig could implement __dir__, for each of its classes. Something like this could be added to every swig wrapper class:

# Merge the two method dictionaries, and get the keys
__swig_dir__ = dict(__swig_getmethods__.items() + __swig_setmethods__.items()).keys()
# Implement __dir__() to return it plus all of the other members
def __dir__(self):
    return __dict__.keys() + __swig_dir__ 

My questions:

  1. Is there an easy way to get the dir() function to return the non-function members as well?
  2. If the answer to 1 is no, is there an easy way to add the above code in every python class that swig generates?

I know this is a minor thing, but tab completion has a very positive effect on productivity in my opinion.

Thanks

like image 302
Nir Avatar asked Apr 26 '26 22:04

Nir


1 Answers

IPython wraps dir in a new function dir2 inside IPython/core/completer.py

So you could try to redefine dir2. Something like:

import IPython.core.completer
old_dir = IPython.core.completer.dir2

def my_dir(obj):
    methods = old_dir(obj)
    #merge your swig methods in
    return methods

IPython.core.completer.dir2 = my_dir
like image 149
Hans Then Avatar answered Apr 28 '26 13:04

Hans Then



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!