sizmailov / pybind11-stubgen

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

Feature: Command-line option for invalid expressions fallback (replacing) #149

Closed VelocityRa closed 11 months ago

VelocityRa commented 11 months ago

I'm exporting a method with a default argument value of std::this_thread::get_id() via pybind11, and the type isn't recognized, it's printed as def my_method(self, thread_id: ThreadId = ...) -> None and the following error is printed:

pybind11_stubgen - [ ERROR] In [redacted] : Invalid expression '<[redacted].ThreadId object at 0x000002159D2BB430>'

It would be useful if I could pass something like --replace-expressions std::this_thread::get_id() CurrentThread.

sizmailov commented 11 months ago

I thought about such an option but decided not to implement it. The reason is that a simple replacement logic is not robust, and a complex logic can't fit into the CLI option. IMO, this is another "use pybind11-stubgen as a library" scenario.

In your particular case, the <[redacted].ThreadId object at 0x000002159D2BB430> comes from my_method.__doc__. You can avoid it from the beginning by using pybind::arg_v("thread_id", std::this_thread::get_id(), "CurrentThread") instead of pybind11::arg("thread_id") = std::this_thread::get_id().

Note that def my_method(self, thread_id: ThreadId = CurrentThread) -> None would likely produce a static checker error, but this is out of the scope of the question.

VelocityRa commented 11 months ago

@sizmailov Using arg_v like that prevents the error being printed but doesn't seem to fix the issue, I still get the = .... Also tried using --print-invalid-expressions-as-is.

sizmailov commented 11 months ago

pybind11-stubgen treats default values reconstructed from docstring as "print-unsafe" to ensure syntactically (and, to some extent, semantically) valid stubs.

The exception is made for

The --print-invalid-expressions-as-is name is a bit misleading because it only affects the expressions in annotations. I'll update the option description to reflect that.

@VelocityRa Add --print-safe-value-reprs="CurrentThread" to your command line to override.

VelocityRa commented 11 months ago

Thank you. Not sure if it's because I invoke stubgen via subprocess.run or not, but I had to use --print-safe-value-reprs without the quotes after the =, otherwise they were getting used as part of the regex (I used an r string and single quotes to enclose the entire argument, no escaping.