[pypy-svn] r25766 - in pypy/dist/pypy/translator/c: . src test

tismer at codespeak.net tismer at codespeak.net
Thu Apr 13 08:25:11 CEST 2006


Author: tismer
Date: Thu Apr 13 08:25:00 2006
New Revision: 25766

Modified:
   pypy/dist/pypy/translator/c/genc.py
   pypy/dist/pypy/translator/c/pyobj.py
   pypy/dist/pypy/translator/c/src/module.h
   pypy/dist/pypy/translator/c/test/test_wrapping.py
   pypy/dist/pypy/translator/c/wrapper.py
Log:
nicer wrapped function names, support for docstrings everywhere

Modified: pypy/dist/pypy/translator/c/genc.py
==============================================================================
--- pypy/dist/pypy/translator/c/genc.py	(original)
+++ pypy/dist/pypy/translator/c/genc.py	Thu Apr 13 08:25:00 2006
@@ -12,7 +12,7 @@
 from pypy.tool.udir import udir
 from pypy.tool import isolate
 from pypy.translator.locality.calltree import CallTree
-from pypy.translator.c.support import log
+from pypy.translator.c.support import log, c_string_constant
 from pypy.rpython.typesystem import getfunctionptr
 
 class CBuilder(object):
@@ -669,13 +669,14 @@
     print >> f, 'static globalfunctiondef_t globalfunctiondefs[] = {'
     wrappers = pyobjmaker.wrappers.items()
     wrappers.sort()
-    for globalobject_name, (base_name, wrapper_name) in wrappers:
+    for globalobject_name, (base_name, wrapper_name, func_doc) in wrappers:
         print >> f, ('\t{&%s, "%s", {"%s", (PyCFunction)%s, '
-                     'METH_VARARGS|METH_KEYWORDS}},' % (
+                     'METH_VARARGS|METH_KEYWORDS, %s}},' % (
             globalobject_name,
             globalobject_name,
             base_name,
-            wrapper_name))
+            wrapper_name,
+            c_string_constant(func_doc or '')))
     print >> f, '\t{ NULL }\t/* Sentinel */'
     print >> f, '};'
     print >> f, 'static globalfunctiondef_t *globalfunctiondefsptr = &globalfunctiondefs[0];'

Modified: pypy/dist/pypy/translator/c/pyobj.py
==============================================================================
--- pypy/dist/pypy/translator/c/pyobj.py	(original)
+++ pypy/dist/pypy/translator/c/pyobj.py	Thu Apr 13 08:25:00 2006
@@ -38,6 +38,7 @@
         self.wrappers = {}    # {'pycfunctionvariable': ('name', 'wrapperfn')}
         self.import_hints = {} # I don't seem to need it any longer.
         # leaving the import support intact, doesn't hurt.
+        self.name_for_meth = {} # get nicer wrapper names
 
     def nameof(self, obj, debug=None):
         if debug:
@@ -208,9 +209,9 @@
         if self.shouldskipfunc(func):
             return self.skipped_function(func)
 
-        fwrapper = gen_wrapper(func, self.translator)
+        fwrapper = gen_wrapper(func, self.translator, self.name_for_meth.get(func, func.__name__))
         pycfunctionobj = self.uniquename('gfunc_' + func.__name__)
-        self.wrappers[pycfunctionobj] = func.__name__, self.getvalue(fwrapper)
+        self.wrappers[pycfunctionobj] = func.__name__, self.getvalue(fwrapper), func.__doc__
         return pycfunctionobj
 
     def import_function(self, func):
@@ -538,14 +539,14 @@
             content.sort()
             for key, value in content:
                 if key.startswith('__'):
-                    if key in ['__module__', '__doc__', '__dict__',
+                    if key in ['__module__', '__dict__', '__doc__',
                                '__weakref__', '__repr__', '__metaclass__']:
                         continue
                 if self.shouldskipfunc(value):
                     log.WARNING("skipped class function: %r" % value)
                     continue
-#                yield '%s.%s = property(lambda self:%s.__get__(self.__self__))' % (
-#                    name, key, self.nameof(value))
+                if callable(value):
+                    self.name_for_meth[value] = '%s.%s' % (cls.__name__, value.__name__)
                 yield '%s.%s = %s' % (name, key, self.nameof(value))
 
         baseargs = ", ".join(basenames)
@@ -554,6 +555,8 @@
             
         a = self.initcode.append
         a('class %s%s:'                     % (name, baseargs) )
+        if cls.__doc__:
+            a('    %r'                      % str(cls.__doc__) )
         a('    __metaclass__ = type')
         a('    __slots__ = ["__self__"] # for PyCObject')
         self.later(initclassobj())

Modified: pypy/dist/pypy/translator/c/src/module.h
==============================================================================
--- pypy/dist/pypy/translator/c/src/module.h	(original)
+++ pypy/dist/pypy/translator/c/src/module.h	Thu Apr 13 08:25:00 2006
@@ -24,6 +24,7 @@
 	PyModule_AddStringConstant(m, "__sourcefile__", __FILE__); \
 	this_module_globals = PyModule_GetDict(m); \
 	PyGenCFunction_Type.tp_base = &PyCFunction_Type;	\
+	PyGenCFunction_Type.tp_getset = PyCFunction_Type.tp_getset; \
 	PyType_Ready(&PyGenCFunction_Type);	\
 	RPythonError = PyErr_NewException(#modname ".RPythonError", \
 					  NULL, NULL); \

Modified: pypy/dist/pypy/translator/c/test/test_wrapping.py
==============================================================================
--- pypy/dist/pypy/translator/c/test/test_wrapping.py	(original)
+++ pypy/dist/pypy/translator/c/test/test_wrapping.py	Thu Apr 13 08:25:00 2006
@@ -43,6 +43,11 @@
         if isinstance(obj, type):
             clsdef = bk.getuniqueclassdef(obj)
             rtyper.add_wrapper(clsdef)
+            # pull it all out
+            for name, value in obj.__dict__.items():
+                continue # do we want that
+                if callable(value):
+                    t.annotator.build_types(value, get_annotation(value))
         elif callable(obj):
             t.annotator.build_types(obj, get_annotation(obj))
     if view:
@@ -231,12 +236,14 @@
 
 # a trivial class to be exposed
 class DemoClass(DemoBaseNotExposed):
+    """this is the doc string"""
     def __init__(self, a, b):
         self.a = a
         self.b = b
         if P:print 'init'
 
     def demo(self):
+        """this is the doc for demo"""
         if P:print 'demo'
         return self.a + self.b
 
@@ -353,6 +360,22 @@
     res = obj.demo()
     assert res == DemoClass(2, 3).demo()
 
+def t(a=int, b=int, c=DemoClass):
+    DemoClass(a, b).demo()
+    DemoSubclass(a, a, b).demo()
+    DemoSubclass(a, a, b).demo(6)
+    DemoSubclass(a, a, b).demo(6, 'hu')
+    if isinstance(c, DemoSubclass):
+        print 42
+        
+# exposing and using classes from a generasted extension module
+def test_asd():
+    m = get_compiled_module(t, use_boehm=not True, exports=[
+        DemoClass, DemoSubclass, DemoNotAnnotated, setup_new_module])
+    obj = m.DemoClass(2, 3)
+    res = obj.demo()
+    assert res == DemoClass(2, 3).demo()
+
 
 if __name__=='__main__':
     test_expose_classes()

Modified: pypy/dist/pypy/translator/c/wrapper.py
==============================================================================
--- pypy/dist/pypy/translator/c/wrapper.py	(original)
+++ pypy/dist/pypy/translator/c/wrapper.py	Thu Apr 13 08:25:00 2006
@@ -10,7 +10,7 @@
 from pypy.rpython.typesystem import getfunctionptr
 
 
-def gen_wrapper(func, translator):
+def gen_wrapper(func, translator, newname=None):
     """generate a wrapper function for 'func' that can be put in a
     PyCFunction object.  The wrapper has signature
 
@@ -121,7 +121,7 @@
 
     # "return result"
     block = Block([vself, vargs, vkwds])
-    wgraph = FunctionGraph('pyfn_' + func.func_name, block)
+    wgraph = FunctionGraph('pyfn_' + (newname or func.func_name), block)
     translator.update_call_graph(wgraph, graph, object())
     translator.graphs.append(wgraph)
     block.operations[:] = newops



More information about the Pypy-commit mailing list