[pypy-svn] r9244 - in pypy/branch/dist-interpapp/pypy/interpreter: . test test/mixedmodule

hpk at codespeak.net hpk at codespeak.net
Wed Feb 16 13:57:50 CET 2005


Author: hpk
Date: Wed Feb 16 13:57:50 2005
New Revision: 9244

Added:
   pypy/branch/dist-interpapp/pypy/interpreter/newmodule.py
   pypy/branch/dist-interpapp/pypy/interpreter/test/mixedmodule/
   pypy/branch/dist-interpapp/pypy/interpreter/test/mixedmodule/__init__.py
   pypy/branch/dist-interpapp/pypy/interpreter/test/mixedmodule/file1.py
   pypy/branch/dist-interpapp/pypy/interpreter/test/mixedmodule/file2_app.py
Modified:
   pypy/branch/dist-interpapp/pypy/interpreter/module.py
   pypy/branch/dist-interpapp/pypy/interpreter/test/test_appinterp.py
Log:
a first go at a new way of doing mixed modules. 

Note: 

- the old mechanisms is still fully in place and used 
  for builtin and sys 

- test_app2interp.py tests with an example 
  found in mixedmodule 

- newmodule contains the new ExtModule 



Modified: pypy/branch/dist-interpapp/pypy/interpreter/module.py
==============================================================================
--- pypy/branch/dist-interpapp/pypy/interpreter/module.py	(original)
+++ pypy/branch/dist-interpapp/pypy/interpreter/module.py	Wed Feb 16 13:57:50 2005
@@ -40,6 +40,9 @@
             space.setitem(self.w_dict, space.wrap('__doc__'), w_doc)
 
     def descr_module__getattr__(self, w_attr):
+        return self.ARGL_getattr(w_attr) 
+
+    def ARGL_getattr(self, w_attr): 
         space = self.space
         attr = space.str_w(w_attr)
         # ______ for the 'sys' module only _____ XXX generalize

Added: pypy/branch/dist-interpapp/pypy/interpreter/newmodule.py
==============================================================================
--- (empty file)
+++ pypy/branch/dist-interpapp/pypy/interpreter/newmodule.py	Wed Feb 16 13:57:50 2005
@@ -0,0 +1,90 @@
+from pypy.interpreter.module import Module 
+from pypy.tool.cache import Cache
+from pypy.interpreter import gateway 
+from pypy.interpreter.error import OperationError 
+
+import inspect
+
+class ExtModule(Module): 
+    def __init__(self, space, w_name): 
+        """ NOT_RPYTHON """ 
+        Module.__init__(self, space, w_name) 
+        self.lazy = True 
+        # build a constant dictionary out of
+        # applevel/interplevel definitions 
+        self.__class__.buildloaders() 
+
+    def ARGL_getattr(self, w_attr): 
+        space = self.space
+        if not self.lazy: 
+            raise OperationError(space.w_AttributeError, w_attr) 
+        name = space.str_w(w_attr)
+        return self.get(name) 
+
+    def get(self, name): 
+        try:
+            return Module.get(self, name)
+        except OperationError, e: 
+            space = self.space
+            if not self.lazy or not e.match(space, self.space.w_KeyError): 
+                raise 
+            # not rpython
+            try: 
+                loader = self.loaders[name]
+            except KeyError: 
+                raise OperationError(space.w_AttributeError, space.wrap(name))
+            else: 
+                w_value = loader(space) 
+                space.setitem(self.w_dict, space.wrap(name), w_value) 
+                return w_value 
+
+    def buildloaders(cls): 
+        """ NOT_RPYTHON """ 
+        if not hasattr(cls, 'loaders'): 
+            cls.loaders = loaders = {}
+            pkgroot = cls.__module__
+            print cls.interpleveldefs
+            for name, spec in cls.interpleveldefs.items(): 
+                if spec.startswith('('): 
+                    loader = getinterpevalloader(spec)
+                else: 
+                    loader = getinterpfileloader(pkgroot, spec) 
+                loaders[name] = loader 
+            for name, spec in cls.appleveldefs.items(): 
+                loaders[name] = getappfileloader(pkgroot, spec) 
+    buildloaders = classmethod(buildloaders) 
+
+def getinterpevalloader(spec): 
+    def ievalloader(space): 
+        """ NOT_RPYTHON """ 
+        d = {'space' : space}
+        return eval(spec, d, d)
+    return ievalloader 
+
+def getinterpfileloader(pkgroot, spec):
+    modname, attrname = spec.split('.')
+    impbase = pkgroot + '.' + modname 
+    def ifileloader(space): 
+        """ NOT_RPYTHON """ 
+        mod = __import__(impbase, None, None, [attrname])
+        attr = getattr(mod, attrname)
+        iattr = gateway.interp2app(attr, attrname)
+        return space.wrap(iattr) 
+    return ifileloader 
+
+applevelcache = Cache()
+def getappfileloader(pkgroot, spec): 
+    # hum, it's a bit more involved, because we usually 
+    # want the import at applevel
+    modname, attrname = spec.split('.')
+    impbase = pkgroot + '.' + modname 
+    mod = __import__(impbase, None, None, ['attrname'])
+    app = applevelcache.getorbuild(mod, buildapplevelfrommodule, None)
+    def afileloader(space): 
+        """ NOT_RPYTHON """ 
+        return app.wget(space, attrname)
+    return afileloader 
+
+def buildapplevelfrommodule(mod, _): 
+    source = inspect.getsource(mod) 
+    return gateway.applevel(source) 

Added: pypy/branch/dist-interpapp/pypy/interpreter/test/mixedmodule/__init__.py
==============================================================================
--- (empty file)
+++ pypy/branch/dist-interpapp/pypy/interpreter/test/mixedmodule/__init__.py	Wed Feb 16 13:57:50 2005
@@ -0,0 +1,11 @@
+from pypy.interpreter.newmodule import ExtModule 
+
+class Module(ExtModule): 
+    interpleveldefs = {
+        'somefunc' : 'file1.somefunc', 
+        'value' : '(space.w_None)', 
+    }
+
+    appleveldefs = {
+        'someappfunc' : 'file2_app.someappfunc', 
+    }

Added: pypy/branch/dist-interpapp/pypy/interpreter/test/mixedmodule/file1.py
==============================================================================
--- (empty file)
+++ pypy/branch/dist-interpapp/pypy/interpreter/test/mixedmodule/file1.py	Wed Feb 16 13:57:50 2005
@@ -0,0 +1,4 @@
+
+def somefunc(space): 
+    return space.w_True 
+

Added: pypy/branch/dist-interpapp/pypy/interpreter/test/mixedmodule/file2_app.py
==============================================================================
--- (empty file)
+++ pypy/branch/dist-interpapp/pypy/interpreter/test/mixedmodule/file2_app.py	Wed Feb 16 13:57:50 2005
@@ -0,0 +1,3 @@
+
+def someappfunc(x): 
+    return x + 1

Modified: pypy/branch/dist-interpapp/pypy/interpreter/test/test_appinterp.py
==============================================================================
--- pypy/branch/dist-interpapp/pypy/interpreter/test/test_appinterp.py	(original)
+++ pypy/branch/dist-interpapp/pypy/interpreter/test/test_appinterp.py	Wed Feb 16 13:57:50 2005
@@ -100,5 +100,27 @@
     assert x/2 == 1
 
 class AppTestMethods: 
-    def test_somee_app_test_method(self): 
+    def test_some_app_test_method(self): 
         assert 2 == 2
+
+class TestMixedModule: 
+    def test_accesses(self): 
+        space = self.space 
+        import mixedmodule 
+        w_module = mixedmodule.Module(space, space.wrap('mixedmodule'))
+        space.appexec([w_module], """
+            (module): 
+                assert module.value is None 
+
+                assert module.somefunc is module.somefunc 
+                result = module.somefunc() 
+                assert result == True 
+
+                assert module.someappfunc is module.someappfunc 
+                appresult = module.someappfunc(41) 
+                assert appresult == 42 
+
+                assert module.__dict__ is module.__dict__
+                for name in ('somefunc', 'someappfunc'): 
+                    assert name in module.__dict__
+        """)



More information about the Pypy-commit mailing list