Compare commits

...

12 Commits

Author SHA1 Message Date
T.Yamada 8959b27b72
Merge ce37acbd6d into ab955f158c 2024-06-13 15:42:39 +00:00
Taiju Yamada ce37acbd6d code review 2022-06-19 19:57:35 +09:00
Taiju Yamada d77c95d068 add tests 2022-06-17 13:14:40 +09:00
Taiju Yamada c19ac6a55c perhaps should not touch newly created tuple as object 2022-06-17 13:13:45 +09:00
Taiju Yamada bf238d91ed add dict tests 2022-06-17 13:10:30 +09:00
Taiju Yamada 6fa2bb161e actually need both tests 2022-06-17 13:10:08 +09:00
Taiju Yamada 4b3f145b94 stronger test 2022-06-17 13:09:35 +09:00
pre-commit-ci[bot] 95ed8a6c29 [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
2022-06-14 19:28:36 +00:00
Aaron Gokaslan fdc20a8912 Is the new test the problem? 2022-06-14 15:27:57 -04:00
Aaron Gokaslan 9ac9c07766 Add template keyword 2022-06-14 14:29:25 -04:00
Aaron Gokaslan c3a313b0e4
Use rvalue casting 2022-06-14 14:21:32 -04:00
woody.chow 3a74bc41ef Support arbitrary type in item accessor's subscript operator 2022-06-14 12:27:10 +09:00
3 changed files with 61 additions and 15 deletions

View File

@ -95,11 +95,8 @@ public:
subclass causes a corresponding call to ``__getitem__``. Assigning a `handle` subclass causes a corresponding call to ``__getitem__``. Assigning a `handle`
or `object` subclass causes a call to ``__setitem__``. or `object` subclass causes a call to ``__setitem__``.
\endrst */ \endrst */
item_accessor operator[](handle key) const; template <typename T>
/// See above (the only difference is that the key's reference is stolen) item_accessor operator[](T &&key) const;
item_accessor operator[](object &&key) const;
/// See above (the only difference is that the key is provided as a string literal)
item_accessor operator[](const char *key) const;
/** \rst /** \rst
Return an internal functor to access the object's attributes. Casting the Return an internal functor to access the object's attributes. Casting the
@ -2474,16 +2471,9 @@ iterator object_api<D>::end() const {
return iterator::sentinel(); return iterator::sentinel();
} }
template <typename D> template <typename D>
item_accessor object_api<D>::operator[](handle key) const { template <typename T>
return {derived(), reinterpret_borrow<object>(key)}; item_accessor object_api<D>::operator[](T &&key) const {
} return {derived(), detail::object_or_cast(std::forward<T>(key)).template cast<object>()};
template <typename D>
item_accessor object_api<D>::operator[](object &&key) const {
return {derived(), std::move(key)};
}
template <typename D>
item_accessor object_api<D>::operator[](const char *key) const {
return {derived(), pybind11::str(key)};
} }
template <typename D> template <typename D>
obj_attr_accessor object_api<D>::attr(handle key) const { obj_attr_accessor object_api<D>::attr(handle key) const {

View File

@ -151,6 +151,20 @@ TEST_SUBMODULE(pytypes, m) {
py::print("list item {}: {}"_s.format(index++, item)); py::print("list item {}: {}"_s.format(index++, item));
} }
}); });
m.def("access_list", []() {
py::list l1 = py::list();
l1.append(1);
l1.append(2);
return l1[1];
});
m.def("access_list_as_object", []() {
py::list l1 = py::list();
l1.append(1);
l1.append(2);
py::object l2 = std::move(l1);
return l2[1];
});
// test_none // test_none
m.def("get_none", [] { return py::none(); }); m.def("get_none", [] { return py::none(); });
m.def("print_none", [](const py::none &none) { py::print("none: {}"_s.format(none)); }); m.def("print_none", [](const py::none &none) { py::print("none: {}"_s.format(none)); });
@ -200,6 +214,28 @@ TEST_SUBMODULE(pytypes, m) {
[](const py::dict &dict, const py::object &val) { return dict.contains(val); }); [](const py::dict &dict, const py::object &val) { return dict.contains(val); });
m.def("dict_contains", m.def("dict_contains",
[](const py::dict &dict, const char *val) { return dict.contains(val); }); [](const py::dict &dict, const char *val) { return dict.contains(val); });
m.def("access_dict_with_str", []() {
py::dict d1 = py::dict();
d1["x"] = 1;
return d1["x"];
});
m.def("access_dict_with_int", []() {
py::dict d1 = py::dict();
d1[1] = 1;
return d1[1];
});
m.def("access_dict_as_object_with_str", []() {
py::dict d1 = py::dict();
d1["x"] = 1;
py::object d2 = std::move(d1);
return d2["x"];
});
m.def("access_dict_as_object_with_int", []() {
py::dict d1 = py::dict();
d1[1] = 1;
py::object d2 = std::move(d1);
return d2[1];
});
// test_tuple // test_tuple
m.def("tuple_no_args", []() { return py::tuple{}; }); m.def("tuple_no_args", []() { return py::tuple{}; });
@ -207,6 +243,16 @@ TEST_SUBMODULE(pytypes, m) {
m.def("tuple_size_t", []() { return py::tuple{(py::size_t) 0}; }); m.def("tuple_size_t", []() { return py::tuple{(py::size_t) 0}; });
m.def("get_tuple", []() { return py::make_tuple(42, py::none(), "spam"); }); m.def("get_tuple", []() { return py::make_tuple(42, py::none(), "spam"); });
m.def("access_tuple", [](py::tuple &tpl) {
return tpl[1];
});
m.def("access_tuple_as_object_with_int_index", [](py::object &tpl) {
return tpl[1];
});
m.def("access_tuple_as_object_with_int_index_multidimension", [](py::object &tpl) {
return tpl[1][2];
});
// test_simple_namespace // test_simple_namespace
m.def("get_simple_namespace", []() { m.def("get_simple_namespace", []() {
auto ns = py::module_::import("types").attr("SimpleNamespace")( auto ns = py::module_::import("types").attr("SimpleNamespace")(

View File

@ -88,6 +88,8 @@ def test_list(capture, doc):
assert doc(m.get_list) == "get_list() -> list" assert doc(m.get_list) == "get_list() -> list"
assert doc(m.print_list) == "print_list(arg0: list) -> None" assert doc(m.print_list) == "print_list(arg0: list) -> None"
assert m.access_list() == 2
assert m.access_list_as_object() == 2
def test_none(doc): def test_none(doc):
assert doc(m.get_none) == "get_none() -> None" assert doc(m.get_none) == "get_none() -> None"
@ -175,6 +177,11 @@ def test_dict(capture, doc):
assert m.dict_keyword_constructor() == {"x": 1, "y": 2, "z": 3} assert m.dict_keyword_constructor() == {"x": 1, "y": 2, "z": 3}
assert m.access_dict_with_str() == 1
assert m.access_dict_with_int() == 1
assert m.access_dict_as_object_with_str() == 1
assert m.access_dict_as_object_with_int() == 1
class CustomContains: class CustomContains:
d = {"key": None} d = {"key": None}
@ -206,6 +213,9 @@ def test_tuple():
assert m.tuple_ssize_t() == () assert m.tuple_ssize_t() == ()
assert m.tuple_size_t() == () assert m.tuple_size_t() == ()
assert m.get_tuple() == (42, None, "spam") assert m.get_tuple() == (42, None, "spam")
assert m.access_tuple((1,2)) == 2
assert m.access_tuple_as_object_with_int_index((1,2)) == 2
assert m.access_tuple_as_object_with_int_index_multidimension(((1,2,3),(4,5,6))) == 6
def test_simple_namespace(): def test_simple_namespace():