fix(numpy): accept PYBIND11_TYPE-wrapped types in the dtype macros - #6148
Conversation
|
Hi @advitrocks9 , below is a codex gpt-5.6-sol ultra review (I'm posting it as generated). It would be very easy for me to ask codex to implement the suggested fix. Please let me know if I should do that and add the commit(s) here. SummaryThis is a focused preprocessor fix for #4018. Although pybind11 documents This PR fixes that by:
This is entirely a preprocessor fix. It does not change NumPy conversion behavior, runtime representation, internals layout, or ABI. The central design looks sound. Important finding: source-compatibility regressionI think one change is needed before merging. The new implementation makes direct calls to PYBIND11_FIELD_DESCRIPTOR(MyStruct, field)At Although the PR describes these as undocumented expansion internals, direct use is real: Rosetta uses This can be fixed without changing the main design:
I tested that structure with GCC 13 and Clang 18; it supports legacy direct calls, wrapped template types, nested templates, and both recursive mapping variants. Tests and other observationsThe new tests cover the actual feature well: both public dtype macros, multiple fields, and the resulting dtype values. Existing ordinary dtype registrations remain heavily exercised. One optional strengthening: the Current CI has no reported failures and includes successful Windows/MSVC, macOS/Clang, and Ubuntu builds. Because the PR is still draft and several jobs were skipped or cancelled, the full matrix should still run before merging. Overall: this is a good, narrowly designed fix. I would be comfortable approving it once the direct field-descriptor calling convention is preserved. |
|
Thanks, the compat finding is right, direct callers like Rosetta would break. Fixed in Also took the test suggestion, the I'll mark the PR ready so the rest of CI runs. |
rwgk
left a comment
There was a problem hiding this comment.
Awesome, thanks; approving. codex is happy now, except:
The only actionable item is the PR description, which is now stale. It still says:
- direct leaf-macro calls require a parenthesized type and may break downstream users; and
PYBIND11_FIELD_DESCRIPTOR_EXperforms the unwrapping.
Those statements describe the previous head. The description should instead say that the public leaf macros retain their bare-type interface, while PYBIND11_FIELD_DESCRIPTOR_EX_IMPL receives and unwraps the protected type. Its test paragraph should also mention the new direct-call regression coverage.
|
Updated the description to match the current version. |
Description
Fixes #4018.
PYBIND11_TYPEis the documented way to pass a type with a comma in its spelling to a macro,but it doesn't work with the dtype macros:
The only workaround was a
usingalias.This happens because
PYBIND11_TYPEis itself a macro.PYBIND11_NUMPY_DTYPEbuilds its fieldlist through
PYBIND11_MAP_LIST, which rescans its output repeatedly, and the first rescanexpands the wrapper away. After that the bare comma splits the type in two at the next argument
collection. Re-wrapping at every step, the way
PYBIND11_OVERRIDEdoes, gives one correct fieldand then a field named
"double>".Plain parentheses survive rescanning, so the dtype macros now pass
(Type)through the mapmachinery, and a new
PYBIND11_FIELD_DESCRIPTOR_EX_IMPLremoves the parentheses where the typeis actually used (
#define PYBIND11_UNPAREN_TYPE(T) PYBIND11_TYPE T). The publicPYBIND11_FIELD_DESCRIPTORandPYBIND11_FIELD_DESCRIPTOR_EXstill take a bare type and addthe parentheses themselves before forwarding to the
_IMPLmacro, so projects that call themdirectly are unaffected, and they now accept a
PYBIND11_TYPE-wrapped type as well. Existingcall sites preprocess to the same tokens as before.
The tests register a two-parameter struct through both dtype macros and check the resulting
dtypes, with two different field types in the
_EXcase so each renamed field is checkedagainst its own type. A second test calls the field descriptor macros directly, with bare and
wrapped types.
Suggested changelog entry:
PYBIND11_NUMPY_DTYPEandPYBIND11_NUMPY_DTYPE_EXnow accept a type whose spelling containsa comma, when it is wrapped in
PYBIND11_TYPE. Previously the wrapper was silently droppedduring expansion and only a
usingalias worked.📚 Documentation preview 📚: https://pybind11--6148.org.readthedocs.build/