gobj: more efficient pickling support for InternalName

Rather than going through the TypedWritable/bam route, this encodes InternalNames in a more compact and efficient manner.
This commit is contained in:
rdb 2020-04-01 18:44:37 +02:00
parent 9d8c523dfa
commit f192a0cdb6
3 changed files with 16 additions and 0 deletions

View File

@ -97,6 +97,8 @@ PUBLISHED:
// These versions are exposed to Python, which have additional logic to map
// from Python interned strings.
EXTENSION(static PT(InternalName) make(PyObject *str));
EXTENSION(PyObject *__reduce__() const);
#endif
public:

View File

@ -17,6 +17,8 @@ using std::string;
#ifdef HAVE_PYTHON
extern struct Dtool_PyTypedObject Dtool_InternalName;
/**
* This extension method serves to allow coercion of Python interned strings
* to InternalName objects more efficiently by storing a mapping between
@ -88,7 +90,17 @@ make(PyObject *str) {
InternalName::_py_intern_table.insert(std::make_pair((PyObject *)str, iname.p()));
return iname;
}
}
/**
* This special Python method is implemented to provide support for the pickle
* module.
*/
PyObject *Extension<InternalName>::
__reduce__() const {
std::string name = _this->get_name();
return Py_BuildValue("(N(s#))",
PyObject_GetAttrString((PyObject *)&Dtool_InternalName._PyType, "make"), name.c_str(), name.size());
}
#endif // HAVE_PYTHON

View File

@ -30,6 +30,8 @@ template<>
class Extension<InternalName> : public ExtensionBase<InternalName> {
public:
static PT(InternalName) make(PyObject *str);
PyObject *__reduce__() const;
};
#endif // HAVE_PYTHON