diff -r 565773aabafb Python/marshal.c --- a/Python/marshal.c Tue Jan 14 22:22:41 2014 -0800 +++ b/Python/marshal.c Wed Jan 15 18:46:09 2014 +0800 @@ -62,6 +62,11 @@ #define WFERR_NESTEDTOODEEP 2 #define WFERR_NOMEMORY 3 +/*[clinic input] +module marshal +[clinic start generated code]*/ +/*[clinic end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ + typedef struct { FILE *fp; int error; /* see WFERR_* values */ @@ -1553,41 +1558,94 @@ } /* And an interface for Python programs... */ +/*[clinic input] +marshal.dump + + value: object + file: object + [ + version: int(c_default="Py_MARSHAL_VERSION") = 2 + ] + / + +Write the value on the open file. + +The value must be a supported type. The file must be an open file object such +as sys.stdout or returned by open() or os.popen(). It must be opened in binary +mode ('wb' or 'w+b'). + +If the value has (or contains an object that has) an unsupported type, a +ValueError exception is raised — but garbage data will also be written to the +file. The object will not be properly read back by load(). + +The version argument indicates the data format that dump should use. +[clinic start generated code]*/ + +PyDoc_STRVAR(marshal_dump__doc__, +"dump(value, file, [version=2])\n" +"Write the value on the open file.\n" +"\n" +"The value must be a supported type. The file must be an open file object such\n" +"as sys.stdout or returned by open() or os.popen(). It must be opened in binary\n" +"mode (\'wb\' or \'w+b\').\n" +"\n" +"If the value has (or contains an object that has) an unsupported type, a\n" +"ValueError exception is raised — but garbage data will also be written to the\n" +"file. The object will not be properly read back by load().\n" +"\n" +"The version argument indicates the data format that dump should use."); + +#define MARSHAL_DUMP_METHODDEF \ + {"dump", (PyCFunction)marshal_dump, METH_VARARGS, marshal_dump__doc__}, static PyObject * -marshal_dump(PyObject *self, PyObject *args) +marshal_dump_impl(PyModuleDef *module, PyObject *value, PyObject *file, int group_right_1, int version); + +static PyObject * +marshal_dump(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + PyObject *value; + PyObject *file; + int group_right_1 = 0; + int version = Py_MARSHAL_VERSION; + + switch (PyTuple_Size(args)) { + case 2: + if (!PyArg_ParseTuple(args, "OO:dump", &value, &file)) + return NULL; + break; + case 3: + if (!PyArg_ParseTuple(args, "OOi:dump", &value, &file, &version)) + return NULL; + group_right_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "marshal.dump requires 2 to 3 arguments"); + return NULL; + } + return_value = marshal_dump_impl(module, value, file, group_right_1, version); + + return return_value; +} + +static PyObject * +marshal_dump_impl(PyModuleDef *module, PyObject *value, PyObject *file, int group_right_1, int version) +/*[clinic end generated code: checksum=6e27acba6025400c85ab35d67f24655119e498d2]*/ { /* XXX Quick hack -- need to do this differently */ - PyObject *x; - PyObject *f; - int version = Py_MARSHAL_VERSION; PyObject *s; PyObject *res; _Py_IDENTIFIER(write); - if (!PyArg_ParseTuple(args, "OO|i:dump", &x, &f, &version)) - return NULL; - s = PyMarshal_WriteObjectToString(x, version); + s = PyMarshal_WriteObjectToString(value, version); if (s == NULL) return NULL; - res = _PyObject_CallMethodId(f, &PyId_write, "O", s); + res = _PyObject_CallMethodId(file, &PyId_write, "O", s); Py_DECREF(s); return res; } -PyDoc_STRVAR(dump_doc, -"dump(value, file[, version])\n\ -\n\ -Write the value on the open file. The value must be a supported type.\n\ -The file must be an open file object such as sys.stdout or returned by\n\ -open() or os.popen(). It must be opened in binary mode ('wb' or 'w+b').\n\ -\n\ -If the value has (or contains an object that has) an unsupported type, a\n\ -ValueError exception is raised — but garbage data will also be written\n\ -to the file. The object will not be properly read back by load()\n\ -\n\ -The version argument indicates the data format that dump should use."); - static PyObject * marshal_load(PyObject *self, PyObject *f) { @@ -1643,38 +1701,127 @@ dump(), load() will substitute None for the unmarshallable type."); +/*[clinic input] +marshal.dumps + + value: object + [ + version: int(c_default="Py_MARSHAL_VERSION") = 2 + ] + / + +Return the string that would be written to a file by dump(value, file) + +The value must be a supported type. Raise a ValueError exception if +value has (or contains an object that has) an unsupported type. + +The version argument indicates the data format that dumps should use. +[clinic start generated code]*/ + +PyDoc_STRVAR(marshal_dumps__doc__, +"dumps(value, [version=2])\n" +"Return the string that would be written to a file by dump(value, file)\n" +"\n" +"The value must be a supported type. Raise a ValueError exception if\n" +"value has (or contains an object that has) an unsupported type.\n" +"\n" +"The version argument indicates the data format that dumps should use."); + +#define MARSHAL_DUMPS_METHODDEF \ + {"dumps", (PyCFunction)marshal_dumps, METH_VARARGS, marshal_dumps__doc__}, + static PyObject * -marshal_dumps(PyObject *self, PyObject *args) +marshal_dumps_impl(PyModuleDef *module, PyObject *value, int group_right_1, int version); + +static PyObject * +marshal_dumps(PyModuleDef *module, PyObject *args) { - PyObject *x; + PyObject *return_value = NULL; + PyObject *value; + int group_right_1 = 0; int version = Py_MARSHAL_VERSION; - if (!PyArg_ParseTuple(args, "O|i:dumps", &x, &version)) - return NULL; - return PyMarshal_WriteObjectToString(x, version); + + switch (PyTuple_Size(args)) { + case 1: + if (!PyArg_ParseTuple(args, "O:dumps", &value)) + return NULL; + break; + case 2: + if (!PyArg_ParseTuple(args, "Oi:dumps", &value, &version)) + return NULL; + group_right_1 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "marshal.dumps requires 1 to 2 arguments"); + return NULL; + } + return_value = marshal_dumps_impl(module, value, group_right_1, version); + + return return_value; } -PyDoc_STRVAR(dumps_doc, -"dumps(value[, version])\n\ -\n\ -Return the string that would be written to a file by dump(value, file).\n\ -The value must be a supported type. Raise a ValueError exception if\n\ -value has (or contains an object that has) an unsupported type.\n\ -\n\ -The version argument indicates the data format that dumps should use."); +static PyObject * +marshal_dumps_impl(PyModuleDef *module, PyObject *value, int group_right_1, int version) +/*[clinic end generated code: checksum=08627b98f0da540bfd1e0db8028ea7b113dde70d]*/ +{ + return PyMarshal_WriteObjectToString(value, version); +} +/*[clinic input] +marshal.loads + + byte: Py_buffer + / + +Convert the bytes object to a value. + +If no valid value is found, raise EOFError, ValueError or TypeError. Extra +characters in the input are ignored. +[clinic start generated code]*/ + +PyDoc_STRVAR(marshal_loads__doc__, +"loads(byte)\n" +"Convert the bytes object to a value.\n" +"\n" +"If no valid value is found, raise EOFError, ValueError or TypeError. Extra\n" +"characters in the input are ignored."); + +#define MARSHAL_LOADS_METHODDEF \ + {"loads", (PyCFunction)marshal_loads, METH_VARARGS, marshal_loads__doc__}, static PyObject * -marshal_loads(PyObject *self, PyObject *args) +marshal_loads_impl(PyModuleDef *module, Py_buffer *byte); + +static PyObject * +marshal_loads(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + Py_buffer byte = {NULL, NULL}; + + if (!PyArg_ParseTuple(args, + "y*:loads", + &byte)) + goto exit; + return_value = marshal_loads_impl(module, &byte); + +exit: + /* Cleanup for byte */ + if (byte.obj) + PyBuffer_Release(&byte); + + return return_value; +} + +static PyObject * +marshal_loads_impl(PyModuleDef *module, Py_buffer *byte) +/*[clinic end generated code: checksum=fd9110c707a921161fb9911caacc22f18cdb90c5]*/ { RFILE rf; - Py_buffer p; char *s; Py_ssize_t n; PyObject* result; - if (!PyArg_ParseTuple(args, "y*:loads", &p)) - return NULL; - s = p.buf; - n = p.len; + s = byte->buf; + n = byte->len; rf.fp = NULL; rf.readable = NULL; rf.current_filename = NULL; @@ -1684,23 +1831,16 @@ if ((rf.refs = PyList_New(0)) == NULL) return NULL; result = read_object(&rf); - PyBuffer_Release(&p); + PyBuffer_Release(byte); Py_DECREF(rf.refs); return result; } -PyDoc_STRVAR(loads_doc, -"loads(bytes)\n\ -\n\ -Convert the bytes object to a value. If no valid value is found, raise\n\ -EOFError, ValueError or TypeError. Extra characters in the input are\n\ -ignored."); - static PyMethodDef marshal_methods[] = { - {"dump", marshal_dump, METH_VARARGS, dump_doc}, + MARSHAL_DUMP_METHODDEF {"load", marshal_load, METH_O, load_doc}, - {"dumps", marshal_dumps, METH_VARARGS, dumps_doc}, - {"loads", marshal_loads, METH_VARARGS, loads_doc}, + MARSHAL_DUMPS_METHODDEF + MARSHAL_LOADS_METHODDEF {NULL, NULL} /* sentinel */ };