[pypy-dev] Builtin Modules, Annotation Space

Rocco Moretti roccomoretti at netscape.net
Fri Jul 4 05:22:39 MEST 2003


Hello all,

I've made some updates to the interpreter internals to generalize builtin 
module loading (with an eye toward getting an os module). These changes 
pass all tests on trivial and standard object spaces, but cause 
test_all.py to crash under -A during the ObjSpace initilization (it 
doesn't even get to the "Running tests under ...").

My best guess is that when I'm working with wrapped objects in the 
initilization code, I'm running afoul of what AnnObjSpace is doing, 
probably in the same way that running the interpreter app-level helper 
functions under AnnObjSpace does not work. (We want the code to execute, 
not be translated.)

How should the people working on the interpreter internals deal with 
wrapped objects, such that we don't run afoul of AnnObjSpace? Are there 
guidelines as to what operations are allowed when?

For those who want to take a look, the diff of my changes should be 
attached. (I'm not commiting it yet for obvious reasons.)

-Rocco

__________________________________________________________________
McAfee VirusScan Online from the Netscape Network.
Comprehensive protection for your entire computer. Get your free trial today!
http://channels.netscape.com/ns/computing/mcafee/index.jsp?promo=393397

Get AOL Instant Messenger 5.1 free of charge.  Download Now!
http://aim.aol.com/aimnew/Aim/register.adp?promo=380455
-------------- next part --------------
Index: interpreter/test/test_main.py
===================================================================
--- interpreter/test/test_main.py   (revision 1082)
+++ interpreter/test/test_main.py   (working copy)
@@ -21,7 +21,7 @@
 
 def checkoutput(expected_output,f,*args):
     space = test.objspace()
-    w_sys = space.get_builtin_module(space.wrap("sys"))
+    w_sys = space.w_sys
     w_oldout = space.getattr(w_sys, space.wrap("stdout"))
     capture.reset()
     space.setattr(w_sys, space.wrap("stdout"), space.wrap(capture))
Index: interpreter/baseobjspace.py
===================================================================
--- interpreter/baseobjspace.py (revision 1082)
+++ interpreter/baseobjspace.py (working copy)
@@ -1,6 +1,6 @@
 from executioncontext import ExecutionContext, OperationError, NoValue
 import pyframe, threadlocals
-import pypy.module.builtin
+import pypy.module
 
 __all__ = ['ObjSpace', 'OperationError', 'NoValue', 'PyPyError']
 
@@ -18,30 +18,46 @@
     def __init__(self):
         "Basic initialization of objects."
         self.w_modules = self.newdict([])
+        self.w_builtin_module_names = self.newlist([])
         self.appfile_helpers = {}
         self.initialize()
 
     def make_builtins(self):
+        import pypy.module.builtin
         self.builtin = pypy.module.builtin.Builtin(self)
         self.w_builtin = self.builtin.wrap_base()
+        # self.builtins must be set before wrap_appfile (or wrap_me) is called.
         self.w_builtins = self.getattr(self.w_builtin, self.wrap("__dict__"))
         self.builtin.wrap_appfile(self.w_builtin)
 
+        w_name = self.getattr(self.w_builtin, self.wrap("__name__"))
+        self.setitem(self.w_modules, w_name, self.w_builtin)
+        self.call_function(self.getattr(self.w_builtin_module_names,
+                                        self.wrap('append')),
+                           w_name)
+
+    def make_builtin_modules(self):
+        #Note - self.w_builtins must be set before calling this function
+        for filename, classname, spacelist in pypy.module._builtin_modules:
+            if self.__class__.__name__ in spacelist:
+                pypy_ = __import__('pypy.module.'+filename)
+                file_ = getattr(getattr(pypy_,'module'),filename)
+                module = getattr(file_, classname)(self) #Call class with space
+                if module is None:
+                    continue
+                w_module = module.wrap_me()
+                w_name = self.getattr(w_module, self.wrap("__name__"))
+                self.setitem(self.w_modules, w_name, w_module)
+                self.call_function(self.getattr(self.w_builtin_module_names,
+                                                self.wrap('append')),
+                                   w_name)
+                
     def make_sys(self):
-        import pypy.module.sysmodule
-        self.sys = pypy.module.sysmodule.Sys(self)
-        self.w_sys = self.sys.wrap_me()
+        self.w_sys = self.getitem(self.w_modules,self.wrap("sys"))
         self.setattr(self.w_sys, self.wrap("modules"), self.w_modules)
-
-    # XXX use a dictionary in the future
-    def get_builtin_module(self, w_name):
-        name = self.unwrap(w_name)
-        if name == '__builtin__':
-            return self.w_builtin
-        elif name == 'sys':
-            return self.w_sys
-        return None
-
+        self.setattr(self.w_sys, self.wrap("builtin_module_names"),
+                     self.w_builtin_module_names)
+        
     def initialize(self):
         """Abstract method that should put some minimal content into the
         w_builtins."""
Index: module/test/test_sysmodule.py
===================================================================
--- module/test/test_sysmodule.py   (revision 1082)
+++ module/test/test_sysmodule.py   (working copy)
@@ -4,7 +4,7 @@
 class SysTests(test.TestCase):
     def setUp(self):
         self.space = test.objspace()
-        self.sys_w = self.space.get_builtin_module(self.space.wrap("sys"))
+        self.sys_w = self.space.w_sys
     def tearDown(self):
         pass
 
@@ -12,6 +12,36 @@
         s = self.space
         self.failUnless_w(s.getattr(self.sys_w, s.wrap("stdout")))
 
+class SysAppTests(test.AppTestCase):
+    def setUp(self):
+        self.space = test.objspace()
+    
+    def test_sys_in_modules(self):
+        import sys
+        modules = sys.modules
+        self.failUnless('sys' in modules, "An entry for sys "
+                                        "is not in sys.modules.")
+        sys2 = sys.modules['sys']
+        self.failUnless(sys is sys2, "import sys is not sys.modules[sys].") 
+
+    def test_builtin_in_modules(self):
+        import sys
+        modules = sys.modules
+        self.failUnless('__builtin__' in modules, "An entry for __builtin__ "
+                                                    "is not in sys.modules.")
+        import __builtin__
+        builtin2 = sys.modules['__builtin__']
+        self.failUnless(__builtin__ is builtin2, "import __builtin__ "
+                                            "is not sys.modules[__builtin__].")
+
+    def test_builtin_module_names(self):
+        import sys
+        names = sys.builtin_module_names
+        self.failUnless('sys' in names,
+                        "sys is not listed as a builtin module.")
+        self.failUnless('__builtin__' in names,
+                        "__builtin__ is not listed as a builtin module.")
+        
 if __name__ == '__main__':
     test.main()
 
Index: module/__init__.py
===================================================================
--- module/__init__.py  (revision 1082)
+++ module/__init__.py  (working copy)
@@ -0,0 +1,17 @@
+
+_all_spaces = ['TrivialObjSpace','StdObjSpace',
+               'AnnotationObjSpace','HelperObjSpace']
+
+# A list of (filename, classname, [applicable spaces]) tuples
+#   describing the builtin modules (pypy.interpreter.extmodule.BuiltinModule)
+#   availible in the pypy.module directory.
+
+# classname should be a classname of a callable in 'filename' that returns
+#   an unwrapped builtin module (pypy.interpreter.extmodule.BuiltinModule
+#   instance) - it returns unwrapped None if the builtin module is not to
+#   be loaded. (e.g. this is the wrong platform.)
+
+#Note: the builtin module is special cased for bootstrapping reasons.
+
+_builtin_modules = [('sysmodule','Sys',_all_spaces),
+                   ]
Index: module/builtin.py
===================================================================
--- module/builtin.py   (revision 1082)
+++ module/builtin.py   (working copy)
@@ -42,10 +42,6 @@
         except executioncontext.OperationError,e:
             if not e.match(space, space.w_KeyError):
                 raise
-            w_mod = space.get_builtin_module(w_modulename)
-            if w_mod is not None:
-                space.setitem(space.w_modules,w_modulename,w_mod)
-                return w_mod
 
             import os, __future__
             for path in space.unwrap(space.getattr(space.w_sys, w('path'))):
Index: objspace/trivial.py
===================================================================
--- objspace/trivial.py (revision 1082)
+++ objspace/trivial.py (working copy)
@@ -152,6 +152,7 @@
                 newstuff[c.__name__] = c
         newstuff.update(self.clone_exception_hierarchy())
         self.make_builtins()
+        self.make_builtin_modules()
         self.make_sys()
         # insert these into the newly-made builtins
         for key, w_value in newstuff.items():
Index: objspace/std/objspace.py
===================================================================
--- objspace/std/objspace.py    (revision 1082)
+++ objspace/std/objspace.py    (working copy)
@@ -176,6 +176,7 @@
         for_builtins.update(self.clone_exception_hierarchy())
         
         self.make_builtins()
+        self.make_builtin_modules()
         self.make_sys()
         
         # insert stuff into the newly-made builtins
Index: objspace/ann/objspace.py
===================================================================
--- objspace/ann/objspace.py    (revision 1082)
+++ objspace/ann/objspace.py    (working copy)
@@ -36,6 +36,7 @@
             if isinstance(c, types.TypeType) or isinstance(c, types.ClassType):
                 setattr(self, 'w_'+n, self.wrap(c))
         self.make_builtins()
+        self.make_builtin_modules()
         self.make_sys()
 
     # Service methods whose interface is in the abstract base class


More information about the pypy-dev mailing list