bpo-20185: Convert the marshal module to Argument Clinic. (#541) · python/cpython@0767ad4 (original) (raw)
`@@ -14,6 +14,13 @@
`
14
14
`#include "marshal.h"
`
15
15
`#include "../Modules/hashtable.h"
`
16
16
``
``
17
`+
/*[clinic input]
`
``
18
`+
module marshal
`
``
19
`+
[clinic start generated code]*/
`
``
20
`+
/[clinic end generated code: output=da39a3ee5e6b4b0d input=c982b7930dee17db]/
`
``
21
+
``
22
`+
#include "clinic/marshal.c.h"
`
``
23
+
17
24
`/* High water mark to determine when the marshalled object is dangerously deep
`
18
25
` * and risks coring the interpreter. When the object stack gets this deep,
`
19
26
` * raise an exception instead of continuing.
`
`@@ -1632,42 +1639,62 @@ PyMarshal_WriteObjectToString(PyObject *x, int version)
`
1632
1639
`}
`
1633
1640
``
1634
1641
`/* And an interface for Python programs... */
`
``
1642
`+
/*[clinic input]
`
``
1643
`+
marshal.dump
`
``
1644
+
``
1645
`+
value: object
`
``
1646
`+
Must be a supported type.
`
``
1647
`+
file: object
`
``
1648
`+
Must be a writeable binary file.
`
``
1649
`+
version: int(c_default="Py_MARSHAL_VERSION") = version
`
``
1650
`+
Indicates the data format that dump should use.
`
``
1651
`+
/
`
``
1652
+
``
1653
`+
Write the value on the open file.
`
``
1654
+
``
1655
`+
If the value has (or contains an object that has) an unsupported type, a
`
``
1656
`+
ValueError exception is raised - but garbage data will also be written
`
``
1657
`+
to the file. The object will not be properly read back by load().
`
``
1658
`+
[clinic start generated code]*/
`
1635
1659
``
1636
1660
`static PyObject *
`
1637
``
`-
marshal_dump(PyObject *self, PyObject *args)
`
``
1661
`+
marshal_dump_impl(PyObject *module, PyObject *value, PyObject *file,
`
``
1662
`+
int version)
`
``
1663
`+
/[clinic end generated code: output=aaee62c7028a7cb2 input=6c7a3c23c6fef556]/
`
1638
1664
`{
`
1639
1665
`/* XXX Quick hack -- need to do this differently */
`
1640
``
`-
PyObject *x;
`
1641
``
`-
PyObject *f;
`
1642
``
`-
int version = Py_MARSHAL_VERSION;
`
1643
1666
`PyObject *s;
`
1644
1667
`PyObject *res;
`
1645
1668
`_Py_IDENTIFIER(write);
`
1646
1669
``
1647
``
`-
if (!PyArg_ParseTuple(args, "OO|i:dump", &x, &f, &version))
`
1648
``
`-
return NULL;
`
1649
``
`-
s = PyMarshal_WriteObjectToString(x, version);
`
``
1670
`+
s = PyMarshal_WriteObjectToString(value, version);
`
1650
1671
`if (s == NULL)
`
1651
1672
`return NULL;
`
1652
``
`-
res = _PyObject_CallMethodIdObjArgs(f, &PyId_write, s, NULL);
`
``
1673
`+
res = _PyObject_CallMethodIdObjArgs(file, &PyId_write, s, NULL);
`
1653
1674
`Py_DECREF(s);
`
1654
1675
`return res;
`
1655
1676
`}
`
1656
1677
``
1657
``
`-
PyDoc_STRVAR(dump_doc,
`
1658
``
`-
"dump(value, file[, version])\n\
`
1659
``
`-
\n\
`
1660
``
`-
Write the value on the open file. The value must be a supported type.\n\
`
1661
``
`-
The file must be a writeable binary file.\n\
`
1662
``
`-
\n\
`
1663
``
`-
If the value has (or contains an object that has) an unsupported type, a\n\
`
1664
``
`-
ValueError exception is raised - but garbage data will also be written\n\
`
1665
``
`-
to the file. The object will not be properly read back by load()\n\
`
1666
``
`-
\n\
`
1667
``
`-
The version argument indicates the data format that dump should use.");
`
``
1678
`+
/*[clinic input]
`
``
1679
`+
marshal.load
`
``
1680
+
``
1681
`+
file: object
`
``
1682
`+
Must be readable binary file.
`
``
1683
`+
/
`
``
1684
+
``
1685
`+
Read one value from the open file and return it.
`
``
1686
+
``
1687
`+
If no valid value is read (e.g. because the data has a different Python
`
``
1688
`+
version's incompatible marshal format), raise EOFError, ValueError or
`
``
1689
`+
TypeError.
`
``
1690
+
``
1691
`+
Note: If an object containing an unsupported type was marshalled with
`
``
1692
`+
dump(), load() will substitute None for the unmarshallable type.
`
``
1693
`+
[clinic start generated code]*/
`
1668
1694
``
1669
1695
`static PyObject *
`
1670
``
`-
marshal_load(PyObject *self, PyObject *f)
`
``
1696
`+
marshal_load(PyObject *module, PyObject *file)
`
``
1697
`+
/[clinic end generated code: output=f8e5c33233566344 input=c85c2b594cd8124a]/
`
1671
1698
`{
`
1672
1699
`PyObject *data, *result;
`
1673
1700
`_Py_IDENTIFIER(read);
`
`@@ -1680,19 +1707,19 @@ marshal_load(PyObject *self, PyObject *f)
`
1680
1707
` * This can be removed if we guarantee good error handling
`
1681
1708
` * for r_string()
`
1682
1709
` */
`
1683
``
`-
data = _PyObject_CallMethodId(f, &PyId_read, "i", 0);
`
``
1710
`+
data = _PyObject_CallMethodId(file, &PyId_read, "i", 0);
`
1684
1711
`if (data == NULL)
`
1685
1712
`return NULL;
`
1686
1713
`if (!PyBytes_Check(data)) {
`
1687
1714
`PyErr_Format(PyExc_TypeError,
`
1688
``
`-
"f.read() returned not bytes but %.100s",
`
``
1715
`+
"file.read() returned not bytes but %.100s",
`
1689
1716
`data->ob_type->tp_name);
`
1690
1717
`result = NULL;
`
1691
1718
` }
`
1692
1719
`else {
`
1693
1720
`rf.depth = 0;
`
1694
1721
`rf.fp = NULL;
`
1695
``
`-
rf.readable = f;
`
``
1722
`+
rf.readable = file;
`
1696
1723
`rf.current_filename = NULL;
`
1697
1724
`rf.ptr = rf.end = NULL;
`
1698
1725
`rf.buf = NULL;
`
`@@ -1708,50 +1735,48 @@ marshal_load(PyObject *self, PyObject *f)
`
1708
1735
`return result;
`
1709
1736
`}
`
1710
1737
``
1711
``
`-
PyDoc_STRVAR(load_doc,
`
1712
``
`-
"load(file)\n\
`
1713
``
`-
\n\
`
1714
``
`-
Read one value from the open file and return it. If no valid value is\n\
`
1715
``
`-
read (e.g. because the data has a different Python version's\n\
`
1716
``
`-
incompatible marshal format), raise EOFError, ValueError or TypeError.\n\
`
1717
``
`-
The file must be a readable binary file.\n\
`
1718
``
`-
\n\
`
1719
``
`-
Note: If an object containing an unsupported type was marshalled with\n\
`
1720
``
`-
dump(), load() will substitute None for the unmarshallable type.");
`
``
1738
`+
/*[clinic input]
`
``
1739
`+
marshal.dumps
`
``
1740
+
``
1741
`+
value: object
`
``
1742
`+
Must be a supported type.
`
``
1743
`+
version: int(c_default="Py_MARSHAL_VERSION") = version
`
``
1744
`+
Indicates the data format that dumps should use.
`
``
1745
`+
/
`
1721
1746
``
``
1747
`+
Return the bytes object that would be written to a file by dump(value, file).
`
``
1748
+
``
1749
`+
Raise a ValueError exception if value has (or contains an object that has) an
`
``
1750
`+
unsupported type.
`
``
1751
`+
[clinic start generated code]*/
`
1722
1752
``
1723
1753
`static PyObject *
`
1724
``
`-
marshal_dumps(PyObject *self, PyObject *args)
`
``
1754
`+
marshal_dumps_impl(PyObject *module, PyObject *value, int version)
`
``
1755
`+
/[clinic end generated code: output=9c200f98d7256cad input=a2139ea8608e9b27]/
`
1725
1756
`{
`
1726
``
`-
PyObject *x;
`
1727
``
`-
int version = Py_MARSHAL_VERSION;
`
1728
``
`-
if (!PyArg_ParseTuple(args, "O|i:dumps", &x, &version))
`
1729
``
`-
return NULL;
`
1730
``
`-
return PyMarshal_WriteObjectToString(x, version);
`
``
1757
`+
return PyMarshal_WriteObjectToString(value, version);
`
1731
1758
`}
`
1732
1759
``
1733
``
`-
PyDoc_STRVAR(dumps_doc,
`
1734
``
`-
"dumps(value[, version])\n\
`
1735
``
`-
\n\
`
1736
``
`-
Return the bytes object that would be written to a file by dump(value, file).\n\
`
1737
``
`-
The value must be a supported type. Raise a ValueError exception if\n\
`
1738
``
`-
value has (or contains an object that has) an unsupported type.\n\
`
1739
``
`-
\n\
`
1740
``
`-
The version argument indicates the data format that dumps should use.");
`
``
1760
`+
/*[clinic input]
`
``
1761
`+
marshal.loads
`
``
1762
+
``
1763
`+
bytes: Py_buffer
`
``
1764
`+
/
`
``
1765
+
``
1766
`+
Convert the bytes-like object to a value.
`
1741
1767
``
``
1768
`+
If no valid value is found, raise EOFError, ValueError or TypeError. Extra
`
``
1769
`+
bytes in the input are ignored.
`
``
1770
`+
[clinic start generated code]*/
`
1742
1771
``
1743
1772
`static PyObject *
`
1744
``
`-
marshal_loads(PyObject *self, PyObject *args)
`
``
1773
`+
marshal_loads_impl(PyObject *module, Py_buffer *bytes)
`
``
1774
`+
/[clinic end generated code: output=9fc65985c93d1bb1 input=6f426518459c8495]/
`
1745
1775
`{
`
1746
1776
`RFILE rf;
`
1747
``
`-
Py_buffer p;
`
1748
``
`-
char *s;
`
1749
``
`-
Py_ssize_t n;
`
``
1777
`+
char *s = bytes->buf;
`
``
1778
`+
Py_ssize_t n = bytes->len;
`
1750
1779
`PyObject* result;
`
1751
``
`-
if (!PyArg_ParseTuple(args, "y*:loads", &p))
`
1752
``
`-
return NULL;
`
1753
``
`-
s = p.buf;
`
1754
``
`-
n = p.len;
`
1755
1780
`rf.fp = NULL;
`
1756
1781
`rf.readable = NULL;
`
1757
1782
`rf.current_filename = NULL;
`
`@@ -1761,23 +1786,15 @@ marshal_loads(PyObject *self, PyObject *args)
`
1761
1786
`if ((rf.refs = PyList_New(0)) == NULL)
`
1762
1787
`return NULL;
`
1763
1788
`result = read_object(&rf);
`
1764
``
`-
PyBuffer_Release(&p);
`
1765
1789
`Py_DECREF(rf.refs);
`
1766
1790
`return result;
`
1767
1791
`}
`
1768
1792
``
1769
``
`-
PyDoc_STRVAR(loads_doc,
`
1770
``
`-
"loads(bytes)\n\
`
1771
``
`-
\n\
`
1772
``
`-
Convert the bytes-like object to a value. If no valid value is found,\n\
`
1773
``
`-
raise EOFError, ValueError or TypeError. Extra bytes in the input are\n\
`
1774
``
`-
ignored.");
`
1775
``
-
1776
1793
`static PyMethodDef marshal_methods[] = {
`
1777
``
`-
{"dump", marshal_dump, METH_VARARGS, dump_doc},
`
1778
``
`-
{"load", marshal_load, METH_O, load_doc},
`
1779
``
`-
{"dumps", marshal_dumps, METH_VARARGS, dumps_doc},
`
1780
``
`-
{"loads", marshal_loads, METH_VARARGS, loads_doc},
`
``
1794
`+
MARSHAL_DUMP_METHODDEF
`
``
1795
`+
MARSHAL_LOAD_METHODDEF
`
``
1796
`+
MARSHAL_DUMPS_METHODDEF
`
``
1797
`+
MARSHAL_LOADS_METHODDEF
`
1781
1798
` {NULL, NULL} /* sentinel */
`
1782
1799
`};
`
1783
1800
``