diff options
author | Robin Jarry <robin.jarry@6wind.com> | 2020-03-31 15:00:14 +0200 |
---|---|---|
committer | Claudiu Popa <pcmanticore@gmail.com> | 2020-04-03 14:34:42 +0200 |
commit | 2da60a08de6f146f5dff78db3d01bee10ed375dc (patch) | |
tree | 5c0ce24b9c9a3b96e5f1213eb8da55b97b00408e | |
parent | 2e1ba8eb47694439215b866564c4699039b86ec9 (diff) | |
download | astroid-git-2da60a08de6f146f5dff78db3d01bee10ed375dc.tar.gz |
Inspect compiled CFFI extension members
To use a CFFI extension, its "lib" symbol gives access to the exported
C symbols and its "ffi" symbol gives access to low-level utilities.
An import such as the following is required:
from _compiled_extension_module import ffi
from _compiled_extension_module import lib
Then in the code, these objects are used to access the C symbols:
pp = ffi.cast('struct mystruct *', p)
lib.exported_c_function(pp)
Even if "_compiled_extension_module" is added to
AstroidManager.extension_package_whitelist, the "ffi" and "lib" objects
are not analyzed properly since they do not fall into any of the
supported categories of objects. A dummy "builtin.module" node is
inserted in their place preventing tools like pylint to properly detect
object membership. Thus producing invalid errors:
Instance of 'module' has no 'cast' member [no-member]
Instance of 'module' has no 'exported_c_function' member [no-member]
Both these objects define __all__ attributes which lists their exported
symbols. The presence of __all__ means that dir(member) will work and
that object_build may be called recursively on that member.
Insert a Module node to represent these objects and add their members to
the built AST.
Link: https://cffi.readthedocs.io/en/latest/overview.html#main-mode-of-usage
Signed-off-by: Robin Jarry <robin.jarry@6wind.com>
-rw-r--r-- | ChangeLog | 2 | ||||
-rw-r--r-- | astroid/raw_building.py | 5 |
2 files changed, 7 insertions, 0 deletions
@@ -192,6 +192,8 @@ Release Date: TBA Close #755 +* Properly analyze CFFI compiled extensions. + What's New in astroid 2.3.2? ============================ Release Date: TBA diff --git a/astroid/raw_building.py b/astroid/raw_building.py index d94f9240..c852485e 100644 --- a/astroid/raw_building.py +++ b/astroid/raw_building.py @@ -354,6 +354,11 @@ class InspectBuilder: # This should be called for Jython, where some builtin # methods aren't caught by isbuiltin branch. _build_from_function(node, name, member, self._module) + elif hasattr(member, '__all__'): + module = build_module(name) + _attach_local_node(node, module, name) + # recursion + self.object_build(module, member) else: # create an empty node so that the name is actually defined attach_dummy_node(node, name, member) |