mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-25 14:45:12 +00:00
relax operator[] for tuples, lists, and sequences
object_api::operator[] has a powerful overload for py::handle that can accept slices, tuples (for NumPy), etc. Lists, sequences, and tuples provide their own specialized operator[], which unfortunately disables this functionality. This is accidental, and the purpose of this commit is to re-enable the more general behavior. This commit is tangentially related to the previous one in that it makes py::handle/py::object et al. behave more like their Python counterparts.
This commit is contained in:
parent
067100201f
commit
b4b2292488
@ -1183,6 +1183,7 @@ public:
|
|||||||
}
|
}
|
||||||
size_t size() const { return (size_t) PyTuple_Size(m_ptr); }
|
size_t size() const { return (size_t) PyTuple_Size(m_ptr); }
|
||||||
detail::tuple_accessor operator[](size_t index) const { return {*this, index}; }
|
detail::tuple_accessor operator[](size_t index) const { return {*this, index}; }
|
||||||
|
detail::item_accessor operator[](handle h) const { return object::operator[](h); }
|
||||||
detail::tuple_iterator begin() const { return {*this, 0}; }
|
detail::tuple_iterator begin() const { return {*this, 0}; }
|
||||||
detail::tuple_iterator end() const { return {*this, PyTuple_GET_SIZE(m_ptr)}; }
|
detail::tuple_iterator end() const { return {*this, PyTuple_GET_SIZE(m_ptr)}; }
|
||||||
};
|
};
|
||||||
@ -1220,6 +1221,7 @@ public:
|
|||||||
PYBIND11_OBJECT_DEFAULT(sequence, object, PySequence_Check)
|
PYBIND11_OBJECT_DEFAULT(sequence, object, PySequence_Check)
|
||||||
size_t size() const { return (size_t) PySequence_Size(m_ptr); }
|
size_t size() const { return (size_t) PySequence_Size(m_ptr); }
|
||||||
detail::sequence_accessor operator[](size_t index) const { return {*this, index}; }
|
detail::sequence_accessor operator[](size_t index) const { return {*this, index}; }
|
||||||
|
detail::item_accessor operator[](handle h) const { return object::operator[](h); }
|
||||||
detail::sequence_iterator begin() const { return {*this, 0}; }
|
detail::sequence_iterator begin() const { return {*this, 0}; }
|
||||||
detail::sequence_iterator end() const { return {*this, PySequence_Size(m_ptr)}; }
|
detail::sequence_iterator end() const { return {*this, PySequence_Size(m_ptr)}; }
|
||||||
};
|
};
|
||||||
@ -1232,6 +1234,7 @@ public:
|
|||||||
}
|
}
|
||||||
size_t size() const { return (size_t) PyList_Size(m_ptr); }
|
size_t size() const { return (size_t) PyList_Size(m_ptr); }
|
||||||
detail::list_accessor operator[](size_t index) const { return {*this, index}; }
|
detail::list_accessor operator[](size_t index) const { return {*this, index}; }
|
||||||
|
detail::item_accessor operator[](handle h) const { return object::operator[](h); }
|
||||||
detail::list_iterator begin() const { return {*this, 0}; }
|
detail::list_iterator begin() const { return {*this, 0}; }
|
||||||
detail::list_iterator end() const { return {*this, PyList_GET_SIZE(m_ptr)}; }
|
detail::list_iterator end() const { return {*this, PyList_GET_SIZE(m_ptr)}; }
|
||||||
template <typename T> void append(T &&val) const {
|
template <typename T> void append(T &&val) const {
|
||||||
|
@ -289,4 +289,8 @@ TEST_SUBMODULE(pytypes, m) {
|
|||||||
l.append(a << b);
|
l.append(a << b);
|
||||||
return l;
|
return l;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
m.def("test_list_slicing", [](py::list a) {
|
||||||
|
return a[py::slice(0, -1, 2)];
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
@ -246,3 +246,8 @@ def test_number_protocol():
|
|||||||
li = [a == b, a != b, a < b, a <= b, a > b, a >= b, a + b,
|
li = [a == b, a != b, a < b, a <= b, a > b, a >= b, a + b,
|
||||||
a - b, a * b, a / b, a | b, a & b, a ^ b, a >> b, a << b]
|
a - b, a * b, a / b, a | b, a & b, a ^ b, a >> b, a << b]
|
||||||
assert m.test_number_protocol(a, b) == li
|
assert m.test_number_protocol(a, b) == li
|
||||||
|
|
||||||
|
|
||||||
|
def test_list_slicing():
|
||||||
|
li = list(range(100))
|
||||||
|
assert li[::2] == m.test_list_slicing(li)
|
||||||
|
Loading…
Reference in New Issue
Block a user