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

exarkun at codespeak.net exarkun at codespeak.net
Fri Apr 2 18:38:23 CEST 2010


Author: exarkun
Date: Fri Apr  2 18:38:21 2010
New Revision: 73302

Modified:
   pypy/branch/cpython-extension/pypy/module/cpyext/include/Python.h
   pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py
   pypy/branch/cpython-extension/pypy/module/cpyext/modsupport.py
   pypy/branch/cpython-extension/pypy/module/cpyext/test/test_cpyext.py
Log:
Add PyDoc_STRVAR and related macros; also extend PyMethodDef to take a docstring

Modified: pypy/branch/cpython-extension/pypy/module/cpyext/include/Python.h
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/include/Python.h	(original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/include/Python.h	Fri Apr  2 18:38:21 2010
@@ -9,6 +9,7 @@
 #define PY_LONG_LONG long long
 #define SIZEOF_LONG_LONG sizeof(PY_LONG_LONG)
 #define PY_FORMAT_SIZE_T "z"
+#define WITH_DOC_STRINGS
 
 /* Compat stuff */
 #ifndef _WIN32
@@ -69,4 +70,13 @@
 
 #include <pypy_decl.h>
 
+/* Define macros for inline documentation. */
+#define PyDoc_VAR(name) static char name[]
+#define PyDoc_STRVAR(name,str) PyDoc_VAR(name) = PyDoc_STR(str)
+#ifdef WITH_DOC_STRINGS
+#define PyDoc_STR(str) str
+#else
+#define PyDoc_STR(str) ""
+#endif
+
 #endif

Modified: pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py
==============================================================================
--- pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py	(original)
+++ pypy/branch/cpython-extension/pypy/module/cpyext/methodobject.py	Fri Apr  2 18:38:21 2010
@@ -15,9 +15,10 @@
 
 
 class W_PyCFunctionObject(Wrappable):
-    def __init__(self, space, ml, w_self):
+    def __init__(self, space, ml, w_self, doc=None):
         self.ml = ml
         self.w_self = w_self
+        self.doc = doc
 
     def call(self, space, w_self, args_tuple):
         # Call the C function
@@ -117,6 +118,7 @@
 W_PyCFunctionObject.typedef = TypeDef(
     'builtin_function_or_method',
     __call__ = interp2app(cfunction_descr_call),
+    __doc__ = interp_attrproperty('doc', cls=W_PyCFunctionObject),
     )
 W_PyCFunctionObject.typedef.acceptable_as_base_class = False
 

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	Fri Apr  2 18:38:21 2010
@@ -3,7 +3,7 @@
         METH_STATIC, METH_CLASS, METH_COEXIST, CANNOT_FAIL
 from pypy.module.cpyext.pyobject import PyObject, register_container
 from pypy.interpreter.module import Module
-from pypy.module.cpyext.methodobject import PyCFunction_NewEx, PyDescr_NewMethod
+from pypy.module.cpyext.methodobject import W_PyCFunctionObject, PyCFunction_NewEx, PyDescr_NewMethod
 from pypy.module.cpyext.pyerrors import PyErr_BadInternalCall
 from pypy.interpreter.error import OperationError
 
@@ -14,6 +14,7 @@
     [('ml_name', rffi.CCHARP),
      ('ml_meth', PyCFunction),
      ('ml_flags', rffi.INT_real),
+     ('ml_doc', rffi.CCHARP),
      ])
 
 def PyImport_AddModule(space, name):
@@ -51,11 +52,16 @@
 
             methodname = rffi.charp2str(method.c_ml_name)
             flags = rffi.cast(lltype.Signed, method.c_ml_flags)
+            if method.c_ml_doc:
+                doc = rffi.charp2str(method.c_ml_doc)
+            else:
+                doc = None
+
             if not pto:
                 if flags & METH_CLASS or flags & METH_STATIC:
                     raise OperationError(space.w_ValueError,
                             space.wrap("module functions cannot set METH_CLASS or METH_STATIC"))
-                w_obj = PyCFunction_NewEx(space, method, w_self)
+                w_obj = space.wrap(W_PyCFunctionObject(space, method, w_self, doc))
             else:
                 if methodname in dict_w and not (flags & METH_COEXIST):
                     continue
@@ -71,6 +77,7 @@
                     #w_obj = PyStaticMethod_New(space, w_func)
                 else:
                     w_obj = PyDescr_NewMethod(space, pto, method)
+
             dict_w[methodname] = w_obj
 
 

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	Fri Apr  2 18:38:21 2010
@@ -195,6 +195,29 @@
         assert module.return_pi is not None
         assert module.return_pi() == 3.14
 
+
+    def test_export_docstring(self):
+        import sys
+        init = """
+        if (Py_IsInitialized())
+            Py_InitModule("foo", methods);
+        """
+        body = """
+        PyDoc_STRVAR(foo_pi_doc, "Return pi.");
+        PyObject* foo_pi(PyObject* self, PyObject *args)
+        {
+            return PyFloat_FromDouble(3.14);
+        }
+        static PyMethodDef methods[] ={
+            { "return_pi", foo_pi, METH_NOARGS, foo_pi_doc },
+            { NULL }
+        };
+        """
+        module = self.import_module(name='foo', init=init, body=body)
+        doc = module.return_pi.__doc__
+        assert doc == "Return pi."
+
+
     def test_InitModule4(self):
         init = """
         PyObject *cookie = PyFloat_FromDouble(3.14);



More information about the Pypy-commit mailing list