[Python-checkins] r56219 - python/branches/cpy_merge/Modules/_picklemodule.c

alexandre.vassalotti python-checkins at python.org
Mon Jul 9 21:36:01 CEST 2007


Author: alexandre.vassalotti
Date: Mon Jul  9 21:36:01 2007
New Revision: 56219

Modified:
   python/branches/cpy_merge/Modules/_picklemodule.c
Log:
Add basic subclassing support to Pickler.
Remove all module-level function.
Remove a left-over from the "list-based" pickle in write_other().
Clean up Picklertype.


Modified: python/branches/cpy_merge/Modules/_picklemodule.c
==============================================================================
--- python/branches/cpy_merge/Modules/_picklemodule.c	(original)
+++ python/branches/cpy_merge/Modules/_picklemodule.c	Mon Jul  9 21:36:01 2007
@@ -461,7 +461,7 @@
 static int
 write_other(Picklerobject *self, const char *s, Py_ssize_t _n)
 {
-    PyObject *py_str = 0, *junk = 0;
+    PyObject *py_str, *result;
     int n;
 
     if (_n > INT_MAX)
@@ -491,21 +491,16 @@
         }
     }
 
-    if (self->write) {
-        /* object with write method */
-        ARG_TUP(self, py_str);
-        if (self->arg) {
-            junk = PyObject_Call(self->write, self->arg, NULL);
-            FREE_ARG_TUP(self);
-        }
-        if (junk)
-            Py_DECREF(junk);
-        else
-            return -1;
+    /* object with write method */
+    ARG_TUP(self, py_str);
+    if (self->arg) {
+        result = PyObject_Call(self->write, self->arg, NULL);
+        FREE_ARG_TUP(self);
     }
-    else
-        PDATA_PUSH(self->file, py_str, -1);
+    if (result == NULL)
+        return -1;
 
+    Py_DECREF(result);
     self->buf_size = 0;
     return n;
 }
@@ -2394,10 +2389,17 @@
     {NULL, NULL}                /* sentinel */
 };
 
-static Picklerobject *
-newPicklerobject(PyObject *file, int proto)
+static PyObject *
+Pickler_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 {
+    static char *kwlist[] = { "file", "protocol", NULL };
     Picklerobject *self;
+    PyObject *file;
+    int proto = 0;
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|i:Pickler",
+                                     kwlist, &file, &proto))
+        return NULL;
 
     if (proto < 0)
         proto = HIGHEST_PROTOCOL;
@@ -2411,86 +2413,66 @@
     self = PyObject_GC_New(Picklerobject, &Picklertype);
     if (self == NULL)
         return NULL;
-    self->proto = proto;
-    self->bin = proto > 0;
-    self->fp = NULL;
-    self->write = NULL;
-    self->memo = NULL;
-    self->arg = NULL;
-    self->pers_func = NULL;
-    self->inst_pers_func = NULL;
-    self->write_buf = NULL;
-    self->fast = 0;
-    self->nesting = 0;
-    self->fast_container = 0;
-    self->fast_memo = NULL;
-    self->buf_size = 0;
-    self->dispatch_table = NULL;
-
-    self->file = NULL;
-    if (file)
-        Py_INCREF(file);
-    else
-        goto err;
 
-    self->file = file;
+	self->proto = proto;
+	self->bin = proto > 0;
+	self->fp = NULL;
+	self->write = NULL;
+	self->memo = NULL;
+	self->arg = NULL;
+	self->pers_func = NULL;
+	self->inst_pers_func = NULL;
+	self->write_buf = NULL;
+	self->fast = 0;
+    self->nesting = 0;
+	self->fast_container = 0;
+	self->fast_memo = NULL;
+	self->buf_size = 0;
+	self->dispatch_table = NULL;
+
+    self->memo = PyDict_New();
+    if (self->memo == NULL)
+        goto error;
 
-    if (!(self->memo = PyDict_New()))
-        goto err;
+    Py_INCREF(dispatch_table);
+    self->dispatch_table = dispatch_table;
 
+    Py_INCREF(file);
     if (PyFile_Check(file)) {
         self->fp = PyFile_AsFile(file);
         if (self->fp == NULL) {
             PyErr_SetString(PyExc_ValueError, "I/O operation on closed file");
-            goto err;
+            goto io_error;
         }
         self->write_func = write_file;
     }
     else {
-        self->write_func = write_other;
-
         self->write = PyObject_GetAttr(file, write_str);
-        if (!self->write) {
+        if (self->write == NULL) {
             PyErr_Clear();
             PyErr_SetString(PyExc_TypeError,
                             "argument must have 'write' " "attribute");
-            goto err;
+            goto io_error;
         }
 
         self->write_buf = (char *) PyMem_Malloc(WRITE_BUF_SIZE);
         if (self->write_buf == NULL) {
             PyErr_NoMemory();
-            goto err;
+            goto io_error;
         }
+        self->write_func = write_other;
     }
 
-    self->dispatch_table = dispatch_table;
-    Py_INCREF(dispatch_table);
     PyObject_GC_Track(self);
+    return (PyObject *) self;
 
-    return self;
-
-  err:
+  io_error:
+    Py_DECREF(file);
+  error:
     Py_DECREF(self);
     return NULL;
 }
 
-
-static PyObject *
-get_Pickler(PyObject *self, PyObject *args, PyObject *kwds)
-{
-    static char *kwlist[] = { "file", "protocol", NULL };
-    PyObject *file = NULL;
-    int proto = 0;
-
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|i:Pickler",
-                                     kwlist, &file, &proto))
-        return NULL;
-
-    return (PyObject *) newPicklerobject(file, proto);
-}
-
-
 static void
 Pickler_dealloc(Picklerobject *self)
 {
@@ -2499,7 +2481,6 @@
     Py_XDECREF(self->memo);
     Py_XDECREF(self->fast_memo);
     Py_XDECREF(self->arg);
-    Py_XDECREF(self->file);
     Py_XDECREF(self->pers_func);
     Py_XDECREF(self->inst_pers_func);
     Py_XDECREF(self->dispatch_table);
@@ -2514,7 +2495,6 @@
     Py_VISIT(self->memo);
     Py_VISIT(self->fast_memo);
     Py_VISIT(self->arg);
-    Py_VISIT(self->file);
     Py_VISIT(self->pers_func);
     Py_VISIT(self->inst_pers_func);
     Py_VISIT(self->dispatch_table);
@@ -2528,7 +2508,6 @@
     Py_CLEAR(self->memo);
     Py_CLEAR(self->fast_memo);
     Py_CLEAR(self->arg);
-    Py_CLEAR(self->file);
     Py_CLEAR(self->pers_func);
     Py_CLEAR(self->inst_pers_func);
     Py_CLEAR(self->dispatch_table);
@@ -2624,40 +2603,73 @@
     {NULL}
 };
 
-PyDoc_STRVAR(Picklertype__doc__, "Objects that know how to pickle objects\n");
+PyDoc_STRVAR(Pickler_doc,
+"Pickler(file, protocol=0) -- Create a pickler.\n"
+"\n"
+"This takes a file-like object for writing a pickle data stream.\n"
+"The optional proto argument tells the pickler to use the given\n"
+"protocol; supported protocols are 0, 1, 2.  The default\n"
+"protocol is 0, to be backwards compatible.  (Protocol 0 is the\n"
+"only protocol that can be written to a file opened in text\n"
+"mode and read back successfully.  When using a protocol higher\n"
+"than 0, make sure the file is opened in binary mode, both when\n"
+"pickling and unpickling.)\n"
+"\n"
+"Protocol 1 is more efficient than protocol 0; protocol 2 is\n"
+"more efficient than protocol 1.\n"
+"\n"
+"Specifying a negative protocol version selects the highest\n"
+"protocol version supported.  The higher the protocol used, the\n"
+"more recent the version of Python needed to read the pickle\n"
+"produced.\n"
+"\n"
+"The file parameter must have a write() method that accepts a single\n"
+"string argument.  It can thus be an open file object, a StringIO\n"
+"object, or any other custom object that meets this interface.\n");
+
 
 static PyTypeObject Picklertype = {
     PyObject_HEAD_INIT(NULL)
-        0,                      /*ob_size */
-    "pickle.Pickler",          /*tp_name */
-    sizeof(Picklerobject),      /*tp_basicsize */
-    0,
-    (destructor) Pickler_dealloc,       /* tp_dealloc */
-    0,                          /* tp_print */
-    0,                          /* tp_getattr */
-    0,                          /* tp_setattr */
-    0,                          /* tp_compare */
-    0,                          /* tp_repr */
-    0,                          /* tp_as_number */
-    0,                          /* tp_as_sequence */
-    0,                          /* tp_as_mapping */
-    0,                          /* tp_hash */
-    0,                          /* tp_call */
-    0,                          /* tp_str */
-    PyObject_GenericGetAttr,    /* tp_getattro */
-    PyObject_GenericSetAttr,    /* tp_setattro */
-    0,                          /* tp_as_buffer */
+    0,                                  /*ob_size*/
+    "_pickle.Pickler"  ,                /*tp_name*/
+    sizeof(Picklerobject),              /*tp_basicsize*/
+    0,                                  /*tp_itemsize*/
+    (destructor)Pickler_dealloc,        /*tp_dealloc*/
+    0,                                  /*tp_print*/
+    0,                                  /*tp_getattr*/
+    0,                                  /*tp_setattr*/
+    0,                                  /*tp_compare*/
+    0,                                  /*tp_repr*/
+    0,                                  /*tp_as_number*/
+    0,                                  /*tp_as_sequence*/
+    0,                                  /*tp_as_mapping*/
+    0,                                  /*tp_hash*/
+    0,                                  /*tp_call*/
+    0,                                  /*tp_str*/
+    PyObject_GenericGetAttr,            /*tp_getattro*/
+    PyObject_GenericSetAttr,            /*tp_setattro*/
+    0,                                  /*tp_as_buffer*/
     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
-    Picklertype__doc__,         /* tp_doc */
-    (traverseproc) Pickler_traverse,    /* tp_traverse */
-    (inquiry) Pickler_clear,    /* tp_clear */
-    0,                          /* tp_richcompare */
-    0,                          /* tp_weaklistoffset */
-    0,                          /* tp_iter */
-    0,                          /* tp_iternext */
-    Pickler_methods,            /* tp_methods */
-    Pickler_members,            /* tp_members */
-    Pickler_getsets,            /* tp_getset */
+    Pickler_doc,                        /*tp_doc*/
+    (traverseproc)Pickler_traverse,     /*tp_traverse*/
+    (inquiry)Pickler_clear,             /*tp_clear*/
+    0,                                  /*tp_richcompare*/
+    0,                                  /*tp_weaklistoffset*/
+    0,                                  /*tp_iter*/
+    0,                                  /*tp_iternext*/
+    Pickler_methods,                    /*tp_methods*/
+    Pickler_members,                    /*tp_members*/
+    Pickler_getsets,                    /*tp_getset*/
+    0,                                  /*tp_base*/
+    0,                                  /*tp_dict*/
+    0,                                  /*tp_descr_get*/
+    0,                                  /*tp_descr_set*/
+    0,                                  /*tp_dictoffset*/
+    0,                                  /*tp_init*/
+    0,                                  /*tp_alloc*/
+    Pickler_new,                        /*tp_new*/
+    0,                                  /*tp_free*/
+    0,                                  /*tp_is_gc*/
 };
 
 static PyObject *
@@ -5008,56 +5020,6 @@
     return -1;
 }
 
-/* ---------------------------------------------------------------------------
- * Module-level functions.
- */
-
-/* dump(obj, file, protocol=0). */
-static PyObject *
-cpm_dump(PyObject *self, PyObject *args, PyObject *kwds)
-{
-    static char *kwlist[] = { "obj", "file", "protocol", NULL };
-    PyObject *ob, *file, *res = NULL;
-    Picklerobject *pickler = 0;
-    int proto = 0;
-
-    if (!(PyArg_ParseTupleAndKeywords(args, kwds, "OO|i", kwlist,
-                                      &ob, &file, &proto)))
-        goto finally;
-
-    if (!(pickler = newPicklerobject(file, proto)))
-        goto finally;
-
-    if (dump(pickler, ob) < 0)
-        goto finally;
-
-    Py_INCREF(Py_None);
-    res = Py_None;
-
-  finally:
-    Py_XDECREF(pickler);
-
-    return res;
-}
-
-/* load(fileobj). */
-static PyObject *
-cpm_load(PyObject *self, PyObject *ob)
-{
-    Unpicklerobject *unpickler = 0;
-    PyObject *res = NULL;
-
-    if (!(unpickler = newUnpicklerobject(ob)))
-        goto finally;
-
-    res = load(unpickler);
-
-  finally:
-    Py_XDECREF(unpickler);
-
-    return res;
-}
-
 PyDoc_STRVAR(Unpicklertype__doc__, "Objects that know how to unpickle");
 
 static PyTypeObject Unpicklertype = {
@@ -5087,47 +5049,6 @@
     (inquiry) Unpickler_clear,          /* tp_clear */
 };
 
-static struct PyMethodDef pickle_methods[] = {
-    {"dump", (PyCFunction) cpm_dump, METH_VARARGS | METH_KEYWORDS,
-     PyDoc_STR("dump(obj, file, protocol=0) -- "
-               "Write an object in pickle format to the given file.\n"
-               "\n"
-               "See the Pickler docstring for the meaning of optional argument proto.")
-     },
-
-    {"load", (PyCFunction) cpm_load, METH_O,
-     PyDoc_STR("load(file) -- Load a pickle from the given file")},
-
-    {"Pickler", (PyCFunction) get_Pickler, METH_VARARGS | METH_KEYWORDS,
-     PyDoc_STR("Pickler(file, protocol=0) -- Create a pickler.\n"
-               "\n"
-               "This takes a file-like object for writing a pickle data stream.\n"
-               "The optional proto argument tells the pickler to use the given\n"
-               "protocol; supported protocols are 0, 1, 2.  The default\n"
-               "protocol is 0, to be backwards compatible.  (Protocol 0 is the\n"
-               "only protocol that can be written to a file opened in text\n"
-               "mode and read back successfully.  When using a protocol higher\n"
-               "than 0, make sure the file is opened in binary mode, both when\n"
-               "pickling and unpickling.)\n"
-               "\n"
-               "Protocol 1 is more efficient than protocol 0; protocol 2 is\n"
-               "more efficient than protocol 1.\n"
-               "\n"
-               "Specifying a negative protocol version selects the highest\n"
-               "protocol version supported.  The higher the protocol used, the\n"
-               "more recent the version of Python needed to read the pickle\n"
-               "produced.\n"
-               "\n"
-               "The file parameter must have a write() method that accepts a single\n"
-               "string argument.  It can thus be an open file object, a StringIO\n"
-               "object, or any other custom object that meets this interface.\n")
-     },
-
-    {"Unpickler", (PyCFunction) get_Unpickler, METH_O,
-     PyDoc_STR("Unpickler(file) -- Create an unpickler.")},
-    {NULL, NULL}
-};
-
 static int
 init_stuff(PyObject *module_dict)
 {
@@ -5282,12 +5203,12 @@
         return;
 
     /* Create the module and add the functions */
-    m = Py_InitModule4("_pickle", pickle_methods,
-                       pickle_module_documentation,
-                       (PyObject *) NULL, PYTHON_API_VERSION);
+    m = Py_InitModule3("_pickle", NULL, pickle_module_documentation);
     if (m == NULL)
         return;
 
+    PyModule_AddObject(m, "Pickler", (PyObject *)&Picklertype);
+
     /* Add some symbolic constants to the module */
     d = PyModule_GetDict(m);
     v = PyString_FromString(rev);


More information about the Python-checkins mailing list