Skip to content

Commit

Permalink
Merge pull request #67 from apple1417/master
Browse files Browse the repository at this point in the history
fix `WrappedArray.index` not including the last item in the array
  • Loading branch information
apple1417 authored Jan 16, 2025
2 parents 8198c19 + b13720d commit be69be6
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 10 deletions.
5 changes: 5 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@

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

- Fixed that `WrappedArray.index` would not check the last item in the array. It also now accepts
start/stop indexes beyond the array bounds, like `list.index` does.

[10bdc130](https://github.com/bl-sdk/pyunrealsdk/commit/10bdc130)

## v1.5.2

### unrealsdk v1.6.1
Expand Down
2 changes: 1 addition & 1 deletion src/pyunrealsdk/unreal_bindings/wrapped_array.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ void register_wrapped_array(py::module_& mod) {
" stop: The index to stop searching before. Defaults to the end of the array.\n"
"Returns:\n"
" The first index of the value in the array.",
"value"_a, "start"_a = 0, "stop"_a = -1)
"value"_a, "start"_a = 0, "stop"_a = std::numeric_limits<py::ssize_t>::max())
.def("insert", &impl::array_py_insert,
"Inserts an item into the array before the given index.\n"
"\n"
Expand Down
2 changes: 1 addition & 1 deletion src/pyunrealsdk/unreal_bindings/wrapped_array.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ struct ArrayIterator {
* @brief Construct a new iterator.
*
* @param arr The array to iterate over.
* @param idx The idnex to start iterating at.
* @param idx The index to start iterating at.
*/
ArrayIterator(const WrappedArray& arr, size_t idx);

Expand Down
37 changes: 30 additions & 7 deletions src/pyunrealsdk/unreal_bindings/wrapped_array_methods.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,15 +63,38 @@ size_t array_py_index(const WrappedArray& self,
py::ssize_t stop) {
array_validate_value(self, value);

auto end = ArrayIterator{self, convert_py_idx(self, stop)};
// `list.index` method handles indexes a little differently to most methods. Essentially, any
// index is allowed, and it's just implicitly clamped to the size of the array. You're allowed
// to do some stupid things like `["a"].index("a", -100, -200)`, it just gives a not in list
// error.

// Firstly, wrap negative indexes
auto size = static_cast<py::ssize_t>(self.size());
if (start < 0) {
start += size;
}
if (stop < 0) {
stop += size;
}

// Clamp to the start of the array
start = std::max(start, py::ssize_t{0});
stop = std::max(stop, py::ssize_t{0});

auto location = std::find_if(ArrayIterator{self, convert_py_idx(self, start)}, end,
[&value](const auto& other) { return value.equal(other); });
if (location == end) {
throw py::value_error(
unrealsdk::fmt::format("{} is not in array", std::string(py::repr(value))));
// Make sure the start is actually before the stop
if (start < stop) {
// If the stop index is beyond the end, this automatically becomes an end of array iterator
auto end = ArrayIterator{self, static_cast<size_t>(stop)};

auto location = std::find_if(ArrayIterator{self, static_cast<size_t>(start)}, end,
[&value](const auto& other) { return value.equal(other); });
if (location != end) {
return location.idx;
}
}
return location.idx;

throw py::value_error(
unrealsdk::fmt::format("{} is not in array", std::string(py::repr(value))));
}

void array_py_insert(WrappedArray& self, py::ssize_t py_idx, const py::object& value) {
Expand Down
3 changes: 2 additions & 1 deletion stubs/unrealsdk/unreal/_wrapped_array.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from __future__ import annotations

import sys
from collections.abc import Callable, Iterator, Sequence
from types import GenericAlias
from typing import Any, Never, Self, overload
Expand Down Expand Up @@ -188,7 +189,7 @@ class WrappedArray[T]:
Args:
values: The sequence of values to append.
"""
def index(self, value: T, start: int = 0, stop: int = -1) -> int:
def index(self, value: T, start: int = 0, stop: int = sys.maxsize) -> int:
"""
Finds the first index of the given value in the array.
Expand Down

0 comments on commit be69be6

Please sign in to comment.