Skip to content

Commit

Permalink
Change @__setstate__ to __setstate__[non-constructor] based on fe…
Browse files Browse the repository at this point in the history
…edback by @rainwoodman. Also revise comments.
  • Loading branch information
Ralf W. Grosse-Kunstleve committed Jan 29, 2024
1 parent 6bc10a7 commit 846bfbd
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 6 deletions.
6 changes: 3 additions & 3 deletions include/pybind11/pybind11.h
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,7 @@ class cpp_function : public function {
// it alive.
auto *rec = unique_rec.get();

// Note the "@__setstate__" manipulation below.
// Note the "__setstate__" manipulation below.
rec->is_constructor = rec->name != nullptr
&& (std::strcmp(rec->name, "__init__") == 0
|| std::strcmp(rec->name, "__setstate__") == 0);
Expand All @@ -410,9 +410,9 @@ class cpp_function : public function {
/* Create copies of all referenced C-style strings */
if (rec->name == nullptr) {
rec->name = guarded_strdup("");
} else if (std::strcmp(rec->name, "@__setstate__") == 0) {
} else if (std::strcmp(rec->name, "__setstate__[non-constructor]") == 0) {
// See google/pywrapcc#30094 for background.
rec->name = guarded_strdup(rec->name + 1);
rec->name = guarded_strdup("__setstate__");
} else {
rec->name = guarded_strdup(rec->name);
}
Expand Down
12 changes: 9 additions & 3 deletions tests/test_pickling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,16 @@ void wrap(py::module m) {

namespace exercise_getinitargs_getstate_setstate {

// Mechanism similar to what was established with Boost.Python:
// https://www.boost.org/doc/libs/1_58_0/libs/python/doc/v2/pickle.html
// Exercise `__setstate__[non-constructor]` (see google/pywrapcc#30094), which
// was added to support a pickle protocol as established with Boost.Python
// (in 2002):
// https://www.boost.org/doc/libs/1_31_0/libs/python/doc/v2/pickle.html
// This mechanism was also adopted for PyCLIF:
// https://github.com/google/clif/blob/7d388e1de7db5beeb3d7429c18a2776d8188f44f/clif/testing/python/pickle_compatibility.clif
// The code below exercises the pickle protocol intentionally exactly as used
// in PyCLIF, to ensure that pybind11 stays fully compatible with existing
// client code relying on the long-established protocol. (It is impractical to
// change all such client code.)

class StoreTwoWithState {
public:
Expand Down Expand Up @@ -97,7 +103,7 @@ void wrap(py::module m) {
},
py::arg("protocol") = -1)
.def(
"@__setstate__", // See google/pywrapcc#30094 for background.
"__setstate__[non-constructor]", // See google/pywrapcc#30094 for background.
[](StoreTwoWithState *self, const std::string &state) { self->SetState(state); },
py::arg("state"));
}
Expand Down

0 comments on commit 846bfbd

Please sign in to comment.