sizmailov / pybind11-stubgen

Generate stubs for python modules
Other
228 stars 45 forks source link

submodule imports don't resolve #174

Closed TheTripleV closed 9 months ago

TheTripleV commented 10 months ago

I have a type in a function wpimath.units.radians that needs to get resolved. wpimath.units is a module. units cannot be accessed from wpimath without importing.

# invalid code
import wpimath
wpimath.units.radians

# valid code
import wpimath.units
wpimath.units.radians

I think stubgen should try all combinations of imports (wpimath, wpimath.units) to resolve a type.

virtuald commented 10 months ago

Were you getting errors building or just type checking errors? I did not get building errors.

TheTripleV commented 10 months ago

Building errors.

sizmailov commented 10 months ago

I think I do what you suggesting:

https://github.com/sizmailov/pybind11-stubgen/blob/1b004b58f0dc8eedb1b0135736795fb8654e94fa/pybind11_stubgen/parser/mixins/fix.py#L151-L159

Sorry, I'll not be able to look into this until next weekend.

sizmailov commented 9 months ago

@TheTripleV Could you provide a reproducible example? I cannot reproduce the issue.

{
        auto sm1 = m.def_submodule("a1");
        auto sm2 = sm1.def_submodule("a2");
        auto sm3 = sm2.def_submodule("a3");
        auto sm4 = sm3.def_submodule("a4");

        struct Unit {
        };

        py::class_<Unit>(sm4, "Unit")
                .def(py::init<>());

        auto b = m.def_submodule("b");
        auto c = m.def_submodule("c");
        auto d = m.def_submodule("d");

        b.def("get_unit", [] { return Unit{}; });
        c.def("set_unit", [](const Unit &u) { return 0; });
        d.attr("unit") = Unit{};
    }
# ==> b.pyi <==
from __future__ import annotations
import demo._bindings.issues.a1.a2.a3.a4
__all__ = ['get_unit']
def get_unit() -> demo._bindings.issues.a1.a2.a3.a4.Unit:
    ...

# ==> c.pyi <==
from __future__ import annotations
import demo._bindings.issues.a1.a2.a3.a4
__all__ = ['set_unit']
def set_unit(arg0: demo._bindings.issues.a1.a2.a3.a4.Unit) -> int:
    ...

# ==> d.pyi <==
from __future__ import annotations
import demo._bindings.issues.a1.a2.a3.a4
__all__ = ['unit']
unit: demo._bindings.issues.a1.a2.a3.a4.Unit  # value = <demo._bindings.issues.a1.a2.a3.a4.Unit object>
sizmailov commented 9 months ago

I assume there was no error in pybind11-stubgen. Feel free to reopen if not.