[pypy-svn] r72725 - in pypy/branch/cpython-extension/pypy/module/cpyext: . include test

afa at codespeak.net afa at codespeak.net
Wed Mar 24 16:09:20 CET 2010


Author: afa
Date: Wed Mar 24 16:09:18 2010
New Revision: 72725

Modified:
   pypy/branch/cpython-extension/pypy/module/cpyext/api.py
   pypy/branch/cpython-extension/pypy/module/cpyext/include/modsupport.h
   pypy/branch/cpython-extension/pypy/module/cpyext/modsupport.py
   pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py
Log:
Add support for Py_InitModule4: 
module docstring and "cookie" object passed to every function of the module.


Modified: pypy/branch/cpython-extension/pypy/module/cpyext/api.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/api.py	(original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/api.py	Wed Mar 24 16:09:18 2010
@@ -226,7 +226,10 @@
             arg = args[i]
             if (typ is PyObject and
                 callable.api_func.argnames[i].startswith('w_')):
-                arg = from_ref(space, arg)
+                if arg:
+                    arg = from_ref(space, arg)
+                else:
+                    arg = None
             boxed_args.append(arg)
         state = space.fromcache(State)
         try:

Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/modsupport.h
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/include/modsupport.h	(original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/include/modsupport.h	Wed Mar 24 16:09:18 2010
@@ -7,7 +7,21 @@
 extern "C" {
 #endif
 
-PyObject *Py_InitModule(const char* name, PyMethodDef* methods);
+#define PYTHON_API_VERSION 1013
+#define PYTHON_API_STRING "1013"
+
+PyObject *Py_InitModule4(const char* name, PyMethodDef* methods,
+                         const char *doc, PyObject *self,
+                         int apiver);
+
+#define Py_InitModule(name, methods) \
+	Py_InitModule4(name, methods, (char *)NULL, (PyObject *)NULL, \
+		       PYTHON_API_VERSION)
+
+#define Py_InitModule3(name, methods, doc) \
+	Py_InitModule4(name, methods, doc, (PyObject *)NULL, \
+		       PYTHON_API_VERSION)
+
 PyObject * PyModule_GetDict(PyObject *);
 
 

Modified: pypy/branch/cpython-extension/pypy/module/cpyext/modsupport.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/modsupport.py	(original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/modsupport.py	Wed Mar 24 16:09:18 2010
@@ -22,18 +22,22 @@
     space.setitem(w_modules, w_name, w_mod)
     return w_mod
 
- at cpython_api([rffi.CCHARP, lltype.Ptr(PyMethodDef)], PyObject, borrowed=True)
-def Py_InitModule(space, name, methods):
+ at cpython_api([rffi.CCHARP, lltype.Ptr(PyMethodDef), rffi.CCHARP,
+              PyObject, rffi.INT_real], PyObject, borrowed=True)
+def Py_InitModule4(space, name, methods, doc, w_self, apiver):
     modname = rffi.charp2str(name)
     w_mod = PyImport_AddModule(space, modname)
     dict_w = {}
-    convert_method_defs(space, dict_w, methods, None)
+    convert_method_defs(space, dict_w, methods, None, w_self)
     for key, w_value in dict_w.items():
         space.setattr(w_mod, space.wrap(key), w_value)
+    if doc:
+        space.setattr(w_mod, space.wrap("__doc__"),
+                      space.wrap(rffi.charp2str(doc)))
     return w_mod
 
 
-def convert_method_defs(space, dict_w, methods, pto):
+def convert_method_defs(space, dict_w, methods, pto, w_self=None):
     methods = rffi.cast(rffi.CArrayPtr(PyMethodDef), methods)
     if methods:
         i = -1
@@ -48,7 +52,7 @@
                 if flags & METH_CLASS or flags & METH_STATIC:
                     raise OperationError(space.w_ValueError,
                             "module functions cannot set METH_CLASS or METH_STATIC")
-                w_obj = PyCFunction_NewEx(space, method, None)
+                w_obj = PyCFunction_NewEx(space, method, w_self)
             else:
                 if methodname in dict_w and not (flags & METH_COEXIST):
                     continue

Modified: pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py	(original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py	Wed Mar 24 16:09:18 2010
@@ -23,9 +23,8 @@
 
 class TestApi:
     def test_signature(self):
-        assert 'Py_InitModule' in api.FUNCTIONS
-        assert api.FUNCTIONS['Py_InitModule'].argtypes == [
-            rffi.CCHARP, lltype.Ptr(api.TYPES['PyMethodDef'])]
+        assert 'PyModule_Check' in api.FUNCTIONS
+        assert api.FUNCTIONS['PyModule_Check'].argtypes == [api.PyObject]
 
     def test_padding(self):
         T = api.get_padded_type(api.PyObject.TO, 42)
@@ -173,6 +172,33 @@
         assert module.return_pi is not None
         assert module.return_pi() == 3.14
 
+    def test_InitModule4(self):
+        init = """
+        PyObject *cookie = PyFloat_FromDouble(3.14);
+        Py_InitModule4("foo", methods, "docstring",
+                       cookie, PYTHON_API_VERSION);
+        Py_DECREF(cookie);
+        """
+        body = """
+        PyObject* return_cookie(PyObject* self, PyObject *args)
+        {
+            if (self)
+            {
+                Py_INCREF(self);
+                return self;
+            }
+            else
+                Py_RETURN_FALSE;
+        }
+        static PyMethodDef methods[] = {
+            { "return_cookie", return_cookie, METH_NOARGS },
+            { NULL }
+        };
+        """
+        module = self.import_module(name='foo', init=init, body=body)
+        assert module.__doc__ == "docstring"
+        assert module.return_cookie() == 3.14
+
     def test_export_function2(self):
         import sys
         init = """



More information about the Pypy-commit mailing list