Author: Armin Rigo <[email protected]>
Branch: 
Changeset: r94527:d18c31e806d6
Date: 2018-05-12 09:47 +0200
http://bitbucket.org/pypy/pypy/changeset/d18c31e806d6/

Log:    Issue #2823

        Implement PyMarshal_ReadObjectFromString and
        PyMarshal_WriteObjectToString

diff --git a/pypy/module/cpyext/__init__.py b/pypy/module/cpyext/__init__.py
--- a/pypy/module/cpyext/__init__.py
+++ b/pypy/module/cpyext/__init__.py
@@ -77,6 +77,7 @@
 import pypy.module.cpyext.pystrtod
 import pypy.module.cpyext.pytraceback
 import pypy.module.cpyext.methodobject
+import pypy.module.cpyext.marshal
 
 # now that all rffi_platform.Struct types are registered, configure them
 api.configure_types()
diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py
--- a/pypy/module/cpyext/api.py
+++ b/pypy/module/cpyext/api.py
@@ -60,7 +60,7 @@
 
 configure_eci = ExternalCompilationInfo(
         include_dirs=include_dirs,
-        includes=['Python.h', 'stdarg.h', 'structmember.h'],
+        includes=['Python.h', 'stdarg.h', 'structmember.h', 'marshal.h'],
         compile_extra=['-DPy_BUILD_CORE'])
 
 class CConfig:
@@ -118,6 +118,7 @@
 pypy_decl = 'pypy_decl.h'
 udir.join(pypy_decl).write("/* Will be filled later */\n")
 udir.join('pypy_structmember_decl.h').write("/* Will be filled later */\n")
+udir.join('pypy_marshal_decl.h').write("/* Will be filled later */\n")
 udir.join('pypy_macros.h').write("/* Will be filled later */\n")
 
 constant_names = """
@@ -1221,14 +1222,11 @@
         global_objects.append('PyTypeObject _PyExc_%s;' % name)
     global_code = '\n'.join(global_objects)
 
-    prologue = ("#include <Python.h>\n"
-                "#include <structmember.h>\n"
+    prologue = ("#include <Python.h>\n" +
+                "#include <structmember.h>\n" +
+                "#include <marshal.h>\n" +
+                ("#include <pypy_numpy.h>\n" if use_micronumpy else "") +
                 "#include <src/thread.c>\n")
-    if use_micronumpy:
-        prologue = ("#include <Python.h>\n"
-                    "#include <structmember.h>\n"
-                    "#include <pypy_numpy.h>\n"
-                    "#include <src/thread.c>\n")
     code = (prologue +
             struct_declaration_code +
             global_code +
diff --git a/pypy/module/cpyext/include/marshal.h 
b/pypy/module/cpyext/include/marshal.h
new file mode 100644
--- /dev/null
+++ b/pypy/module/cpyext/include/marshal.h
@@ -0,0 +1,13 @@
+#ifndef Py_MARSHAL_H
+#define Py_MARSHAL_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define Py_MARSHAL_VERSION 2
+#include "pypy_marshal_decl.h"
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* !Py_MARSHAL_H */
diff --git a/pypy/module/cpyext/marshal.py b/pypy/module/cpyext/marshal.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/cpyext/marshal.py
@@ -0,0 +1,17 @@
+from rpython.rtyper.lltypesystem import rffi, lltype
+from pypy.module.cpyext.api import cpython_api, Py_ssize_t
+from pypy.module.cpyext.pyobject import PyObject
+
+
+_HEADER = 'pypy_marshal_decl.h'
+
+@cpython_api([rffi.CCHARP, Py_ssize_t], PyObject, header=_HEADER)
+def PyMarshal_ReadObjectFromString(space, p, size):
+    from pypy.module.marshal.interp_marshal import loads
+    s = rffi.charpsize2str(p, size)
+    return loads(space, space.newbytes(s))
+
+@cpython_api([PyObject, rffi.INT_real], PyObject, header=_HEADER)
+def PyMarshal_WriteObjectToString(space, w_x, version):
+    from pypy.module.marshal.interp_marshal import dumps
+    return dumps(space, w_x, space.newint(version))
diff --git a/pypy/module/cpyext/test/test_marshal.py 
b/pypy/module/cpyext/test/test_marshal.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/cpyext/test/test_marshal.py
@@ -0,0 +1,33 @@
+from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase
+
+
+class AppTestMarshal(AppTestCpythonExtensionBase):
+    def test_PyMarshal_ReadObjectFromString(self):
+        module = self.import_extension('foo', [
+            ("mloads", "METH_O",
+             """
+                 char *input = PyString_AsString(args);
+                 Py_ssize_t length = PyString_Size(args);
+                 return PyMarshal_ReadObjectFromString(input, length);
+             """)],
+            prologue='#include <marshal.h>')
+        import marshal
+        assert module.mloads(marshal.dumps(42.5)) == 42.5
+        x = [None, True, (4, 5), b"adkj", u"\u1234"]
+        assert module.mloads(marshal.dumps(x)) == x
+
+    def test_PyMarshal_WriteObjectToString(self):
+        module = self.import_extension('foo', [
+            ("mdumps", "METH_VARARGS",
+             """
+                 PyObject *obj;
+                 int version;
+                 if (!PyArg_ParseTuple(args, "Oi", &obj, &version))
+                     return NULL;
+                 return PyMarshal_WriteObjectToString(obj, version);
+             """)],
+            prologue='#include <marshal.h>')
+        import marshal
+        for x in [42, b"foo", u"\u2345", (4, None, False)]:
+            for version in [0, 1, 2]:
+                assert module.mdumps(x, version) == marshal.dumps(x, version)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to