Closed
Description
Stubgen generates wrong stubs for instance variables defined in C extensions.
In the attached extension.C
, I've created a class named Custom which has 3 instance variables: var1,var2,var3. On running stubgen for this extension, the generated .pyi file contains:
from typing import Any, ClassVar
class Custom:
// This is wrong. Var{1,2,3} are not Class Variables but are rather instance variables.
var1: ClassVar[getset_descriptor] = ...
var2: ClassVar[getset_descriptor] = ...
var3: ClassVar[member_descriptor] = ...
// This is wrong.
def display(self, *args, **kwargs) -> Any: ...
Detailed Reproducer:
- In some test directory (say $DIR), download the attached file extension.zip to extension folder.
- Compile the extension by running:
g++ -fPIC -std=c++11 -I. -I/opt/python/python-3.9/include/python3.9 -Iextension -c extension/extension.C -o extension.o
in directory $DIR. - Create the .so file by running:
g++ -shared -L/opt/python/python-3.9/lib64 -Wl,-R/opt/python/python-3.9/lib64 extension.o -o extension.so
in directory $DIR. - Run stubgen using
env PYTHONPATH=$DIR stubgen -m extension
- Notice that the generated $DIR/out/extension.pyi declares var{1,2,3} as 'Class Variables' which is wrong.
On digging into this, I found this is due to a wrong check in stubgenc.py#is_c_property
.
def is_c_property(obj: object) -> bool:
return inspect.isdatadescriptor(obj) and hasattr(obj, 'fget')
The check should contain "or" (instead of "and") since the instance variables in case of C extension doesn't have the "fget" attribute but inspect.isdatadescription
return True.
On making this change locally, stubgen runs fine.
If this looks good to you, I can raise a PR for the same.