Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions include/pybind11/pytypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -1292,6 +1292,25 @@ class dict : public object {
return PyDict_Contains(m_ptr, detail::object_or_cast(std::forward<T>(key)).ptr()) == 1;
}

object get(handle key, handle default_) const {
if (PyObject *result = PyDict_GetItem(m_ptr, key.ptr())) {
return reinterpret_borrow<object>(result);
} else {
return reinterpret_borrow<object>(default_);
}
}

object get(const char *key, handle default_) const {
if (PyObject *result = PyDict_GetItemString(m_ptr, key)) {
return reinterpret_borrow<object>(result);
} else {
return reinterpret_borrow<object>(default_);
}
}

object get(handle key) const { return get(key, none()); }
object get(const char *key) const { return get(key, none()); }

private:
/// Call the `dict` Python type -- always returns a new reference
static PyObject *raw_dict(PyObject *op) {
Expand Down
12 changes: 12 additions & 0 deletions tests/test_pytypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,18 @@ TEST_SUBMODULE(pytypes, m) {
m.def("dict_contains", [](py::dict dict, const char* val) {
return dict.contains(val);
});
m.def("dict_get", [](py::dict dict, py::object key, py::object default_) {
return dict.get(key, default_);
});
m.def("dict_get", [](py::dict dict, const char* key, py::object default_) {
return dict.get(key, default_);
});
m.def("dict_get", [](py::dict dict, py::object key) {
return dict.get(key);
});
m.def("dict_get", [](py::dict dict, const char* key) {
return dict.get(key);
});

// test_str
m.def("str_from_string", []() { return py::str(std::string("baz")); });
Expand Down
10 changes: 10 additions & 0 deletions tests/test_pytypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,16 @@ def test_dict(capture, doc):
assert m.dict_contains({42: None}, 42)
assert m.dict_contains({"foo": None}, "foo")

d2 = {True: 42, 3: "abc", "abc": 3}
assert m.dict_get(d2, True) == 42
assert m.dict_get(d2, False) is None
assert m.dict_get(d2, 3, "def") == "abc"
assert m.dict_get(d2, 5, "def") == "def"
assert m.dict_get(d2, "abc") == 3
assert m.dict_get(d2, "def") is None
assert m.dict_get(d2, "abc", 5) == 3
assert m.dict_get(d2, "def", 5) == 5

assert doc(m.get_dict) == "get_dict() -> dict"
assert doc(m.print_dict) == "print_dict(arg0: dict) -> None"

Expand Down