cpython/Modules/_pickle.c

/* 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)
{}