feat(numpy): add NPY_HALF_ to npy_api::constants - #6151
Open
advitrocks9 wants to merge 2 commits into
Open
Conversation
advitrocks9
marked this pull request as ready for review
August 23, 2026 21:15
Skylion007
reviewed
Aug 25, 2026
Contributor
There was a problem hiding this comment.
Pull request overview
Adds the missing compile-time NumPy typenum constant for float16 to pybind11’s internal npy_api::constants, enabling users to specialize npy_format_descriptor<T> for custom half types without including NumPy headers or hardcoding values elsewhere. This aligns npy_api::constants more closely with NumPy’s NPY_TYPES and addresses the reported gap for NPY_HALF (issue #4061).
Changes:
- Add
NPY_HALF_ = 23topybind11::detail::npy_api::constantsininclude/pybind11/numpy.h. - Add a C++ test specialization of
npy_format_descriptorfor a 2-byte PODUserHalfthat maps tonumpy.float16. - Add a Python test that verifies the typenum matches NumPy’s
float16and thatarray_t<UserHalf>round-trips asfloat16.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| include/pybind11/numpy.h | Exposes NPY_HALF_ (float16 typenum) in npy_api::constants for compile-time use in dtype specializations. |
| tests/test_numpy_dtypes.cpp | Adds UserHalf + npy_format_descriptor specialization and binds helpers to validate float16 typenum and round-trip. |
| tests/test_numpy_dtypes.py | Adds pytest coverage ensuring the new constant matches np.dtype("float16").num and round-trips with float16 dtype. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Fixes #4061.
npy_api::constantsmirrors NumPy'sNPY_TYPES, but stops atNPY_VOID_(20) and goes straight into the platform-dependent aliases, soNPY_HALF_(23) isn't there:Taking that suggestion is worse than the error.
NPY_CHAR_isn't NumPy'sNPY_CHAR, it's pybind11's ownis_signed<char> ? NPY_BYTE_ : NPY_UBYTE_, so it compiles cleanly and truncates float16 to int8.py::dtype("half")already works at runtime. What's missing is the compile-time constant, which is whatnpy_format_descriptor<T>::valueneeds to specialize a user-defined half type. The workaround in #1776 reads the typenum out of NumPy's own headers, which is the dependency this header exists to avoid.= 23is explicit since 21 and 22 aren't mirrored.numpy.hasks fornormalized_dtype_numto be reviewed alongside this enum: it's sized[NPY_VOID_ + 1]and bounds-checked before indexing, so 23 falls through unchanged, same as a float16 array does today.No caster or
format_descriptorfor a concrete half type here. Which C++ type that should be is #4627.Test specializes
npy_format_descriptorfor a 2-byte POD and round-trips it asnumpy.float16; without the enumerator the test module doesn't compile. Suite passes on macOS arm64 withPYBIND11_WERROR=ON. No Linux or Windows box to hand, so those are down to CI.Suggested changelog entry:
float16typenum topy::detail::npy_api::constantsasNPY_HALF_, so a user-defined half type can specializenpy_format_descriptorwithout hardcoding the value.