Skip to content

Commit 22185f9

Browse files
committed
Remove nb::any nd-array size tag
This is the first in a sequence of two API-breaking commits that repurposes ``nb::any`` to be a wrapper type for ``typing.Any``. To fix code impacted by this commit, change ``nb::shape<.., nb::any, ..>`` to ``nb::shape<.., -1, ..>``.
1 parent 9a81356 commit 22185f9

File tree

8 files changed

+37
-25
lines changed

8 files changed

+37
-25
lines changed

docs/api_extra.rst

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -799,19 +799,19 @@ nanobind does not support non-standard types as documented in the section on
799799
Shape
800800
+++++
801801

802-
.. cpp:class:: template <size_t... Is> shape
802+
.. cpp:class:: template <ssize_t... Is> shape
803803

804804
Require the array to have ``sizeof...(Is)`` dimensions. Each entry of `Is`
805805
specifies a fixed size constraint for that specific dimension. An entry
806-
equal to :cpp:var:`any` indicates that any size should be accepted for this
806+
equal to ``-1`` indicates that *any* size should be accepted for this
807807
dimension.
808808

809+
(An alias named ``nb::any`` representing ``-1`` was removed in nanobind 2).
810+
809811
.. cpp:class:: template <size_t N> ndim
810812

811813
Alternative to the above that only constrains the array dimension.
812-
``nb::ndim<2>`` is equivalent to ``nb::shape<nb::any, nb::any>``.
813-
814-
.. cpp:var:: constexpr size_t any = (size_t) -1
814+
``nb::ndim<2>`` is equivalent to ``nb::shape<-1, -1>``.
815815

816816
Contiguity
817817
++++++++++

docs/changelog.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,14 @@ noteworthy:
155155
nanobind versions but was awkward to use, as it required the user to provide
156156
a custom type formatter. This release makes the interface more convenient.
157157

158+
* The ``nb::any`` placeholder to specify an unconstrained
159+
:cpp:class:`nb::ndarray <ndarray>` axis was removed. This name was given to a
160+
new wrapper type :cpp:class:`nb::any`` indicating ``typing.Any``-typed
161+
values.
162+
163+
All use of ``nb::any`` in existing code must be replaced with ``-1`` (for
164+
example, ``nb::shape<3, nb::any, 4>`` → ``nb::shape<3, -1, 4>``).
165+
158166
* :ref:`Keyword-only arguments <kw_only>` are now supported, and can be
159167
indicated using the new :cpp:struct:`nb::kw_only() <kw_only>` function
160168
annotation. (PR `#448 <https://github.com/wjakob/nanobind/pull/448>`__).

include/nanobind/eigen/dense.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,9 @@ using array_for_eigen_t = ndarray<
9595
numpy,
9696
std::conditional_t<
9797
ndim_v<T> == 1,
98-
shape<(size_t) T::SizeAtCompileTime>,
99-
shape<(size_t) T::RowsAtCompileTime,
100-
(size_t) T::ColsAtCompileTime>>,
98+
shape<T::SizeAtCompileTime>,
99+
shape<T::RowsAtCompileTime,
100+
T::ColsAtCompileTime>>,
101101
std::conditional_t<
102102
is_contiguous_v<T>,
103103
std::conditional_t<

include/nanobind/eigen/sparse.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ template <typename T> struct type_caster<T, enable_if_t<is_eigen_sparse_matrix_v
3939

4040
static constexpr bool RowMajor = T::IsRowMajor;
4141

42-
using ScalarNDArray = ndarray<numpy, Scalar, shape<any>>;
43-
using StorageIndexNDArray = ndarray<numpy, StorageIndex, shape<any>>;
42+
using ScalarNDArray = ndarray<numpy, Scalar, shape<-1>>;
43+
using StorageIndexNDArray = ndarray<numpy, StorageIndex, shape<-1>>;
4444

4545
using ScalarCaster = make_caster<ScalarNDArray>;
4646
using StorageIndexCaster = make_caster<StorageIndexNDArray>;

include/nanobind/nb_traits.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
*/
99

1010
NAMESPACE_BEGIN(NB_NAMESPACE)
11+
using ssize_t = std::make_signed_t<size_t>;
12+
1113
NAMESPACE_BEGIN(detail)
1214

1315
struct void_type { };

include/nanobind/ndarray.h

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,11 @@ template <typename T> struct is_complex : std::false_type { };
7171

7272
NAMESPACE_END(detail)
7373

74-
constexpr size_t any = (size_t) -1;
75-
76-
template <size_t... Is> struct shape {
74+
template <ssize_t... Is> struct shape {
75+
static_assert(
76+
((Is >= 0 || Is == -1) && ...),
77+
"The arguments to nanobind::shape must either be positive or equal to -1"
78+
);
7779
static constexpr size_t size = sizeof...(Is);
7880
};
7981

@@ -103,7 +105,7 @@ constexpr bool is_ndarray_scalar_v =
103105

104106
template <typename> struct ndim_shape;
105107
template <size_t... S> struct ndim_shape<std::index_sequence<S...>> {
106-
using type = shape<((void) S, any)...>;
108+
using type = shape<((void) S, -1)...>;
107109
};
108110

109111
NAMESPACE_END(detail)
@@ -227,16 +229,16 @@ template<> struct ndarray_arg<ro> {
227229
}
228230
};
229231

230-
template <size_t... Is> struct ndarray_arg<shape<Is...>> {
232+
template <ssize_t... Is> struct ndarray_arg<shape<Is...>> {
231233
static constexpr size_t size = sizeof...(Is);
232234
static constexpr auto name =
233235
const_name("shape=(") +
234-
concat(const_name<Is == any>(const_name("*"), const_name<Is>())...) +
236+
concat(const_name<Is == -1>(const_name("*"), const_name<(size_t) Is>())...) +
235237
const_name(")");
236238

237239
static void apply(ndarray_req &tr) {
238240
size_t i = 0;
239-
((tr.shape[i++] = Is), ...);
241+
((tr.shape[i++] = (size_t) Is), ...);
240242
tr.ndim = (uint32_t) sizeof...(Is);
241243
tr.req_shape = true;
242244
}
@@ -281,7 +283,7 @@ template <typename T, typename... Ts> struct ndarray_info<T, Ts...> : ndarray_i
281283
T, typename ndarray_info<Ts...>::scalar_type>;
282284
};
283285

284-
template <size_t... Is, typename... Ts> struct ndarray_info<shape<Is...>, Ts...> : ndarray_info<Ts...> {
286+
template <ssize_t... Is, typename... Ts> struct ndarray_info<shape<Is...>, Ts...> : ndarray_info<Ts...> {
285287
using shape_type = shape<Is...>;
286288
};
287289

@@ -347,14 +349,14 @@ template <typename Scalar, typename Shape, char Order> struct ndarray_view {
347349
private:
348350
template <typename...> friend class ndarray;
349351

350-
template <size_t... I1, size_t... I2>
352+
template <size_t... I1, ssize_t... I2>
351353
ndarray_view(Scalar *data, const int64_t *shape, const int64_t *strides,
352354
std::index_sequence<I1...>, nanobind::shape<I2...>)
353355
: m_data(data) {
354356

355357
/* Initialize shape/strides with compile-time knowledge if
356358
available (to permit vectorization, loop unrolling, etc.) */
357-
((m_shape[I1] = (I2 == any) ? shape[I1] : I2), ...);
359+
((m_shape[I1] = (I2 == -1) ? shape[I1] : (int64_t) I2), ...);
358360
((m_strides[I1] = strides[I1]), ...);
359361

360362
if constexpr (Order == 'F') {

src/nb_ndarray.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ ndarray_handle *ndarray_import(PyObject *o, const ndarray_req *req,
375375
if (pass_shape) {
376376
for (uint32_t i = 0; i < req->ndim; ++i) {
377377
if (req->shape[i] != (size_t) t.shape[i] &&
378-
req->shape[i] != nanobind::any) {
378+
req->shape[i] != (size_t) -1) {
379379
pass_shape = false;
380380
break;
381381
}

tests/test_ndarray.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,11 @@ NB_MODULE(test_ndarray_ext, m) {
7676
m.def("pass_uint32", [](const nb::ndarray<uint32_t> &) { }, "array"_a.noconvert());
7777
m.def("pass_bool", [](const nb::ndarray<bool> &) { }, "array"_a.noconvert());
7878
m.def("pass_float32_shaped",
79-
[](const nb::ndarray<float, nb::shape<3, nb::any, 4>> &) {}, "array"_a.noconvert());
79+
[](const nb::ndarray<float, nb::shape<3, -1, 4>> &) {}, "array"_a.noconvert());
8080

8181
m.def("pass_float32_shaped_ordered",
8282
[](const nb::ndarray<float, nb::c_contig,
83-
nb::shape<nb::any, nb::any, 4>> &) {}, "array"_a.noconvert());
83+
nb::shape<-1, -1, 4>> &) {}, "array"_a.noconvert());
8484

8585
m.def("check_order", [](nb::ndarray<nb::c_contig>) -> char { return 'C'; });
8686
m.def("check_order", [](nb::ndarray<nb::f_contig>) -> char { return 'F'; });
@@ -98,7 +98,7 @@ NB_MODULE(test_ndarray_ext, m) {
9898
});
9999

100100
m.def("initialize",
101-
[](nb::ndarray<float, nb::shape<10, nb::any>, nb::device::cpu> &t) {
101+
[](nb::ndarray<float, nb::shape<10, -1>, nb::device::cpu> &t) {
102102
int k = 0;
103103
for (size_t i = 0; i < 10; ++i)
104104
for (size_t j = 0; j < t.shape(1); ++j)
@@ -132,7 +132,7 @@ NB_MODULE(test_ndarray_ext, m) {
132132
);
133133
});
134134

135-
m.def("process", [](nb::ndarray<uint8_t, nb::shape<nb::any, nb::any, 3>,
135+
m.def("process", [](nb::ndarray<uint8_t, nb::shape<-1, -1, 3>,
136136
nb::c_contig, nb::device::cpu> ndarray) {
137137
// Double brightness of the MxNx3 RGB image
138138
for (size_t y = 0; y < ndarray.shape(0); ++y)

0 commit comments

Comments
 (0)