Skip to content

[Stubgen bug] Fix behavior for Instance Variables in C extensions #12150

Closed
@shubz1998

Description

@shubz1998

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:

  1. In some test directory (say $DIR), download the attached file extension.zip to extension folder.
  2. 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.
  3. 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.
  4. Run stubgen using env PYTHONPATH=$DIR stubgen -m extension
  5. 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.

extension.zip

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions