stubgenc.py does not generate correct lines for staticmethods
Bug Report
When I use stubgen to generate stub file for a pybind11 module
klass
.def_static("some_static_method", &A::some_static_method,
R"#(None)#", py::arg("a"), py::arg("b")
);
where pybind11::class_ klass is bound to C++ class A
the result line is like:
class A:
def some_static_method(self, *args, **kwargs): ...
which should be like:
class A:
@static_method
def some_static_method(a: T, b: T): ...
The issue here is related to a pybind11 discussion: [https://github.com/pybind/pybind11/issues/2403]. which says "a static method of class Foo, Foo.dict['f_static'] points to the static method decorator around the function object instead, not the function object itself"
So, I temporarily fixed this issue for my own project by appending a staticmethod checker right after the is_c_classmethod in file stubgenc.py:
def is_c_staticmethod(obj: object) -> bool:
return type(obj).__name__ in ('staticmethod')
def generate_c_type_stub(module: ModuleType,
class_name: str,
obj: type,
output: List[str],
imports: List[str],
sigs: Optional[Dict[str, str]] = None,
class_sigs: Optional[Dict[str, str]] = None) -> None:
...
if is_c_classmethod(value):
methods.append('@classmethod')
self_var = 'cls'
elif is_c_staticmethod(value):
methods.append('@staticmethod')
value = value.__func__
self_var = None
else:
self_var = 'self'
...
The result turns out correct with my pybind11 code. But I guess it may not work for other conditions?
For overloaded static methods the @staticmethod decorator is added to the output only once at the top, because multiple overloads are inferred in value.__func__ and their stubs appended in a loop in function generate_c_function_stub:
class A:
@staticmethod
@overload
def some_static_method(a: A1, b: B1): ...
@overload
def some_static_method(a: A2, b: B2): ...
@overload
def some_static_method(a: A3, b: B3): ...
Passing an additional decorator string argument to generate_c_function_stub, and use it in that loop can fix this problem:
class A:
@overload
@staticmethod
def some_static_method(a: A1, b: B1): ...
@overload
@staticmethod
def some_static_method(a: A2, b: B2): ...
@overload
@staticmethod
def some_static_method(a: A3, b: B3): ...
I created #14934 to fix this issue, but he pull request seems to have gone cold. I don't get any response from the reviewers and I can't merge it since I don't have the necessary permissions. How should I proceed? I would like to have this bug fixed.