Skip to content

Conversation

@dbs4261
Copy link

@dbs4261 dbs4261 commented Jan 26, 2026

Description

Add convenience functions to pybind11::array to return the shape and strides as a std::span. These functions are hidden with macros unless PYBIND11_CPP20 is defined and the include has been found. By returning an iterable container, a new array could be created more simply with array(other.dtype(), other.size_span(), other.strides_span()).

Suggested changelog entry:

Add convenience functions to pybind11::array to return the shape and strides as a std::span.

dbs4261 and others added 3 commits January 26, 2026 12:37
…es as a std::span. These functions are hidden with macros unless PYBIND11_CPP20 is defined and the <span> include has been found.
Add comprehensive unit tests for the new std::span helper functions:
- Test 0D, 1D, 2D, and 3D arrays
- Verify spans match regular shape()/strides() methods
- Test that spans can be used to construct new arrays
- Tests are conditionally compiled only when PYBIND11_HAS_SPAN is defined
@rwgk
Copy link
Collaborator

rwgk commented Jan 29, 2026

My prompt for Cursor was merely:

Unit tests for the two new member functions are missing, but appart from that the PR seems fine. However, I'm not familiar with std::span. Could you please review carefully?

Next thing I know, it had generated the missing unit tests.

This is the full response:

  Implementation review

  The implementation looks correct:
  1. Correct span usage:
    • Uses std::span<const ssize_t, std::dynamic_extent> (const, dynamic extent)
    • Constructs spans with std::span(pointer, count) (valid constructor)
    • Cast from ssize_t to std::size_t is safe since ndim() is non-negative for valid arrays
  2. Proper feature gating:
    • Guarded with #ifdef PYBIND11_HAS_SPAN
    • PYBIND11_HAS_SPAN is defined only when C++20 is available and <span> is found
  3. API consistency:
    • Mirrors shape() and strides() naming
    • Returns const spans, matching the const pointer returns
  4. Use case:
    • Spans can be passed to array constructors via any_container<ssize_t>, which accepts containers with iterators


  Unit tests added

  Added tests covering:
  • 0-dimensional arrays (scalars)
  • 1D, 2D, and 3D arrays
  • Comparison with regular shape()/strides() methods
  • Using spans to construct new arrays (main use case from PR description)
  • Tests are conditionally compiled only when PYBIND11_HAS_SPAN is defined


  Minor observations

  • The cast from ssize_t to std::size_t is safe but could theoretically wrap if ndim() were negative; that would indicate a corrupted array, which is outside this function's scope.

  The PR is ready to merge once the tests pass. The implementation follows pybind11 patterns and correctly uses std::span.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants