Hello David, It look like you're trying to create a brain for astroid. Here's a recent example for signal directly in astroid recently : https://github.com/PyCQA/astroid/pull/1172/files
Hope this helps :) Le mar. 5 oct. 2021 à 14:26, David Rajaratnam <da...@gemarex.com.au> a écrit : > Hi all, > > I'm trying to write a transform plugin to better work with a library that > I maintain. For background my library extends a third-party library and > uses some dynamic typing to add new features and wrappers on top of the > third-party library. Because it uses dynamically created classes pylint > complains about having missing members (E1101) and unexpected keyword > arguments in the constructor (E1123). > > The class that is being dynamically generated only gets generated once > when the module is imported and provides a proxy/wrapper around an existing > class from the third-party library. The wrapper mirrors the member > functions from the original class, as well as overriding and adding some > new member functions. So the structure is something like: > > > tpmodule.py > > # third-party library > > class Control: > .... > > > mymodule.py > > # my library > > import tpmodule > > def _make_wrapper(towrap): > .... # dynamically create new class > > Control = _make_wrapper(tpmodule.Control) > > > user.py > > # user code to run pylint on > > import mymodule > > ctrl = Control(...) > ctrl.original_func(...) > ctrl.new_func(...) > > > My plan with the transform plugin is to use > 'astroid.MANAGER.register_transform()' to detect the 'astroid.Module' calls > and turn 'mymodule.py' into something more palatable for pylint; in > particular to replace 'mymodule.Control' with an 'astroid.ClassDef' that > has the correct initializer and member functions. Unfortunately, things are > not working the way I would like and I'm still getting the missing member > and bad constructor arguments errors, even though, as far as I can see, I > am returning the appropriately modified module. > > However, there are many things that I don't understand: > > 1) Relating to the above example, pylint seems to be treating the 'ctrl' > variable in 'user.py' 'ctrl' as being of type 'tpmodule.Control' so doesn't > complain about things that are common to 'tpmodule.Control' and > 'mymodule.Control'. But I cannot understand how pylint could possibly > detect the relationship between 'tpmodule.Control' and 'mymodule.Control' > without getting into the guts of the 'mymodule._make_wrapper()' function. > > 2) It is not clear to me how pylint treats imports from external > libraries? In my example tpmodule.py and mymodule.py are not things that I > want pylint to report on. But presumably it still needs to follow some of > the chain of dependencies to work out the signature of what is exposed by > the module so I understand why it would parse 'mymodule.py', but I don't > understand why it would parse 'tpmodule.py'. > > In fact, another curious thing is that I created a cut down example to > highlight the problem and while it has some of the same errors it also > behaves slightly differently. In the cut-down example pylint DOESN'T > actually parse 'tpmodule.py' so 'tpmodule.Control' doesn't trigger the > 'register_transform()' the way it does in the real system. Even though this > makes more sense to me than what is happening in the actual code, it is > unfortunate because I wanted to dynamically construct the signature of > 'tpmodule.Control' so was relying on pylint parsing 'tpmodule.py'. > > Note for clarification, in the real system 'mymodule.py' and 'tpmodule.py' > are more complex and both use functions from their respective internal > modules. 'tpmodule.py' is actually written in C++ and is using CFFI to > generate the Python API, so maybe that can explain some difference in the > behaviour to the pylint expert? > > Anyway, I'm sorry for the long winded questions. However, I'm hoping > someone has someone insight or can point me to some docs or a specific > example that solves a similar issue. I can also post a zip file of my cut > down example if it is appropriate to do so. It consists of four short files > ('mymodule.py', 'tpmodule.py', 'user.py', and 'plugin.py'). > > > Regards, > > Dave > > > > > > > To be clear I'm not using pylint on the library itself, instead I want > pylint to work nicely with users of the library; although at some point I > will try to configure pylint to help me with refactoring some of the code > as well. > > > My library extends an existing library with some new feature. and does > some dynamic typing. > > > I'm new to the group and > _______________________________________________ > code-quality mailing list -- code-quality@python.org > To unsubscribe send an email to code-quality-le...@python.org > https://mail.python.org/mailman3/lists/code-quality.python.org/ > Member address: pierre.sassou...@gmail.com >
_______________________________________________ code-quality mailing list -- code-quality@python.org To unsubscribe send an email to code-quality-le...@python.org https://mail.python.org/mailman3/lists/code-quality.python.org/ Member address: arch...@mail-archive.com