Skip to content

Commit 853bafa

Browse files
authored
fix: use original dict (#5658)
* fix: use original dict Signed-off-by: Henry Schreiner <[email protected]> * refactor: handle unset dict just in case Signed-off-by: Henry Schreiner <[email protected]> --------- Signed-off-by: Henry Schreiner <[email protected]>
1 parent c5dc6f9 commit 853bafa

File tree

2 files changed

+11
-5
lines changed

2 files changed

+11
-5
lines changed

include/pybind11/detail/init.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -451,7 +451,16 @@ void setstate(value_and_holder &v_h, std::pair<T, O> &&result, bool need_alias)
451451
// See PR #2972 for details.
452452
return;
453453
}
454-
setattr((PyObject *) v_h.inst, "__dict__", d);
454+
// Our tests never run into an unset dict, but being careful here for now (see #5658)
455+
auto dict = getattr((PyObject *) v_h.inst, "__dict__", none());
456+
if (dict.is_none()) {
457+
setattr((PyObject *) v_h.inst, "__dict__", d);
458+
} else {
459+
// Keep the original object dict and just update it
460+
if (PyDict_Update(dict.ptr(), d.ptr()) < 0) {
461+
throw error_already_set();
462+
}
463+
}
455464
}
456465

457466
/// Implementation for py::pickle(GetState, SetState)

tests/test_pickling.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,7 @@ void wrap(py::module m) {
3535
.def_readwrite("num", &SimpleBase::num)
3636
.def(py::pickle(
3737
[](const py::object &self) {
38-
py::dict d;
39-
if (py::hasattr(self, "__dict__")) {
40-
d = self.attr("__dict__");
41-
}
38+
py::dict d = py::getattr(self, "__dict__", py::dict());
4239
return py::make_tuple(self.attr("num"), d);
4340
},
4441
[](const py::tuple &t) {

0 commit comments

Comments
 (0)