sizmailov / pybind11-stubgen

Generate stubs for python modules
Other
238 stars 50 forks source link

Generate less bad typestubs for invalid bindings? #33

Closed virtuald closed 4 years ago

virtuald commented 4 years ago

I've got one like so:

    def registerFPGAButtonCallback(self, callback: std::function<void (wpi::StringRef, HAL_Value const*)>, initialNotify: bool) -> CallbackStore: 
        """
        registerFPGAButtonCallback(self: hal.simulation._simulation.RoboRioSim, callback: std::function<void (wpi::StringRef, HAL_Value const*)>, initialNotify: bool) -> hal.simulation._simulation.CallbackStore
        """

Now, clearly I forgot to include <pybind11/functional.h>. It seems like it would be a good idea to deal with this in the stubgen to make it easier to find this sort of thing. Some possibilities:

sizmailov commented 4 years ago

Hi, this is sort of duplicate of #19.

I think we can give a descriptive error message and exit shortly with error code. IMO, patching invalid bindings is a bad option as it hides actual problem and can't be done reliably anyway.

With extra --non-stop argument script should generate the stubs (like it does right now), error messages and exit with non-zero. Does it sound like a good plan?

An alternative would be to discard all arguments/rtype info from troubling signatures in stub output: def registerFPGAButtonCallback(self, *args, **kwargs) -> Any. This might be useful when someone generates stubs for 3rd party modules and doesn't want to fix everything... but it's for another issue/PR I suppose.

virtuald commented 4 years ago

Having a flag that accomplishes that would be great.

sizmailov commented 4 years ago

That's funny. I made up some examples with missing python bindings to test the patch. One of the examples looks like that:

[](std::pair<forgotten::Unbound, int>){ return 0;}
def accept_unbound_type(arg0: typing.Tuple[forgotten::Unbound, int]) -> int:

... and it turns out that is syntactically correct python snippet. I didn't believe first, it's clearly a C++-namespace type in Python! ಠ_ಠ

Give yourself a second to think how is this possible before reading next.

spoiler This is interpreted as slice expression from something called `forgotten` with stride `Unbound`.

I think I'll keep those examples as a reminder of troubling cases :smile:

sizmailov commented 4 years ago

Closed by 12862d1663461437e00573ce5d995189db6fa1bd