Skip to content

Commit be69be6

Browse files
authored
Merge pull request #67 from apple1417/master
fix `WrappedArray.index` not including the last item in the array
2 parents 8198c19 + b13720d commit be69be6

File tree

5 files changed

+39
-10
lines changed

5 files changed

+39
-10
lines changed

changelog.md

+5
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@
66

77
[2ce96e52](https://github.com/bl-sdk/pyunrealsdk/commit/2ce96e52)
88

9+
- Fixed that `WrappedArray.index` would not check the last item in the array. It also now accepts
10+
start/stop indexes beyond the array bounds, like `list.index` does.
11+
12+
[10bdc130](https://github.com/bl-sdk/pyunrealsdk/commit/10bdc130)
13+
914
## v1.5.2
1015

1116
### unrealsdk v1.6.1

src/pyunrealsdk/unreal_bindings/wrapped_array.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ void register_wrapped_array(py::module_& mod) {
159159
" stop: The index to stop searching before. Defaults to the end of the array.\n"
160160
"Returns:\n"
161161
" The first index of the value in the array.",
162-
"value"_a, "start"_a = 0, "stop"_a = -1)
162+
"value"_a, "start"_a = 0, "stop"_a = std::numeric_limits<py::ssize_t>::max())
163163
.def("insert", &impl::array_py_insert,
164164
"Inserts an item into the array before the given index.\n"
165165
"\n"

src/pyunrealsdk/unreal_bindings/wrapped_array.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ struct ArrayIterator {
8888
* @brief Construct a new iterator.
8989
*
9090
* @param arr The array to iterate over.
91-
* @param idx The idnex to start iterating at.
91+
* @param idx The index to start iterating at.
9292
*/
9393
ArrayIterator(const WrappedArray& arr, size_t idx);
9494

src/pyunrealsdk/unreal_bindings/wrapped_array_methods.cpp

+30-7
Original file line numberDiff line numberDiff line change
@@ -63,15 +63,38 @@ size_t array_py_index(const WrappedArray& self,
6363
py::ssize_t stop) {
6464
array_validate_value(self, value);
6565

66-
auto end = ArrayIterator{self, convert_py_idx(self, stop)};
66+
// `list.index` method handles indexes a little differently to most methods. Essentially, any
67+
// index is allowed, and it's just implicitly clamped to the size of the array. You're allowed
68+
// to do some stupid things like `["a"].index("a", -100, -200)`, it just gives a not in list
69+
// error.
70+
71+
// Firstly, wrap negative indexes
72+
auto size = static_cast<py::ssize_t>(self.size());
73+
if (start < 0) {
74+
start += size;
75+
}
76+
if (stop < 0) {
77+
stop += size;
78+
}
79+
80+
// Clamp to the start of the array
81+
start = std::max(start, py::ssize_t{0});
82+
stop = std::max(stop, py::ssize_t{0});
6783

68-
auto location = std::find_if(ArrayIterator{self, convert_py_idx(self, start)}, end,
69-
[&value](const auto& other) { return value.equal(other); });
70-
if (location == end) {
71-
throw py::value_error(
72-
unrealsdk::fmt::format("{} is not in array", std::string(py::repr(value))));
84+
// Make sure the start is actually before the stop
85+
if (start < stop) {
86+
// If the stop index is beyond the end, this automatically becomes an end of array iterator
87+
auto end = ArrayIterator{self, static_cast<size_t>(stop)};
88+
89+
auto location = std::find_if(ArrayIterator{self, static_cast<size_t>(start)}, end,
90+
[&value](const auto& other) { return value.equal(other); });
91+
if (location != end) {
92+
return location.idx;
93+
}
7394
}
74-
return location.idx;
95+
96+
throw py::value_error(
97+
unrealsdk::fmt::format("{} is not in array", std::string(py::repr(value))));
7598
}
7699

77100
void array_py_insert(WrappedArray& self, py::ssize_t py_idx, const py::object& value) {

stubs/unrealsdk/unreal/_wrapped_array.pyi

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
from __future__ import annotations
44

5+
import sys
56
from collections.abc import Callable, Iterator, Sequence
67
from types import GenericAlias
78
from typing import Any, Never, Self, overload
@@ -188,7 +189,7 @@ class WrappedArray[T]:
188189
Args:
189190
values: The sequence of values to append.
190191
"""
191-
def index(self, value: T, start: int = 0, stop: int = -1) -> int:
192+
def index(self, value: T, start: int = 0, stop: int = sys.maxsize) -> int:
192193
"""
193194
Finds the first index of the given value in the array.
194195

0 commit comments

Comments
 (0)