Exposing arbitrary methods names in a python class for an IDE to read

24 views Asked by At

The situation is this. Suppose you

from nastymodule import NastyObject1, NastyObject2, NastyObject3

and this NastyObject's under the hood have a weird implementation that does not cleanly expose its methods due to an inextricable maze of interfaces (COM, dll calls and the likes), so the IDE is not able to suggest them. From the documentation, you read that NastyObject1 has a method do_thing, NastyObject2 has a method do_other_thing, and in fact

NO1 = NastyObject1()
res = NO1.do_thing()
NO2 = NastyObject2()
res = NO2.do_other_thing()

perfectly works as documented. The only problem is that, as I said, the IDE does not know, due to the obscure implementation, of this method do_thing, or any other methods of that class. Now, for reasons I have to write a unique NstObjWrapper class for all these NastyObject's, capable of dynamically exposing these methods.

Keep in mind that I already wrote NstObjWrapper's __getattr__, so that

NOW1 = NstObjWrapper('NastyObject1')
res = NOW1.do_thing()
NOW2 = NstObjWrapper('NastyObject2')
res = NOW2.do_other_thing()

already works; I only need to find a way to dynamically make IDEs (and any kind of class inspectors) aware that NOW1 has a do_thing method and NOW2 has a do_other_thing method.

NstObjWrapper can be, if necessary, informed of the methods of the NastyObject's through an exhaustive, hardcoded dict:

methods_dict = {'NastyObject1': ['do_thing', ......]
                'NastyObject2': ['do_other_thing', .......]
                'NastyObject3': [.......]}

But since the class has to be able to wrap all the objects, that all have different methods, you cannot just define methods with the same name, and then calling the wrapped NastyObject's methods.

Is this possible? How would you do it?

1

There are 1 answers

1
Rohi On

A pretty simple way to solve this would be to the following :

class my_class_func():
    def do_thing():
        pass
    def func2():
        pass
    def func3():
        pass
    def func4():
        pass

With each func corresponding to one of the funcs you want, and then telling the IDE your class created is of type of that specific class, as following :

NOW1 = NstObjWrapper('NastyObject1') # type: my_class_func
res = NOW1.do_thing()

You would get auto-complete, since the way we wrote the "type" comment is according to pep convention.

Either way I am not sure this is the best way to go.