Skip to content

Commit

Permalink
serialization issues addressed
Browse files Browse the repository at this point in the history
  • Loading branch information
dg-pb committed Jun 25, 2024
1 parent 9038ed5 commit 49b8c71
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 2 deletions.
9 changes: 8 additions & 1 deletion Lib/functools.py
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ class __PlaceholderTypeBase:
Used as a placeholder for partial arguments.
"""
__instance = None
__slots__ = ()

def __new__(cls):
if cls.__instance is None:
Expand All @@ -295,8 +296,14 @@ def __repr__(self):
def __reduce__(self):
return 'Placeholder'

def __placeholder_init_subclass__(cls, *args, **kwargs):
raise TypeError(f"type '{cls.__name__}' is not an acceptable base type")

Placeholder = type('PlaceholderType', (__PlaceholderTypeBase,), {})()
Placeholder = type(
'PlaceholderType',
(__PlaceholderTypeBase,),
{'__slots__': (), '__init_subclass__': __placeholder_init_subclass__}
)()


def _partial_prepare_new(cls, func, args, keywords):
Expand Down
4 changes: 3 additions & 1 deletion Lib/pickle.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
from copyreg import dispatch_table
from copyreg import _extension_registry, _inverted_registry, _extension_cache
from itertools import islice
from functools import partial
from functools import partial, Placeholder
import sys
from sys import maxsize
from struct import pack, unpack
Expand Down Expand Up @@ -1120,6 +1120,8 @@ def save_type(self, obj):
return self.save_reduce(type, (NotImplemented,), obj=obj)
elif obj is type(...):
return self.save_reduce(type, (...,), obj=obj)
elif obj is type(Placeholder):
return self.save_reduce(type, (Placeholder,), obj=obj)
return self.save_global(obj)

dispatch[FunctionType] = save_global
Expand Down
12 changes: 12 additions & 0 deletions Modules/_functoolsmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,17 @@ placeholder_repr(PyObject *op)
return PyUnicode_FromString("Placeholder");
}

static PyObject *
placeholder_reduce(PyObject *op, PyObject *Py_UNUSED(ignored))
{
return PyUnicode_FromString("Placeholder");
}

static PyMethodDef placeholder_methods[] = {
{"__reduce__", placeholder_reduce, METH_NOARGS, NULL},
{NULL, NULL}
};

static void
placeholder_dealloc(PyObject* placeholder)
{
Expand Down Expand Up @@ -98,6 +109,7 @@ static PyType_Slot placeholder_type_slots[] = {
{Py_tp_dealloc, placeholder_dealloc},
{Py_tp_repr, placeholder_repr},
{Py_tp_doc, (void *)placeholder_doc},
{Py_tp_methods, placeholder_methods},
{Py_tp_new, placeholder_new},
// Number protocol
{Py_nb_bool, placeholder_bool},
Expand Down
9 changes: 9 additions & 0 deletions Modules/_pickle.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ typedef struct {
/* functools.partial, used for implementing __newobj_ex__ with protocols
2 and 3 */
PyObject *partial;
PyObject *placeholder;

/* Types */
PyTypeObject *Pickler_Type;
Expand Down Expand Up @@ -253,6 +254,7 @@ _Pickle_ClearState(PickleState *st)
Py_CLEAR(st->codecs_encode);
Py_CLEAR(st->getattr);
Py_CLEAR(st->partial);
Py_CLEAR(st->placeholder);
Py_CLEAR(st->Pickler_Type);
Py_CLEAR(st->Unpickler_Type);
Py_CLEAR(st->Pdata_Type);
Expand Down Expand Up @@ -375,6 +377,9 @@ _Pickle_InitState(PickleState *st)
st->partial = _PyImport_GetModuleAttrString("functools", "partial");
if (!st->partial)
goto error;
st->placeholder = _PyImport_GetModuleAttrString("functools", "Placeholder");
if (!st->placeholder)
goto error;

return 0;

Expand Down Expand Up @@ -3861,6 +3866,9 @@ save_type(PickleState *state, PicklerObject *self, PyObject *obj)
else if (obj == (PyObject *)&_PyNotImplemented_Type) {
return save_singleton_type(state, self, obj, Py_NotImplemented);
}
else if (obj == (PyObject *)Py_TYPE(state->placeholder)) {
return save_singleton_type(state, self, obj, state->placeholder);
}
return save_global(state, self, obj, NULL);
}

Expand Down Expand Up @@ -7791,6 +7799,7 @@ pickle_traverse(PyObject *m, visitproc visit, void *arg)
Py_VISIT(st->codecs_encode);
Py_VISIT(st->getattr);
Py_VISIT(st->partial);
Py_VISIT(st->placeholder);
Py_VISIT(st->Pickler_Type);
Py_VISIT(st->Unpickler_Type);
Py_VISIT(st->Pdata_Type);
Expand Down

0 comments on commit 49b8c71

Please sign in to comment.