/* pickle accelerator C extensor: _pickle module. * * It is built as a built-in module (Py_BUILD_CORE_BUILTIN define) on Windows * and as an extension module (Py_BUILD_CORE_MODULE define) on other * platforms. */ #ifndef Py_BUILD_CORE_BUILTIN #define Py_BUILD_CORE_MODULE … #endif #include "Python.h" #include "pycore_bytesobject.h" // _PyBytesWriter #include "pycore_ceval.h" // _Py_EnterRecursiveCall() #include "pycore_critical_section.h" // Py_BEGIN_CRITICAL_SECTION() #include "pycore_long.h" // _PyLong_AsByteArray() #include "pycore_moduleobject.h" // _PyModule_GetState() #include "pycore_object.h" // _PyNone_Type #include "pycore_pyerrors.h" // _PyErr_FormatNote #include "pycore_pystate.h" // _PyThreadState_GET() #include "pycore_runtime.h" // _Py_ID() #include "pycore_setobject.h" // _PySet_NextEntry() #include "pycore_sysmodule.h" // _PySys_GetAttr() #include <stdlib.h> // strtol() PyDoc_STRVAR(pickle_module_doc, "Optimized C implementation for the Python pickle module."); /*[clinic input] module _pickle class _pickle.Pickler "PicklerObject *" "" class _pickle.PicklerMemoProxy "PicklerMemoProxyObject *" "" class _pickle.Unpickler "UnpicklerObject *" "" class _pickle.UnpicklerMemoProxy "UnpicklerMemoProxyObject *" "" [clinic start generated code]*/ /*[clinic end generated code: output=da39a3ee5e6b4b0d input=b6d7191ab6466cda]*/ /* Bump HIGHEST_PROTOCOL when new opcodes are added to the pickle protocol. Bump DEFAULT_PROTOCOL only when the oldest still supported version of Python already includes it. */ enum { … }; #ifdef MS_WINDOWS // These are already typedefs from windows.h, pulled in via pycore_runtime.h. #define FLOAT … #define INT … #define LONG … /* This can already be defined on Windows to set the character set the Windows header files treat as default */ #ifdef UNICODE #undef UNICODE #endif #endif /* Pickle opcodes. These must be kept updated with pickle.py. Extensive docs are in pickletools.py. */ enum opcode { … }; enum { … }; /*************************************************************************/ /* State of the pickle module, per PEP 3121. */ PickleState; /* Forward declaration of the _pickle module definition. */ static struct PyModuleDef _picklemodule; /* Given a module object, get its per-module state. */ static inline PickleState * _Pickle_GetState(PyObject *module) { … } static inline PickleState * _Pickle_GetStateByClass(PyTypeObject *cls) { … } static inline PickleState * _Pickle_FindStateByType(PyTypeObject *tp) { … } /* Clear the given pickle module state. */ static void _Pickle_ClearState(PickleState *st) { … } /* Initialize the given pickle module state. */ static int _Pickle_InitState(PickleState *st) { … } /* Helper for calling a function with a single argument quickly. This function steals the reference of the given argument. */ static PyObject * _Pickle_FastCall(PyObject *func, PyObject *obj) { … } /*************************************************************************/ /* Internal data type used as the unpickling stack. */ Pdata; static int Pdata_traverse(Pdata *self, visitproc visit, void *arg) { … } static void Pdata_dealloc(Pdata *self) { … } static PyType_Slot pdata_slots[] = …; static PyType_Spec pdata_spec = …; static PyObject * Pdata_New(PickleState *state) { … } /* Retain only the initial clearto items. If clearto >= the current * number of items, this is a (non-erroneous) NOP. */ static int Pdata_clear(Pdata *self, Py_ssize_t clearto) { … } static int Pdata_grow(Pdata *self) { … } static int Pdata_stack_underflow(PickleState *st, Pdata *self) { … } /* D is a Pdata*. Pop the topmost element and store it into V, which * must be an lvalue holding PyObject*. On stack underflow, UnpicklingError * is raised and V is set to NULL. */ static PyObject * Pdata_pop(PickleState *state, Pdata *self) { … } #define PDATA_POP(S, D, V) … static int Pdata_push(Pdata *self, PyObject *obj) { … } /* Push an object on stack, transferring its ownership to the stack. */ #define PDATA_PUSH(D, O, ER) … /* Push an object on stack, adding a new reference to the object. */ #define PDATA_APPEND(D, O, ER) … static PyObject * Pdata_poptuple(PickleState *state, Pdata *self, Py_ssize_t start) { … } static PyObject * Pdata_poplist(Pdata *self, Py_ssize_t start) { … } PyMemoEntry; PyMemoTable; PicklerObject; UnpicklerObject; PicklerMemoProxyObject; UnpicklerMemoProxyObject; /* Forward declarations */ static int save(PickleState *state, PicklerObject *, PyObject *, int); static int save_reduce(PickleState *, PicklerObject *, PyObject *, PyObject *); #include "clinic/_pickle.c.h" /************************************************************************* A custom hashtable mapping void* to Python ints. This is used by the pickler for memoization. Using a custom hashtable rather than PyDict allows us to skip a bunch of unnecessary object creation. This makes a huge performance difference. */ #define MT_MINSIZE … #define PERTURB_SHIFT … static PyMemoTable * PyMemoTable_New(void) { … } static PyMemoTable * PyMemoTable_Copy(PyMemoTable *self) { … } static Py_ssize_t PyMemoTable_Size(PyMemoTable *self) { … } static int PyMemoTable_Clear(PyMemoTable *self) { … } static void PyMemoTable_Del(PyMemoTable *self) { … } /* Since entries cannot be deleted from this hashtable, _PyMemoTable_Lookup() can be considerably simpler than dictobject.c's lookdict(). */ static PyMemoEntry * _PyMemoTable_Lookup(PyMemoTable *self, PyObject *key) { … } /* Returns -1 on failure, 0 on success. */ static int _PyMemoTable_ResizeTable(PyMemoTable *self, size_t min_size) { … } /* Returns NULL on failure, a pointer to the value otherwise. */ static Py_ssize_t * PyMemoTable_Get(PyMemoTable *self, PyObject *key) { … } /* Returns -1 on failure, 0 on success. */ static int PyMemoTable_Set(PyMemoTable *self, PyObject *key, Py_ssize_t value) { … } #undef MT_MINSIZE #undef PERTURB_SHIFT /*************************************************************************/ static int _Pickler_ClearBuffer(PicklerObject *self) { … } static void _write_size64(char *out, size_t value) { … } static int _Pickler_CommitFrame(PicklerObject *self) { … } static PyObject * _Pickler_GetString(PicklerObject *self) { … } static int _Pickler_FlushToFile(PicklerObject *self) { … } static int _Pickler_OpcodeBoundary(PicklerObject *self) { … } static Py_ssize_t _Pickler_Write(PicklerObject *self, const char *s, Py_ssize_t data_len) { … } static PicklerObject * _Pickler_New(PickleState *st) { … } static int _Pickler_SetProtocol(PicklerObject *self, PyObject *protocol, int fix_imports) { … } /* Returns -1 (with an exception set) on failure, 0 on success. This may be called once on a freshly created Pickler. */ static int _Pickler_SetOutputStream(PicklerObject *self, PyObject *file) { … } static int _Pickler_SetBufferCallback(PicklerObject *self, PyObject *buffer_callback) { … } /* Returns the size of the input on success, -1 on failure. This takes its own reference to `input`. */ static Py_ssize_t _Unpickler_SetStringInput(UnpicklerObject *self, PyObject *input) { … } static int bad_readline(PickleState *st) { … } /* Skip any consumed data that was only prefetched using peek() */ static int _Unpickler_SkipConsumed(UnpicklerObject *self) { … } static const Py_ssize_t READ_WHOLE_LINE = …; /* If reading from a file, we need to only pull the bytes we need, since there may be multiple pickle objects arranged contiguously in the same input buffer. If `n` is READ_WHOLE_LINE, read a whole line. Otherwise, read up to `n` bytes from the input stream/buffer. Update the unpickler's input buffer with the newly-read data. Returns -1 on failure; on success, returns the number of bytes read from the file. On success, self->input_len will be 0; this is intentional so that when unpickling from a file, the "we've run out of data" code paths will trigger, causing the Unpickler to go back to the file for more data. Use the returned size to tell you how much data you can process. */ static Py_ssize_t _Unpickler_ReadFromFile(UnpicklerObject *self, Py_ssize_t n) { … } /* Don't call it directly: use _Unpickler_Read() */ static Py_ssize_t _Unpickler_ReadImpl(UnpicklerObject *self, PickleState *st, char **s, Py_ssize_t n) { … } /* Read `n` bytes from the unpickler's data source, storing the result in `buf`. * * This should only be used for non-small data reads where potentially * avoiding a copy is beneficial. This method does not try to prefetch * more data into the input buffer. * * _Unpickler_Read() is recommended in most cases. */ static Py_ssize_t _Unpickler_ReadInto(PickleState *state, UnpicklerObject *self, char *buf, Py_ssize_t n) { … } /* Read `n` bytes from the unpickler's data source, storing the result in `*s`. This should be used for all data reads, rather than accessing the unpickler's input buffer directly. This method deals correctly with reading from input streams, which the input buffer doesn't deal with. Note that when reading from a file-like object, self->next_read_idx won't be updated (it should remain at 0 for the entire unpickling process). You should use this function's return value to know how many bytes you can consume. Returns -1 (with an exception set) on failure. On success, return the number of chars read. */ #define _Unpickler_Read(self, state, s, n) … static Py_ssize_t _Unpickler_CopyLine(UnpicklerObject *self, char *line, Py_ssize_t len, char **result) { … } /* Read a line from the input stream/buffer. If we run off the end of the input before hitting \n, raise an error. Returns the number of chars read, or -1 on failure. */ static Py_ssize_t _Unpickler_Readline(PickleState *state, UnpicklerObject *self, char **result) { … } /* Returns -1 (with an exception set) on failure, 0 on success. The memo array will be modified in place. */ static int _Unpickler_ResizeMemoList(UnpicklerObject *self, size_t new_size) { … } /* Returns NULL if idx is out of bounds. */ static PyObject * _Unpickler_MemoGet(UnpicklerObject *self, size_t idx) { … } /* Returns -1 (with an exception set) on failure, 0 on success. This takes its own reference to `value`. */ static int _Unpickler_MemoPut(UnpicklerObject *self, size_t idx, PyObject *value) { … } static PyObject ** _Unpickler_NewMemo(Py_ssize_t new_size) { … } /* Free the unpickler's memo, taking care to decref any items left in it. */ static void _Unpickler_MemoCleanup(UnpicklerObject *self) { … } static UnpicklerObject * _Unpickler_New(PyObject *module) { … } /* Returns -1 (with an exception set) on failure, 0 on success. This may be called once on a freshly created Unpickler. */ static int _Unpickler_SetInputStream(UnpicklerObject *self, PyObject *file) { … } /* Returns -1 (with an exception set) on failure, 0 on success. This may be called once on a freshly created Unpickler. */ static int _Unpickler_SetInputEncoding(UnpicklerObject *self, const char *encoding, const char *errors) { … } /* Returns -1 (with an exception set) on failure, 0 on success. This may be called once on a freshly created Unpickler. */ static int _Unpickler_SetBuffers(UnpicklerObject *self, PyObject *buffers) { … } /* Generate a GET opcode for an object stored in the memo. */ static int memo_get(PickleState *st, PicklerObject *self, PyObject *key) { … } /* Store an object in the memo, assign it a new unique ID based on the number of objects currently stored in the memo and generate a PUT opcode. */ static int memo_put(PickleState *st, PicklerObject *self, PyObject *obj) { … } static PyObject * get_dotted_path(PyObject *name) { … } static int check_dotted_path(PickleState *st, PyObject *obj, PyObject *dotted_path) { … } static PyObject * getattribute(PyObject *obj, PyObject *names, int raises) { … } static int _checkmodule(PyObject *module_name, PyObject *module, PyObject *global, PyObject *dotted_path) { … } static PyObject * whichmodule(PickleState *st, PyObject *global, PyObject *global_name, PyObject *dotted_path) { … } /* fast_save_enter() and fast_save_leave() are guards against recursive objects when Pickler is used with the "fast mode" (i.e., with object memoization disabled). If the nesting of a list or dict object exceed FAST_NESTING_LIMIT, these guards will start keeping an internal reference to the seen list or dict objects and check whether these objects are recursive. These are not strictly necessary, since save() has a hard-coded recursion limit, but they give a nicer error message than the typical RuntimeError. */ static int fast_save_enter(PicklerObject *self, PyObject *obj) { … } static int fast_save_leave(PicklerObject *self, PyObject *obj) { … } static int save_none(PicklerObject *self, PyObject *obj) { … } static int save_bool(PicklerObject *self, PyObject *obj) { … } static int save_long(PicklerObject *self, PyObject *obj) { … } static int save_float(PicklerObject *self, PyObject *obj) { … } /* Perform direct write of the header and payload of the binary object. The large contiguous data is written directly into the underlying file object, bypassing the output_buffer of the Pickler. We intentionally do not insert a protocol 4 frame opcode to make it possible to optimize file.read calls in the loader. */ static int _Pickler_write_bytes(PicklerObject *self, const char *header, Py_ssize_t header_size, const char *data, Py_ssize_t data_size, PyObject *payload) { … } static int _save_bytes_data(PickleState *st, PicklerObject *self, PyObject *obj, const char *data, Py_ssize_t size) { … } static int save_bytes(PickleState *st, PicklerObject *self, PyObject *obj) { … } static int _save_bytearray_data(PickleState *state, PicklerObject *self, PyObject *obj, const char *data, Py_ssize_t size) { … } static int save_bytearray(PickleState *state, PicklerObject *self, PyObject *obj) { … } static int save_picklebuffer(PickleState *st, PicklerObject *self, PyObject *obj) { … } /* A copy of PyUnicode_AsRawUnicodeEscapeString() that also translates backslash and newline characters to \uXXXX escapes. */ static PyObject * raw_unicode_escape(PyObject *obj) { … } static int write_unicode_binary(PicklerObject *self, PyObject *obj) { … } static int save_unicode(PickleState *state, PicklerObject *self, PyObject *obj) { … } /* A helper for save_tuple. Push the len elements in tuple t on the stack. */ static int store_tuple_elements(PickleState *state, PicklerObject *self, PyObject *t, Py_ssize_t len) { … } /* Tuples are ubiquitous in the pickle protocols, so many techniques are * used across protocols to minimize the space needed to pickle them. * Tuples are also the only builtin immutable type that can be recursive * (a tuple can be reached from itself), and that requires some subtle * magic so that it works in all cases. IOW, this is a long routine. */ static int save_tuple(PickleState *state, PicklerObject *self, PyObject *obj) { … } /* iter is an iterator giving items, and we batch up chunks of * MARK item item ... item APPENDS * opcode sequences. Calling code should have arranged to first create an * empty list, or list-like object, for the APPENDS to operate on. * Returns 0 on success, <0 on error. */ static int batch_list(PickleState *state, PicklerObject *self, PyObject *iter, PyObject *origobj) { … } /* This is a variant of batch_list() above, specialized for lists (with no * support for list subclasses). Like batch_list(), we batch up chunks of * MARK item item ... item APPENDS * opcode sequences. Calling code should have arranged to first create an * empty list, or list-like object, for the APPENDS to operate on. * Returns 0 on success, -1 on error. * * This version is considerably faster than batch_list(), if less general. * * Note that this only works for protocols > 0. */ static int batch_list_exact(PickleState *state, PicklerObject *self, PyObject *obj) { … } static int save_list(PickleState *state, PicklerObject *self, PyObject *obj) { … } /* iter is an iterator giving (key, value) pairs, and we batch up chunks of * MARK key value ... key value SETITEMS * opcode sequences. Calling code should have arranged to first create an * empty dict, or dict-like object, for the SETITEMS to operate on. * Returns 0 on success, <0 on error. * * This is very much like batch_list(). The difference between saving * elements directly, and picking apart two-tuples, is so long-winded at * the C level, though, that attempts to combine these routines were too * ugly to bear. */ static int batch_dict(PickleState *state, PicklerObject *self, PyObject *iter, PyObject *origobj) { … } /* This is a variant of batch_dict() above that specializes for dicts, with no * support for dict subclasses. Like batch_dict(), we batch up chunks of * MARK key value ... key value SETITEMS * opcode sequences. Calling code should have arranged to first create an * empty dict, or dict-like object, for the SETITEMS to operate on. * Returns 0 on success, -1 on error. * * Note that this currently doesn't work for protocol 0. */ static int batch_dict_exact(PickleState *state, PicklerObject *self, PyObject *obj) { … } static int save_dict(PickleState *state, PicklerObject *self, PyObject *obj) { … } static int save_set(PickleState *state, PicklerObject *self, PyObject *obj) { … } static int save_frozenset(PickleState *state, PicklerObject *self, PyObject *obj) { … } static int fix_imports(PickleState *st, PyObject **module_name, PyObject **global_name) { … } static int save_global(PickleState *st, PicklerObject *self, PyObject *obj, PyObject *name) { … } static int save_singleton_type(PickleState *state, PicklerObject *self, PyObject *obj, PyObject *singleton) { … } static int save_type(PickleState *state, PicklerObject *self, PyObject *obj) { … } static int save_pers(PickleState *state, PicklerObject *self, PyObject *obj) { … } static PyObject * get_class(PyObject *obj) { … } /* We're saving obj, and args is the 2-thru-5 tuple returned by the * appropriate __reduce__ method for obj. */ static int save_reduce(PickleState *st, PicklerObject *self, PyObject *args, PyObject *obj) { … } static int save(PickleState *st, PicklerObject *self, PyObject *obj, int pers_save) { … } static PyObject * persistent_id(PyObject *self, PyObject *obj) { … } static int dump(PickleState *state, PicklerObject *self, PyObject *obj) { … } /*[clinic input] _pickle.Pickler.clear_memo Clears the pickler's "memo". The memo is the data structure that remembers which objects the pickler has already seen, so that shared or recursive objects are pickled by reference and not by value. This method is useful when re-using picklers. [clinic start generated code]*/ static PyObject * _pickle_Pickler_clear_memo_impl(PicklerObject *self) /*[clinic end generated code: output=8665c8658aaa094b input=01bdad52f3d93e56]*/ { … } /*[clinic input] _pickle.Pickler.dump cls: defining_class obj: object / Write a pickled representation of the given object to the open file. [clinic start generated code]*/ static PyObject * _pickle_Pickler_dump_impl(PicklerObject *self, PyTypeObject *cls, PyObject *obj) /*[clinic end generated code: output=952cf7f68b1445bb input=f949d84151983594]*/ { … } /*[clinic input] _pickle.Pickler.__sizeof__ -> size_t Returns size in memory, in bytes. [clinic start generated code]*/ static size_t _pickle_Pickler___sizeof___impl(PicklerObject *self) /*[clinic end generated code: output=23ad75658d3b59ff input=d8127c8e7012ebd7]*/ { … } static struct PyMethodDef Pickler_methods[] = …; static int Pickler_clear(PicklerObject *self) { … } static void Pickler_dealloc(PicklerObject *self) { … } static int Pickler_traverse(PicklerObject *self, visitproc visit, void *arg) { … } /*[clinic input] _pickle.Pickler.__init__ file: object protocol: object = None fix_imports: bool = True buffer_callback: object = None This takes a binary file for writing a pickle data stream. The optional *protocol* argument tells the pickler to use the given protocol; supported protocols are 0, 1, 2, 3, 4 and 5. The default protocol is 5. It was introduced in Python 3.8, and is incompatible with previous versions. Specifying a negative protocol version selects the highest protocol version supported. The higher the protocol used, the more recent the version of Python needed to read the pickle produced. The *file* argument must have a write() method that accepts a single bytes argument. It can thus be a file object opened for binary writing, an io.BytesIO instance, or any other custom object that meets this interface. If *fix_imports* is True and protocol is less than 3, pickle will try to map the new Python 3 names to the old module names used in Python 2, so that the pickle data stream is readable with Python 2. If *buffer_callback* is None (the default), buffer views are serialized into *file* as part of the pickle stream. If *buffer_callback* is not None, then it can be called any number of times with a buffer view. If the callback returns a false value (such as None), the given buffer is out-of-band; otherwise the buffer is serialized in-band, i.e. inside the pickle stream. It is an error if *buffer_callback* is not None and *protocol* is None or smaller than 5. [clinic start generated code]*/ static int _pickle_Pickler___init___impl(PicklerObject *self, PyObject *file, PyObject *protocol, int fix_imports, PyObject *buffer_callback) /*[clinic end generated code: output=0abedc50590d259b input=cddc50f66b770002]*/ { … } /* Define a proxy object for the Pickler's internal memo object. This is to * avoid breaking code like: * pickler.memo.clear() * and * pickler.memo = saved_memo * Is this a good idea? Not really, but we don't want to break code that uses * it. Note that we don't implement the entire mapping API here. This is * intentional, as these should be treated as black-box implementation details. */ /*[clinic input] _pickle.PicklerMemoProxy.clear Remove all items from memo. [clinic start generated code]*/ static PyObject * _pickle_PicklerMemoProxy_clear_impl(PicklerMemoProxyObject *self) /*[clinic end generated code: output=5fb9370d48ae8b05 input=ccc186dacd0f1405]*/ { … } /*[clinic input] _pickle.PicklerMemoProxy.copy Copy the memo to a new object. [clinic start generated code]*/ static PyObject * _pickle_PicklerMemoProxy_copy_impl(PicklerMemoProxyObject *self) /*[clinic end generated code: output=bb83a919d29225ef input=b73043485ac30b36]*/ { … } /*[clinic input] _pickle.PicklerMemoProxy.__reduce__ Implement pickle support. [clinic start generated code]*/ static PyObject * _pickle_PicklerMemoProxy___reduce___impl(PicklerMemoProxyObject *self) /*[clinic end generated code: output=bebba1168863ab1d input=2f7c540e24b7aae4]*/ { … } static PyMethodDef picklerproxy_methods[] = …; static void PicklerMemoProxy_dealloc(PicklerMemoProxyObject *self) { … } static int PicklerMemoProxy_traverse(PicklerMemoProxyObject *self, visitproc visit, void *arg) { … } static int PicklerMemoProxy_clear(PicklerMemoProxyObject *self) { … } static PyType_Slot memoproxy_slots[] = …; static PyType_Spec memoproxy_spec = …; static PyObject * PicklerMemoProxy_New(PicklerObject *pickler) { … } /*****************************************************************************/ static PyObject * Pickler_get_memo(PicklerObject *self, void *Py_UNUSED(ignored)) { … } static int Pickler_set_memo(PicklerObject *self, PyObject *obj, void *Py_UNUSED(ignored)) { … } static PyObject * Pickler_getattr(PyObject *self, PyObject *name) { … } static int Pickler_setattr(PyObject *self, PyObject *name, PyObject *value) { … } static PyMemberDef Pickler_members[] = …; static PyGetSetDef Pickler_getsets[] = …; static PyType_Slot pickler_type_slots[] = …; static PyType_Spec pickler_type_spec = …; /* Temporary helper for calling self.find_class(). XXX: It would be nice to able to avoid Python function call overhead, by using directly the C version of find_class(), when find_class() is not overridden by a subclass. Although, this could become rather hackish. A simpler optimization would be to call the C function when self is not a subclass instance. */ static PyObject * find_class(UnpicklerObject *self, PyObject *module_name, PyObject *global_name) { … } static Py_ssize_t marker(PickleState *st, UnpicklerObject *self) { … } static int load_none(PickleState *state, UnpicklerObject *self) { … } static int load_int(PickleState *state, UnpicklerObject *self) { … } static int load_bool(PickleState *state, UnpicklerObject *self, PyObject *boolean) { … } /* s contains x bytes of an unsigned little-endian integer. Return its value * as a C Py_ssize_t, or -1 if it's higher than PY_SSIZE_T_MAX. */ static Py_ssize_t calc_binsize(char *bytes, int nbytes) { … } /* s contains x bytes of a little-endian integer. Return its value as a * C int. Obscure: when x is 1 or 2, this is an unsigned little-endian * int, but when x is 4 it's a signed one. This is a historical source * of x-platform bugs. */ static long calc_binint(char *bytes, int nbytes) { … } static int load_binintx(UnpicklerObject *self, char *s, int size) { … } static int load_binint(PickleState *state, UnpicklerObject *self) { … } static int load_binint1(PickleState *state, UnpicklerObject *self) { … } static int load_binint2(PickleState *state, UnpicklerObject *self) { … } static int load_long(PickleState *state, UnpicklerObject *self) { … } /* 'size' bytes contain the # of bytes of little-endian 256's-complement * data following. */ static int load_counted_long(PickleState *st, UnpicklerObject *self, int size) { … } static int load_float(PickleState *state, UnpicklerObject *self) { … } static int load_binfloat(PickleState *state, UnpicklerObject *self) { … } static int load_string(PickleState *st, UnpicklerObject *self) { … } static int load_counted_binstring(PickleState *st, UnpicklerObject *self, int nbytes) { … } static int load_counted_binbytes(PickleState *state, UnpicklerObject *self, int nbytes) { … } static int load_counted_bytearray(PickleState *state, UnpicklerObject *self) { … } static int load_next_buffer(PickleState *st, UnpicklerObject *self) { … } static int load_readonly_buffer(PickleState *state, UnpicklerObject *self) { … } static int load_unicode(PickleState *state, UnpicklerObject *self) { … } static int load_counted_binunicode(PickleState *state, UnpicklerObject *self, int nbytes) { … } static int load_counted_tuple(PickleState *state, UnpicklerObject *self, Py_ssize_t len) { … } static int load_tuple(PickleState *state, UnpicklerObject *self) { … } static int load_empty_list(PickleState *state, UnpicklerObject *self) { … } static int load_empty_dict(PickleState *state, UnpicklerObject *self) { … } static int load_empty_set(PickleState *state, UnpicklerObject *self) { … } static int load_list(PickleState *state, UnpicklerObject *self) { … } static int load_dict(PickleState *st, UnpicklerObject *self) { … } static int load_frozenset(PickleState *state, UnpicklerObject *self) { … } static PyObject * instantiate(PyObject *cls, PyObject *args) { … } static int load_obj(PickleState *state, UnpicklerObject *self) { … } static int load_inst(PickleState *state, UnpicklerObject *self) { … } static void newobj_unpickling_error(PickleState *st, const char *msg, int use_kwargs, PyObject *arg) { … } static int load_newobj(PickleState *state, UnpicklerObject *self, int use_kwargs) { … } static int load_global(PickleState *state, UnpicklerObject *self) { … } static int load_stack_global(PickleState *st, UnpicklerObject *self) { … } static int load_persid(PickleState *st, UnpicklerObject *self) { … } static int load_binpersid(PickleState *st, UnpicklerObject *self) { … } static int load_pop(PickleState *state, UnpicklerObject *self) { … } static int load_pop_mark(PickleState *state, UnpicklerObject *self) { … } static int load_dup(PickleState *state, UnpicklerObject *self) { … } static int load_get(PickleState *st, UnpicklerObject *self) { … } static int load_binget(PickleState *st, UnpicklerObject *self) { … } static int load_long_binget(PickleState *st, UnpicklerObject *self) { … } /* Push an object from the extension registry (EXT[124]). nbytes is * the number of bytes following the opcode, holding the index (code) value. */ static int load_extension(PickleState *st, UnpicklerObject *self, int nbytes) { … } static int load_put(PickleState *state, UnpicklerObject *self) { … } static int load_binput(PickleState *state, UnpicklerObject *self) { … } static int load_long_binput(PickleState *state, UnpicklerObject *self) { … } static int load_memoize(PickleState *state, UnpicklerObject *self) { … } static int do_append(PickleState *state, UnpicklerObject *self, Py_ssize_t x) { … } static int load_append(PickleState *state, UnpicklerObject *self) { … } static int load_appends(PickleState *state, UnpicklerObject *self) { … } static int do_setitems(PickleState *st, UnpicklerObject *self, Py_ssize_t x) { … } static int load_setitem(PickleState *state, UnpicklerObject *self) { … } static int load_setitems(PickleState *state, UnpicklerObject *self) { … } static int load_additems(PickleState *state, UnpicklerObject *self) { … } static int load_build(PickleState *st, UnpicklerObject *self) { … } static int load_mark(PickleState *state, UnpicklerObject *self) { … } static int load_reduce(PickleState *state, UnpicklerObject *self) { … } /* Just raises an error if we don't know the protocol specified. PROTO * is the first opcode for protocols >= 2. */ static int load_proto(PickleState *state, UnpicklerObject *self) { … } static int load_frame(PickleState *state, UnpicklerObject *self) { … } static PyObject * load(PickleState *st, UnpicklerObject *self) { … } /*[clinic input] _pickle.Unpickler.persistent_load cls: defining_class pid: object / [clinic start generated code]*/ static PyObject * _pickle_Unpickler_persistent_load_impl(UnpicklerObject *self, PyTypeObject *cls, PyObject *pid) /*[clinic end generated code: output=9f4706f1330cb14d input=2f9554fae051276e]*/ { … } /*[clinic input] _pickle.Unpickler.load cls: defining_class Load a pickle. Read a pickled object representation from the open file object given in the constructor, and return the reconstituted object hierarchy specified therein. [clinic start generated code]*/ static PyObject * _pickle_Unpickler_load_impl(UnpicklerObject *self, PyTypeObject *cls) /*[clinic end generated code: output=cc88168f608e3007 input=f5d2f87e61d5f07f]*/ { … } /* The name of find_class() is misleading. In newer pickle protocols, this function is used for loading any global (i.e., functions), not just classes. The name is kept only for backward compatibility. */ /*[clinic input] _pickle.Unpickler.find_class cls: defining_class module_name: object global_name: object / Return an object from a specified module. If necessary, the module will be imported. Subclasses may override this method (e.g. to restrict unpickling of arbitrary classes and functions). This method is called whenever a class or a function object is needed. Both arguments passed are str objects. [clinic start generated code]*/ static PyObject * _pickle_Unpickler_find_class_impl(UnpicklerObject *self, PyTypeObject *cls, PyObject *module_name, PyObject *global_name) /*[clinic end generated code: output=99577948abb0be81 input=9577745719219fc7]*/ { … } /*[clinic input] _pickle.Unpickler.__sizeof__ -> size_t Returns size in memory, in bytes. [clinic start generated code]*/ static size_t _pickle_Unpickler___sizeof___impl(UnpicklerObject *self) /*[clinic end generated code: output=4648d84c228196df input=27180b2b6b524012]*/ { … } static struct PyMethodDef Unpickler_methods[] = …; static int Unpickler_clear(UnpicklerObject *self) { … } static void Unpickler_dealloc(UnpicklerObject *self) { … } static int Unpickler_traverse(UnpicklerObject *self, visitproc visit, void *arg) { … } /*[clinic input] _pickle.Unpickler.__init__ file: object * fix_imports: bool = True encoding: str = 'ASCII' errors: str = 'strict' buffers: object(c_default="NULL") = () This takes a binary file for reading a pickle data stream. The protocol version of the pickle is detected automatically, so no protocol argument is needed. Bytes past the pickled object's representation are ignored. The argument *file* must have two methods, a read() method that takes an integer argument, and a readline() method that requires no arguments. Both methods should return bytes. Thus *file* can be a binary file object opened for reading, an io.BytesIO object, or any other custom object that meets this interface. Optional keyword arguments are *fix_imports*, *encoding* and *errors*, which are used to control compatibility support for pickle stream generated by Python 2. If *fix_imports* is True, pickle will try to map the old Python 2 names to the new names used in Python 3. The *encoding* and *errors* tell pickle how to decode 8-bit string instances pickled by Python 2; these default to 'ASCII' and 'strict', respectively. The *encoding* can be 'bytes' to read these 8-bit string instances as bytes objects. [clinic start generated code]*/ static int _pickle_Unpickler___init___impl(UnpicklerObject *self, PyObject *file, int fix_imports, const char *encoding, const char *errors, PyObject *buffers) /*[clinic end generated code: output=09f0192649ea3f85 input=ca4c1faea9553121]*/ { … } /* Define a proxy object for the Unpickler's internal memo object. This is to * avoid breaking code like: * unpickler.memo.clear() * and * unpickler.memo = saved_memo * Is this a good idea? Not really, but we don't want to break code that uses * it. Note that we don't implement the entire mapping API here. This is * intentional, as these should be treated as black-box implementation details. * * We do, however, have to implement pickling/unpickling support because of * real-world code like cvs2svn. */ /*[clinic input] _pickle.UnpicklerMemoProxy.clear Remove all items from memo. [clinic start generated code]*/ static PyObject * _pickle_UnpicklerMemoProxy_clear_impl(UnpicklerMemoProxyObject *self) /*[clinic end generated code: output=d20cd43f4ba1fb1f input=b1df7c52e7afd9bd]*/ { … } /*[clinic input] _pickle.UnpicklerMemoProxy.copy Copy the memo to a new object. [clinic start generated code]*/ static PyObject * _pickle_UnpicklerMemoProxy_copy_impl(UnpicklerMemoProxyObject *self) /*[clinic end generated code: output=e12af7e9bc1e4c77 input=97769247ce032c1d]*/ { … } /*[clinic input] _pickle.UnpicklerMemoProxy.__reduce__ Implement pickling support. [clinic start generated code]*/ static PyObject * _pickle_UnpicklerMemoProxy___reduce___impl(UnpicklerMemoProxyObject *self) /*[clinic end generated code: output=6da34ac048d94cca input=6920862413407199]*/ { … } static PyMethodDef unpicklerproxy_methods[] = …; static void UnpicklerMemoProxy_dealloc(UnpicklerMemoProxyObject *self) { … } static int UnpicklerMemoProxy_traverse(UnpicklerMemoProxyObject *self, visitproc visit, void *arg) { … } static int UnpicklerMemoProxy_clear(UnpicklerMemoProxyObject *self) { … } static PyType_Slot unpickler_memoproxy_slots[] = …; static PyType_Spec unpickler_memoproxy_spec = …; static PyObject * UnpicklerMemoProxy_New(UnpicklerObject *unpickler) { … } /*****************************************************************************/ static PyObject * Unpickler_get_memo(UnpicklerObject *self, void *Py_UNUSED(ignored)) { … } static int Unpickler_set_memo(UnpicklerObject *self, PyObject *obj, void *Py_UNUSED(ignored)) { … } static PyObject * Unpickler_getattr(PyObject *self, PyObject *name) { … } static int Unpickler_setattr(PyObject *self, PyObject *name, PyObject *value) { … } static PyGetSetDef Unpickler_getsets[] = …; static PyType_Slot unpickler_type_slots[] = …; static PyType_Spec unpickler_type_spec = …; /*[clinic input] _pickle.dump obj: object file: object protocol: object = None * fix_imports: bool = True buffer_callback: object = None Write a pickled representation of obj to the open file object file. This is equivalent to ``Pickler(file, protocol).dump(obj)``, but may be more efficient. The optional *protocol* argument tells the pickler to use the given protocol; supported protocols are 0, 1, 2, 3, 4 and 5. The default protocol is 5. It was introduced in Python 3.8, and is incompatible with previous versions. Specifying a negative protocol version selects the highest protocol version supported. The higher the protocol used, the more recent the version of Python needed to read the pickle produced. The *file* argument must have a write() method that accepts a single bytes argument. It can thus be a file object opened for binary writing, an io.BytesIO instance, or any other custom object that meets this interface. If *fix_imports* is True and protocol is less than 3, pickle will try to map the new Python 3 names to the old module names used in Python 2, so that the pickle data stream is readable with Python 2. If *buffer_callback* is None (the default), buffer views are serialized into *file* as part of the pickle stream. It is an error if *buffer_callback* is not None and *protocol* is None or smaller than 5. [clinic start generated code]*/ static PyObject * _pickle_dump_impl(PyObject *module, PyObject *obj, PyObject *file, PyObject *protocol, int fix_imports, PyObject *buffer_callback) /*[clinic end generated code: output=706186dba996490c input=b89ce8d0e911fd46]*/ { … } /*[clinic input] _pickle.dumps obj: object protocol: object = None * fix_imports: bool = True buffer_callback: object = None Return the pickled representation of the object as a bytes object. The optional *protocol* argument tells the pickler to use the given protocol; supported protocols are 0, 1, 2, 3, 4 and 5. The default protocol is 5. It was introduced in Python 3.8, and is incompatible with previous versions. Specifying a negative protocol version selects the highest protocol version supported. The higher the protocol used, the more recent the version of Python needed to read the pickle produced. If *fix_imports* is True and *protocol* is less than 3, pickle will try to map the new Python 3 names to the old module names used in Python 2, so that the pickle data stream is readable with Python 2. If *buffer_callback* is None (the default), buffer views are serialized into *file* as part of the pickle stream. It is an error if *buffer_callback* is not None and *protocol* is None or smaller than 5. [clinic start generated code]*/ static PyObject * _pickle_dumps_impl(PyObject *module, PyObject *obj, PyObject *protocol, int fix_imports, PyObject *buffer_callback) /*[clinic end generated code: output=fbab0093a5580fdf input=139fc546886c63ac]*/ { … } /*[clinic input] _pickle.load file: object * fix_imports: bool = True encoding: str = 'ASCII' errors: str = 'strict' buffers: object(c_default="NULL") = () Read and return an object from the pickle data stored in a file. This is equivalent to ``Unpickler(file).load()``, but may be more efficient. The protocol version of the pickle is detected automatically, so no protocol argument is needed. Bytes past the pickled object's representation are ignored. The argument *file* must have two methods, a read() method that takes an integer argument, and a readline() method that requires no arguments. Both methods should return bytes. Thus *file* can be a binary file object opened for reading, an io.BytesIO object, or any other custom object that meets this interface. Optional keyword arguments are *fix_imports*, *encoding* and *errors*, which are used to control compatibility support for pickle stream generated by Python 2. If *fix_imports* is True, pickle will try to map the old Python 2 names to the new names used in Python 3. The *encoding* and *errors* tell pickle how to decode 8-bit string instances pickled by Python 2; these default to 'ASCII' and 'strict', respectively. The *encoding* can be 'bytes' to read these 8-bit string instances as bytes objects. [clinic start generated code]*/ static PyObject * _pickle_load_impl(PyObject *module, PyObject *file, int fix_imports, const char *encoding, const char *errors, PyObject *buffers) /*[clinic end generated code: output=250452d141c23e76 input=46c7c31c92f4f371]*/ { … } /*[clinic input] _pickle.loads data: object / * fix_imports: bool = True encoding: str = 'ASCII' errors: str = 'strict' buffers: object(c_default="NULL") = () Read and return an object from the given pickle data. The protocol version of the pickle is detected automatically, so no protocol argument is needed. Bytes past the pickled object's representation are ignored. Optional keyword arguments are *fix_imports*, *encoding* and *errors*, which are used to control compatibility support for pickle stream generated by Python 2. If *fix_imports* is True, pickle will try to map the old Python 2 names to the new names used in Python 3. The *encoding* and *errors* tell pickle how to decode 8-bit string instances pickled by Python 2; these default to 'ASCII' and 'strict', respectively. The *encoding* can be 'bytes' to read these 8-bit string instances as bytes objects. [clinic start generated code]*/ static PyObject * _pickle_loads_impl(PyObject *module, PyObject *data, int fix_imports, const char *encoding, const char *errors, PyObject *buffers) /*[clinic end generated code: output=82ac1e6b588e6d02 input=b3615540d0535087]*/ { … } static struct PyMethodDef pickle_methods[] = …; static int pickle_clear(PyObject *m) { … } static void pickle_free(PyObject *m) { … } static int pickle_traverse(PyObject *m, visitproc visit, void *arg) { … } static int _pickle_exec(PyObject *m) { … } static PyModuleDef_Slot pickle_slots[] = …; static struct PyModuleDef _picklemodule = …; PyMODINIT_FUNC PyInit__pickle(void) { … }