[pypy-svn] r23587 - in pypy/dist/pypy: annotation translator translator/c

tismer at codespeak.net tismer at codespeak.net
Wed Feb 22 06:32:05 CET 2006


Author: tismer
Date: Wed Feb 22 06:31:47 2006
New Revision: 23587

Modified:
   pypy/dist/pypy/annotation/bookkeeper.py
   pypy/dist/pypy/translator/c/pyobj.py
   pypy/dist/pypy/translator/translator.py
Log:
revived the patch for extension module building. I'm undecided if it should stay so. Will add tests before thinking of a redesign.

Modified: pypy/dist/pypy/annotation/bookkeeper.py
==============================================================================
--- pypy/dist/pypy/annotation/bookkeeper.py	(original)
+++ pypy/dist/pypy/annotation/bookkeeper.py	Wed Feb 22 06:31:47 2006
@@ -139,7 +139,11 @@
 
     def consider_dict_delitem(self, dic):
         return dic
-            
+
+# this dictionary can be extended by extension writers
+DEFINED_SOMEOBJECTS = { sys: True,
+                        }
+# XXX should this live in the Bookkeeper instance?
 
 class Bookkeeper:
     """The log of choices that have been made while analysing the operations.
@@ -354,13 +358,17 @@
                 for ek, ev in x.iteritems():
                     result.dictdef.generalize_key(self.immutablevalue(ek))
                     result.dictdef.generalize_value(self.immutablevalue(ev))
+        elif ishashable(x) and x in DEFINED_SOMEOBJECTS: # sys by default
+            return SomeObject()
         elif ishashable(x) and x in BUILTIN_ANALYZERS:
-	    _module = getattr(x,"__module__","unknown")
+            _module = getattr(x,"__module__","unknown")
             result = SomeBuiltin(BUILTIN_ANALYZERS[x], methodname="%s.%s" % (_module, x.__name__))
         elif hasattr(x, "compute_result_annotation"):
             result = SomeBuiltin(x.compute_result_annotation, methodname=x.__name__)
         elif hasattr(tp, "compute_annotation"):
             result = tp.compute_annotation()
+        elif tp in DEFINED_SOMEOBJECTS:
+            return SomeObject()
         elif tp in EXTERNAL_TYPE_ANALYZERS:
             result = SomeExternalObject(tp)
         elif isinstance(x, lltype._ptr):

Modified: pypy/dist/pypy/translator/c/pyobj.py
==============================================================================
--- pypy/dist/pypy/translator/c/pyobj.py	(original)
+++ pypy/dist/pypy/translator/c/pyobj.py	Wed Feb 22 06:31:47 2006
@@ -36,6 +36,9 @@
                                #   objects
         self.debugstack = ()  # linked list of nested nameof()
         self.wrappers = {}    # {'pycfunctionvariable': ('name', 'wrapperfn')}
+        self.import_hints = {}
+        if translator:
+            self.import_hints = translator.flags['import_hints']
 
     def nameof(self, obj, debug=None):
         if debug:
@@ -105,7 +108,37 @@
         name = self.uniquename('mod%s'%value.__name__)
         self.initcode_python(name, "__import__(%r)" % (value.__name__,))
         return name
-        
+
+    # try to build valid imports for external stuff        
+    def nameof_module(self, value):
+        easy = value is os or not hasattr(value, "__file__") or \
+               not (value.__file__.endswith('.pyc') or
+                    value.__file__.endswith('.py') or
+                    value.__file__.endswith('.pyo'))
+        name = self.uniquename('mod%s'%value.__name__)
+        if not easy:
+            self.initcode.append('######## warning ########')
+            self.initcode.append('## %r is not a builtin module (probably :)' %value)
+        access = "__import__(%r)" % value.__name__
+        # this is an inlined version of my_import, see sect. 2.1 of the python docs
+        for submodule in value.__name__.split('.')[1:]:
+            access += '.' + submodule
+        self.initcode_python(name, access)
+        return name
+
+    def _import_module(self, modname):
+        mod = __import__(modname)
+        for submodule in modname.split('.')[1:]:
+            mod = getattr(mod, submodule)
+        return mod
+
+    def _find_in_module(self, obj, mod):
+        if hasattr(obj, '__name__') and obj.__name__ in mod.__dict__:
+            return obj.__name__
+        for key, value in mod.__dict__.iteritems():
+            if value is obj:
+                return key
+        raise ImportError, 'object %r cannot be found in %r' % (obj, mod)
 
     def nameof_int(self, value):
         if value >= 0:
@@ -180,6 +213,9 @@
         assert self.translator is not None, (
             "the Translator must be specified to build a PyObject "
             "wrapper for %r" % (func,))
+        # shortcut imports
+        if func in self.import_hints:
+            return self.import_function(func)
         # look for skipped functions
         if self.shouldskipfunc(func):
             return self.skipped_function(func)
@@ -190,6 +226,15 @@
         self.wrappers[pycfunctionobj] = func.__name__, self.getvalue(fwrapper)
         return pycfunctionobj
 
+    def import_function(self, func):
+        name = self.uniquename('impfunc_' + func.__name__)
+        modulestr = self.import_hints[func] or func.__module__
+        module = self._import_module(modulestr)
+        modname = self.nameof(module)
+        obname = self._find_in_module(func, module)
+        self.initcode_python(name, '%s.%s' % (modname, obname))
+        return name
+
     def nameof_staticmethod(self, sm):
         # XXX XXX XXXX
         func = sm.__get__(42.5)
@@ -227,6 +272,8 @@
         return False
 
     def nameof_instance(self, instance):
+        if instance in self.import_hints:
+            return self.import_instance(instance)
         klass = instance.__class__
         if issubclass(klass, LowLevelType):
             raise Exception, 'nameof_LowLevelType(%r)' % (instance,)
@@ -263,6 +310,16 @@
         self.later(initinstance())
         return name
 
+    def import_instance(self, inst):
+        klass = inst.__class__
+        name = self.uniquename('impinst_' + klass.__name__)
+        modulestr = self.import_hints[inst] or klass.__module__
+        module = self._import_module(modulestr)
+        modname = self.nameof(module)
+        obname = self._find_in_module(func, module)
+        self.initcode_python(name, '%s.%s' % (modname, obname))
+        return name
+
     def nameof_builtin_function_or_method(self, func):
         if func.__self__ is None:
             # builtin function
@@ -294,6 +351,8 @@
         if cls.__doc__ and cls.__doc__.lstrip().startswith('NOT_RPYTHON'):
             raise Exception, "%r should never be reached" % (cls,)
 
+        if cls in self.import_hints:
+            return self.import_classobj(cls)
         metaclass = "type"
         if issubclass(cls, Exception):
             # if cls.__module__ == 'exceptions':
@@ -343,6 +402,15 @@
 
     nameof_class = nameof_classobj   # for Python 2.2
 
+    def import_classobj(self, cls):
+        name = self.uniquename('impcls_' + cls.__name__)
+        modulestr = self.import_hints[cls] or cls.__module__
+        module = self._import_module(modulestr)
+        modname = self.nameof(module)
+        obname = self._find_in_module(cls, module)
+        self.initcode_python(name, '%s.%s' % (modname, obname))
+        return name
+
     typename_mapping = {
         InstanceType: 'types.InstanceType',
         type(None):   'type(None)',

Modified: pypy/dist/pypy/translator/translator.py
==============================================================================
--- pypy/dist/pypy/translator/translator.py	(original)
+++ pypy/dist/pypy/translator/translator.py	Wed Feb 22 06:31:47 2006
@@ -4,7 +4,7 @@
 translation-related code.  It can be used for interactive testing of the
 translator; see pypy/bin/translator.py.
 """
-import autopath, os, sys, types
+import autopath, os, sys, types, copy
 
 from pypy.objspace.flow.model import *
 from pypy.translator.simplify import simplify_graph
@@ -21,10 +21,11 @@
         'simplifying': True,
         'do_imports_immediately': True,
         'builtins_can_raise_exceptions': False,
+        'import_hints': {},
         }
 
     def __init__(self, **flowing_flags):
-        self.flags = self.FLOWING_FLAGS.copy()
+        self.flags = copy.deepcopy(self.FLOWING_FLAGS)
         self.flags.update(flowing_flags)
         if len(self.flags) > len(self.FLOWING_FLAGS):
             raise TypeError("unexpected keyword argument")



More information about the Pypy-commit mailing list