-
-
Notifications
You must be signed in to change notification settings - Fork 498
python: switch binding library to nanobind
#948
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?
Conversation
|
Sorry for not reacting to your PR so far. This is definitively interesting, I just don't have the time right now to properly look into this. But I will at some point in time. |
|
No worries, take your time! |
|
Does nanobind require switching the whole build backend from setuptools to scikit-build? If not, what are the reasons for this change and which benefits and side effects does this have? |
|
@Doekin Sorry for letting this PR wait so long without feedback. I plan to make a 2.4 release soonish, so I'm trying to catch up... Are you still around to discuss details? Would you be willing to fix the conflicts? Do have you have something to say to the question from @stefan6419846 ? |
|
Thanks for checking in. Yes, I'll update the PR and fix the conflicts. As for the build backend: It's not mandatory, but |
|
With this changes, it seems like the build is broken - before, building the source distribution worked fine. Running |
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.
Thanks for coming back to this after this long delay. As you can see, I have a couple of questions.
I'd need to make sure the whole buffer_protocol + __array_interface__ code still works. I'm not sure all uses cases are covered in the tests...
| # Target the stable ABI for Python 3.12+, which reduces | ||
| # the number of binary wheels that must be built. This | ||
| # does nothing on older Python versions | ||
| STABLE_ABI |
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.
That sounds interesting. Do you know how the publish-pyhton.yml file would need to change to benefit from that? I'd also like to point out this commit by @chamalgomes. Which is touching on the same issue, at least in terms of build-times.
| set(PYBIND11_FINDPYTHON ON) # see https://github.com/pybind/pybind11/issues/4785 | ||
| zxing_add_package(pybind11 pybind11 https://github.com/pybind/pybind11.git v3.0.1) | ||
| # Try to import all Python components potentially needed by nanobind | ||
| find_package(Python 3.8 |
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.
Why exactly 3.8?
| set(ZXING_PYTHON_INSTALL_BINDIR "${CMAKE_INSTALL_BINDIR}") | ||
| if (SKBUILD) | ||
| set_target_properties(zxingcpp PROPERTIES | ||
| LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} |
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.
Does this really need to be an in-source-tree build?
| LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_SOURCE_DIR}) | ||
| endif() | ||
|
|
||
| # Copy ZXing.dll alongside zxingcpp.pyd to solve ImportError during stub generation |
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.
So you are actively developing on windows? Very helpful to find those kind of special handling requirements...
| LIBRARY DESTINATION "${ZXING_PYTHON_INSTALL_LIBDIR}") | ||
| install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/init.py | ||
| COMPONENT python | ||
| RENAME __init__.py |
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 file is generated by nanobind, right? Why would they name it init.py when it has to be renamed anyway?
| # Build stable ABI wheels for CPython 3.12+ | ||
| wheel.py-api = "cp312" | ||
|
|
||
| [tool.cibuildwheel] |
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.
How does this section conflict/interact with
| CIBW_TEST_COMMAND: python {package}/test.py |
| "pybind11[global]", | ||
| ] | ||
| build-backend = "setuptools.build_meta" | ||
| requires = ["scikit-build-core >=0.10", "nanobind >=1.3.2", "typing_extensions >=4.12;python_version<\"3.11\""] |
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.
What is typing_extension used for and why does the python_version need to be < 3.11?
| auto shape = ai["shape"].cast<std::vector<py::ssize_t>>(); | ||
| auto typestr = ai["typestr"].cast<std::string>(); | ||
| auto ai = nb::cast<nb::dict>(_image.attr("__array_interface__")); | ||
| auto shape = nb::cast<std::vector<size_t>>(ai["shape"]); |
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.
Are you sure, this is suddenly unsigned?
| imgfmt = ImageFormat::BGR; | ||
| else | ||
| throw py::value_error("Unsupported number of channels for buffer: " + std::to_string(channels)); | ||
| throw nb::value_error(("Unsupported number of channels for buffer: " + std::to_string(channels)).c_str()); |
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.
Are you sure that passing a pointer to a temporary const char* is valid here?
| return 0; | ||
| } | ||
|
|
||
| extern "C" inline int ImageView_getbuffer(PyObject* obj, Py_buffer* view, int flags) { |
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.
extern "C" + inline? I'm confused. :)
|
OK, I'll try to address these in the next few days. |
|
Re: @stefan6419846 : Perhaps it is the same issue as scikit-build/scikit-build-core#801 ? |
This PR migrates the Python bindings for
zxingcppfrompybind11tonanobind.Key Benefits:
Enhanced IDE Support (Autocompletion & Type Hinting):
The primary driver for this change is
nanobind's straightforward support for generating stub files (.pyi). These stubs enable autocompletion and type hinting in IDEs, significantly improving the development experience when using thezxingcpplibrary.Smaller Binary Sizes
Faster Compilation Times
Important Structural Change:
nanobind's typical project structure, thezxingcppPython extension has been refactored from a single-file module (e.g.,zxingcpp.pydorzxingcpp.so) into a Python package (a directory namedzxingcppcontaining an__init__.pyand the compiled extension module).