-
Notifications
You must be signed in to change notification settings - Fork 250
Add support to generate type stubs recursively from cmake #1093
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Add support to generate type stubs recursively from cmake #1093
Conversation
FYI there's another PR to do this here: #463 |
@@ -659,6 +667,7 @@ function (nanobind_add_stub name) | |||
if (NOT ARG_INSTALL_TIME) | |||
add_custom_command( | |||
OUTPUT ${NB_STUBGEN_OUTPUTS} | |||
COMMAND ${CMAKE_COMMAND} -E rm -rf ${ARG_OUTPUT} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This directory may already have things in it which the user wants to keep. For example, installing directly into a wheel.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When directory already exists, stubgen will refuse to do anything and report error. So this will not be supported regardless even without deleting the folder.
I see, thank you. In that case feel free to close this, but please finish that other PR. |
That's not my PR :) Just commenting to show there's some prior art, it's had a lot of design back-and-forth. Not necessarily saying this should be closed. |
Non-empty output might cause issues when called with recursive option
41c7710
to
0026300
Compare
Sorry about the huge delay. I am in principle in favor of this change. I have not merged it because accepting this PR requires me to first investigate whether this recursive generation approach works for my own projects like Dr.Jit, and I have not had the time to do that. Can you clarify what is the difference between these two PRs? Which one is better? ;) @laggykiller @Ahajha |
I can't speak to the other questions, but I checked out this PR into a personal fork to test it in my project, and it seemed to work like a charm. nanobind_add_module(calc LTO calc.cpp)
nanobind_add_stub(
calc_stub
MODULE calc
RECURSIVE
OUTPUT "calc"
PYTHON_PATH "$<TARGET_FILE_DIR:calc>"
MARKER_FILE "py.typed"
DEPENDS calc
...
target_link_libraries(calc PRIVATE SHARPlib)
install(TARGETS calc DESTINATION nwsspc/sharp)
install(
FILES
"${CMAKE_CURRENT_BINARY_DIR}/py.typed"
DESTINATION "nwsspc/sharp"
)
install(
DIRECTORY
"${CMAKE_CURRENT_BINARY_DIR}/calc/"
DESTINATION "nwsspc/sharp"
) Tested with PyRight and function signatures and docs show up in my LSP. |
It's been a year since I wrote my PR, I can't remember exactly why I thought writing
Does this PR ensure stubgen is run only when necessary? I think this PR looks cleaner than my solution, only small concern from me is |
If I remember correctly, stubgen will return error if the folder already exists. So user files are not really an option. If you want to have some other files in there, you need to put them in after generating stubs. |
I have a PR that I would like merged here that would fix the recursive output structure, IMO it should be merged before CMake support is added. One of the things it does is collapses folders into files if the only contents are an |
I finally remember why generating NB_STUBGEN_OUTPUTS might be empty, causing OUTPUT to be empty, adding See https://stackoverflow.com/questions/43347087/cmake-add-custom-command-without-output for more info I have updated my PR (#463) to merge latest changes in upstream master and rename This PR solution might fail if output directory name is empty string I have tried this PR by modifying self-tests in nanobind: diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 3bd5478..56866f2 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -182,6 +182,7 @@ set(TEST_FILES
test_enum_ext.pyi.ref
test_typing_ext.pyi.ref
py_stub_test.py
+ py_stub_submodule_test.py
py_stub_test.pyi.ref
)
@@ -203,7 +204,9 @@ endif()
nanobind_add_stub(
py_stub
MODULE py_stub_test
- OUTPUT ${PYI_PREFIX}py_stub_test.pyi
+ OUTPUT ${PYI_PREFIX}
+ RECURSIVE
+ VERBOSE
PYTHON_PATH $<TARGET_FILE_DIR:test_stl_ext>
DEPENDS ${PY_STUB_TEST}
)
diff --git a/tests/py_stub_test.py b/tests/py_stub_test.py
index c0251ba..39ba1f8 100644
--- a/tests/py_stub_test.py
+++ b/tests/py_stub_test.py
@@ -12,6 +12,8 @@ from os import PathLike, getcwd
del sys
+from py_stub_submodule_test import BClass
+
C = 123
T = typing.TypeVar("T")
@@ -66,3 +68,5 @@ class AClass:
def overloaded_2(self, x):
"docstr 3"
+
+b = BClass(1)
Run tests with This would fail as |
Merging #1082 would also be super helpful, since right now I’m doing some work to try and coerce the current structure into my project. I’m currently having to rename my main module to init.pyi too, among other post processing steps (like setting return types to NDArray instead of ArrayLike). |
Iirc my PR also adds another folder level, I wrote the motivation in the PR, essentially we don't want any surprise renaming. That should handle the empty prefix case. |
Nanobind stub generators supports
--recursive
option to generate stubs also for submodules. However cmake functionnanobind_add_stub
doesn't support passing this option. This adds option to also specify RECURSIVE from cmake.