Skip to content

Commit 1513c93

Browse files
authored
feat(core): Support List.__setitem__ (#23)
1 parent 4f414eb commit 1513c93

File tree

4 files changed

+34
-1
lines changed

4 files changed

+34
-1
lines changed

include/mlc/core/list.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,8 @@ struct UList : public ObjectRef {
174174
self->erase(i);
175175
return ret;
176176
})
177-
.MemFn("_clear", &UListObj::clear);
177+
.MemFn("_clear", &UListObj::clear)
178+
.MemFn("__setitem__", &::mlc::core::ListBase::Accessor<UListObj>::SetItem);
178179
};
179180

180181
template <typename T> struct ListObj : protected UListObj {

include/mlc/core/list_base.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ struct ListBase : public MLCList {
4444
template <typename TListObj> struct Accessor {
4545
MLC_INLINE static void New(int32_t num_args, const AnyView *args, Any *ret);
4646
MLC_INLINE static Any At(TListObj *self, int64_t i);
47+
MLC_INLINE static void SetItem(TListObj *self, int64_t i, Any value);
4748
};
4849
};
4950

@@ -180,6 +181,11 @@ MLC_INLINE Any ListBase::Accessor<TListObj>::At(TListObj *self, int64_t i) {
180181
return self->operator[](i);
181182
}
182183

184+
template <typename TListObj> //
185+
MLC_INLINE void ListBase::Accessor<TListObj>::SetItem(TListObj *self, int64_t i, Any value) {
186+
self->operator[](i) = std::move(value);
187+
}
188+
183189
} // namespace core
184190
} // namespace mlc
185191

python/mlc/core/list.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,14 @@ def __getitem__(self, i: int | slice) -> T | Sequence[T]:
4343
else:
4444
raise TypeError(f"list indices must be integers or slices, not {type(i).__name__}")
4545

46+
def __setitem__(self, index: int, value: T) -> None:
47+
length = len(self)
48+
if not -length <= index < length:
49+
raise IndexError(f"list assignment index out of range: {index}")
50+
if index < 0:
51+
index += length
52+
List._C(b"__setitem__", self, index, value)
53+
4654
def __iter__(self) -> Iterator[T]:
4755
return iter(self[i] for i in range(len(self)))
4856

tests/python/test_core_list.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,3 +163,21 @@ def test_list_ne() -> None:
163163
b = List([1, 2, 3, 4])
164164
assert a != b
165165
assert b != a
166+
167+
168+
def test_list_setitem() -> None:
169+
a = List([1, 4, 9, 16])
170+
a[1] = 8
171+
assert tuple(a) == (1, 8, 9, 16)
172+
a[-2] = 12
173+
assert tuple(a) == (1, 8, 12, 16)
174+
a[-4] = 2
175+
assert tuple(a) == (2, 8, 12, 16)
176+
177+
with pytest.raises(IndexError) as e:
178+
a[4] = 20
179+
assert str(e.value) == "list assignment index out of range: 4"
180+
181+
with pytest.raises(IndexError) as e:
182+
a[-5] = 20
183+
assert str(e.value) == "list assignment index out of range: -5"

0 commit comments

Comments
 (0)