[Python-checkins] r56240 - python/branches/cpy_merge/Modules/_picklemodule.c
alexandre.vassalotti
python-checkins at python.org
Tue Jul 10 16:13:31 CEST 2007
Author: alexandre.vassalotti
Date: Tue Jul 10 16:13:31 2007
New Revision: 56240
Modified:
python/branches/cpy_merge/Modules/_picklemodule.c
Log:
Add basic subclassing support to Unpickler.
Fix docstring of Pickler and Unpickler.
Fix a reference leak in Pickler.
Modified: python/branches/cpy_merge/Modules/_picklemodule.c
==============================================================================
--- python/branches/cpy_merge/Modules/_picklemodule.c (original)
+++ python/branches/cpy_merge/Modules/_picklemodule.c Tue Jul 10 16:13:31 2007
@@ -2438,11 +2438,12 @@
self->dispatch_table = dispatch_table;
Py_INCREF(file);
+ self->file = 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 io_error;
+ goto error;
}
self->write_func = write_file;
}
@@ -2452,13 +2453,13 @@
PyErr_Clear();
PyErr_SetString(PyExc_TypeError,
"argument must have 'write' " "attribute");
- goto io_error;
+ goto error;
}
self->write_buf = (char *) PyMem_Malloc(WRITE_BUF_SIZE);
if (self->write_buf == NULL) {
PyErr_NoMemory();
- goto io_error;
+ goto error;
}
self->write_func = write_other;
}
@@ -2466,8 +2467,6 @@
PyObject_GC_Track(self);
return (PyObject *) self;
- io_error:
- Py_DECREF(file);
error:
Py_DECREF(self);
return NULL;
@@ -2477,6 +2476,7 @@
Pickler_dealloc(PicklerObject *self)
{
PyObject_GC_UnTrack(self);
+ Py_XDECREF(self->file);
Py_XDECREF(self->write);
Py_XDECREF(self->memo);
Py_XDECREF(self->fast_memo);
@@ -2604,11 +2604,12 @@
};
PyDoc_STRVAR(Pickler_doc,
-"Pickler(file, protocol=0) -- Create a pickler.\n"
+"Pickler(file, protocol=0) -> new pickler object"
"\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"
+"\n"
+"The optional protocol argument tells the pickler to use the\n"
+"given 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"
@@ -4812,17 +4813,23 @@
};
-static UnpicklerObject *
-newUnpicklerObject(PyObject *f)
+static PyObject *
+Unpickler_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
+ static char *kwlist[] = { "file", NULL };
UnpicklerObject *self;
+ PyObject *file;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:Unpickler",
+ kwlist, &file))
+ return NULL;
- if (!(self = PyObject_GC_New(UnpicklerObject, &Unpickler_Type)))
+ self = PyObject_GC_New(UnpicklerObject, &Unpickler_Type);
+ if (self == NULL)
return NULL;
- self->file = NULL;
+ self->fp = NULL;
self->arg = NULL;
- self->stack = (Pdata *) Pdata_New();
self->pers_func = NULL;
self->last_string = NULL;
self->marks = NULL;
@@ -4833,18 +4840,19 @@
self->readline = NULL;
self->find_class = NULL;
- if (!(self->memo = PyDict_New()))
+ self->memo = PyDict_New();
+ if (self->memo == NULL)
goto error;
- if (!self->stack)
+ self->stack = (Pdata *) Pdata_New();
+ if (self->stack == NULL)
goto error;
- Py_INCREF(f);
- self->file = f;
-
- /* Set read, readline based on type of f */
- if (PyFile_Check(f)) {
- self->fp = PyFile_AsFile(f);
+ Py_INCREF(file);
+ self->file = file;
+ /* Set read, readline based on type of 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 error;
@@ -4853,37 +4861,27 @@
self->readline_func = readline_file;
}
else {
-
- self->fp = NULL;
- self->read_func = read_other;
- self->readline_func = readline_other;
-
- if (!((self->readline = PyObject_GetAttr(f, readline_str)) &&
- (self->read = PyObject_GetAttr(f, read_str)))) {
+ self->readline = PyObject_GetAttr(file, readline_str);
+ self->read = PyObject_GetAttr(file, read_str);
+ if (self->readline == NULL || self->read == NULL) {
PyErr_Clear();
PyErr_SetString(PyExc_TypeError,
"argument must have 'read' and "
"'readline' attributes");
goto error;
}
+ self->read_func = read_other;
+ self->readline_func = readline_other;
}
- PyObject_GC_Track(self);
- return self;
+ PyObject_GC_Track(self);
+ return (PyObject *)self;
error:
- Py_DECREF((PyObject *) self);
+ Py_DECREF(self);
return NULL;
}
-
-static PyObject *
-get_Unpickler(PyObject *self, PyObject *file)
-{
- return (PyObject *) newUnpicklerObject(file);
-}
-
-
static void
Unpickler_dealloc(UnpicklerObject *self)
{
@@ -5020,33 +5018,62 @@
return -1;
}
-PyDoc_STRVAR(Unpickler_Type__doc__, "Objects that know how to unpickle");
+PyDoc_STRVAR(Unpickler_doc,
+"Unpickler(file) -> new unpickler object"
+"\n"
+"This takes a file-like object for reading a pickle data stream.\n"
+"\n"
+"The protocol version of the pickle is detected automatically, so no\n"
+"proto argument is needed.\n"
+"\n"
+"The file-like object must have two methods, a read() method that\n"
+"takes an integer argument, and a readline() method that requires no\n"
+"arguments. Both methods should return a string. Thus file-like\n"
+"object can be a file object opened for reading, a StringIO object,\n"
+"or any other custom object that meets this interface.\n");
static PyTypeObject Unpickler_Type = {
PyObject_HEAD_INIT(NULL)
- 0, /*ob_size */
- "_pickle.Unpickler", /*tp_name */
- sizeof(UnpicklerObject), /*tp_basicsize */
- 0,
- (destructor) Unpickler_dealloc, /* tp_dealloc */
- 0, /* tp_print */
- (getattrfunc) Unpickler_getattr, /* tp_getattr */
- (setattrfunc) Unpickler_setattr, /* 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 */
- 0, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer */
+ 0, /*ob_size*/
+ "_pickle.Unpickler", /*tp_name*/
+ sizeof(UnpicklerObject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ (destructor)Unpickler_dealloc, /*tp_dealloc*/
+ 0, /*tp_print*/
+ (getattrfunc)Unpickler_getattr, /*tp_getattr*/
+ (setattrfunc)Unpickler_setattr, /*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*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
- Unpickler_Type__doc__, /* tp_doc */
- (traverseproc) Unpickler_traverse, /* tp_traverse */
- (inquiry) Unpickler_clear, /* tp_clear */
+ Unpickler_doc, /*tp_doc*/
+ (traverseproc)Unpickler_traverse, /*tp_traverse*/
+ (inquiry)Unpickler_clear, /*tp_clear*/
+ 0, /*tp_richcompare*/
+ 0, /*tp_weaklistoffset*/
+ 0, /*tp_iter*/
+ 0, /*tp_iternext*/
+ 0, /*tp_methods*/
+ 0, /*tp_members*/
+ 0, /*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*/
+ Unpickler_new, /*tp_new*/
+ 0, /*tp_free*/
+ 0, /*tp_is_gc*/
};
static int
@@ -5208,6 +5235,7 @@
return;
PyModule_AddObject(m, "Pickler", (PyObject *)&Pickler_Type);
+ PyModule_AddObject(m, "Unpickler", (PyObject *)&Unpickler_Type);
/* Add some symbolic constants to the module */
d = PyModule_GetDict(m);
More information about the Python-checkins
mailing list