[pypy-svn] r5319 - in pypy/trunk/src/pypy: interpreter interpreter/test module objspace objspace/std

arigo at codespeak.net arigo at codespeak.net
Fri Jun 25 19:34:57 CEST 2004


Author: arigo
Date: Fri Jun 25 19:34:55 2004
New Revision: 5319

Modified:
   pypy/trunk/src/pypy/interpreter/eval.py
   pypy/trunk/src/pypy/interpreter/gateway.py
   pypy/trunk/src/pypy/interpreter/pycode.py
   pypy/trunk/src/pypy/interpreter/test/test_code.py
   pypy/trunk/src/pypy/interpreter/typedef.py
   pypy/trunk/src/pypy/module/__builtin__interp.py
   pypy/trunk/src/pypy/module/sysinterp.py
   pypy/trunk/src/pypy/module/sysmodule.py
   pypy/trunk/src/pypy/objspace/std/objecttype.py
   pypy/trunk/src/pypy/objspace/trivial.py
Log:
* Built-in code objects have some inspectable co_xxx attributes now.
* 'sys.pypy_objspaceclass' is a string naming the object space on which
  we are running.
* A few TrivialObjSpace simplifications and fixes.



Modified: pypy/trunk/src/pypy/interpreter/eval.py
==============================================================================
--- pypy/trunk/src/pypy/interpreter/eval.py	(original)
+++ pypy/trunk/src/pypy/interpreter/eval.py	Fri Jun 25 19:34:55 2004
@@ -46,6 +46,8 @@
             argcount += 1
         return argcount
 
+    def getdocstring(self):
+        return None
 
 UNDEFINED = object()  # marker for undefined local variables
 
@@ -83,7 +85,7 @@
         return self.w_locals
 
     def fget_getdictscope(space, w_self):
-        self = space.unwrap(w_self)
+        self = space.unwrap_builtin(w_self)
         return self.getdictscope()
 
     def setdictscope(self, w_locals):

Modified: pypy/trunk/src/pypy/interpreter/gateway.py
==============================================================================
--- pypy/trunk/src/pypy/interpreter/gateway.py	(original)
+++ pypy/trunk/src/pypy/interpreter/gateway.py	Fri Jun 25 19:34:55 2004
@@ -28,6 +28,7 @@
         # Note that this uses a lot of (construction-time) introspection.
         eval.Code.__init__(self, func.__name__)
         self.func = func
+        self.docstring = func.__doc__
         # extract the signature from the (CPython-level) code object
         tmp = pycode.PyCode(None)
         tmp._from_code(func.func_code)
@@ -82,6 +83,9 @@
     def signature(self):
         return self.sig
 
+    def getdocstring(self):
+        return self.docstring
+
 
 class BuiltinFrame(eval.Frame):
     "Frame emulation for BuiltinCode."

Modified: pypy/trunk/src/pypy/interpreter/pycode.py
==============================================================================
--- pypy/trunk/src/pypy/interpreter/pycode.py	(original)
+++ pypy/trunk/src/pypy/interpreter/pycode.py	Fri Jun 25 19:34:55 2004
@@ -87,6 +87,12 @@
     def getvarnames(self):
         return self.co_varnames
 
+    def getdocstring(self):
+        if self.co_consts:   # it is probably never empty
+            return self.co_consts[0]
+        else:
+            return None
+
     def dictscope_needed(self):
         # regular functions always have CO_OPTIMIZED and CO_NEWLOCALS.
         # class bodies only have CO_NEWLOCALS.

Modified: pypy/trunk/src/pypy/interpreter/test/test_code.py
==============================================================================
--- pypy/trunk/src/pypy/interpreter/test/test_code.py	(original)
+++ pypy/trunk/src/pypy/interpreter/test/test_code.py	Fri Jun 25 19:34:55 2004
@@ -5,18 +5,57 @@
 
 
 class AppTestCodeIntrospection(testit.AppTestCase):
+
     def test_attributes(self):
         def f(): pass
-        code = f.func_code    
-        self.assert_(hasattr(code, 'co_code'))
-        self.assert_(hasattr(code, '__class__'))
-        self.assert_(not hasattr(code,'__dict__'))
-        self.assertEquals(code.co_name,'f')
-        self.assertEquals(code.co_names,())
-        self.assertEquals(code.co_varnames,())
-        self.assertEquals(code.co_argcount,0)
+        def g(x, *y, **z): "docstring"
+        self.assert_(hasattr(f.func_code, 'co_code'))
+        self.assert_(hasattr(g.func_code, 'co_code'))
+
+        testcases = [
+            (f.func_code, {'co_name': 'f',
+                           'co_names': (),
+                           'co_varnames': (),
+                           'co_argcount': 0,
+                           'co_consts': (None,)
+                           }),
+            (g.func_code, {'co_name': 'g',
+                           'co_names': (),
+                           'co_varnames': ('x', 'y', 'z'),
+                           'co_argcount': 1,
+                           'co_consts': ("docstring", None),
+                           }),
+            ]
+
+        import sys
+        if sys.pypy_objspaceclass != 'TrivialObjSpace':
+            testcases += [
+                (abs.func_code, {'co_name': 'abs',
+                                 'co_varnames': ('val',),
+                                 'co_argcount': 1,
+                                 'co_flags': 0,
+                                 'co_consts': ("abs(number) -> number\n\nReturn the absolute value of the argument.",),
+                                 }),
+                (object.__init__.im_func.func_code,
+                                {#'co_name': '__init__',   XXX getting descr__init__
+                                 'co_varnames': ('obj', 'args', 'keywords'),
+                                 'co_argcount': 1,
+                                 'co_flags': 0x000C,  # VARARGS|VARKEYWORDS
+                                 }),
+                ]
+
+        # in PyPy, built-in functions have code objects
+        # that emulate some attributes
+        for code, expected in testcases:
+            self.assert_(hasattr(code, '__class__'))
+            self.assert_(not hasattr(code,'__dict__'))
+            for key, value in expected.items():
+                self.assertEquals(getattr(code, key), value)
+
     def test_code(self):
-        import new
+        import sys, new
+        if sys.pypy_objspaceclass == 'TrivialObjSpace':
+            return   # skip
         codestr = "global c\na = 1\nb = 2\nc = a + b\n"
         ccode = compile(codestr, '<string>', 'exec')
         co = new.code(ccode.co_argcount,

Modified: pypy/trunk/src/pypy/interpreter/typedef.py
==============================================================================
--- pypy/trunk/src/pypy/interpreter/typedef.py	(original)
+++ pypy/trunk/src/pypy/interpreter/typedef.py	Fri Jun 25 19:34:55 2004
@@ -128,7 +128,7 @@
 # Definition of the type's descriptors for all the internal types
 
 from pypy.interpreter.eval import Code, Frame
-from pypy.interpreter.pycode import PyCode
+from pypy.interpreter.pycode import PyCode, CO_VARARGS, CO_VARKEYWORDS
 from pypy.interpreter.pyframe import PyFrame, ControlFlowException
 from pypy.interpreter.module import Module
 from pypy.interpreter.function import Function, Method, StaticMethod
@@ -150,15 +150,40 @@
 default_dict_descr = GetSetProperty(descr_get_dict, descr_set_dict)
 
 
+# co_xxx interface emulation for built-in code objects
+def fget_co_varnames(space, w_code):
+    code = space.unwrap_builtin(w_code)
+    return space.newtuple([space.wrap(name) for name in code.getvarnames()])
+
+def fget_co_argcount(space, w_code):
+    code = space.unwrap_builtin(w_code)
+    argnames, varargname, kwargname = code.signature()
+    return space.wrap(len(argnames))
+
+def fget_co_flags(space, w_code):
+    code = space.unwrap_builtin(w_code)
+    argnames, varargname, kwargname = code.signature()
+    flags = 0
+    if varargname is not None: flags |= CO_VARARGS
+    if kwargname  is not None: flags |= CO_VARKEYWORDS
+    return space.wrap(flags)
+
+def fget_co_consts(space, w_code):
+    code = space.unwrap_builtin(w_code)
+    w_docstring = space.wrap(code.getdocstring())
+    return space.newtuple([w_docstring])
+
 Code.typedef = TypeDef('internal-code',
     co_name = attrproperty('co_name'),
-    # XXX compute more co_xxx from the methods in Code
+    co_varnames = GetSetProperty(fget_co_varnames),
+    co_argcount = GetSetProperty(fget_co_argcount),
+    co_flags = GetSetProperty(fget_co_flags),
+    co_consts = GetSetProperty(fget_co_consts),
     )
 
 Frame.typedef = TypeDef('internal-frame',
     f_code = attrproperty('code'),
-    f_locals = GetSetProperty(Frame.fget_getdictscope.im_func,
-                              ), # , setdictscope), XXX
+    f_locals = GetSetProperty(Frame.fget_getdictscope.im_func),
     f_globals = attrproperty_w('w_globals'),
     )
 

Modified: pypy/trunk/src/pypy/module/__builtin__interp.py
==============================================================================
--- pypy/trunk/src/pypy/module/__builtin__interp.py	(original)
+++ pypy/trunk/src/pypy/module/__builtin__interp.py	Fri Jun 25 19:34:55 2004
@@ -237,6 +237,7 @@
     return space.unwrap(w_codeobj).exec_code(space, w_globals, w_locals)
 
 def abs(w_val):
+    "abs(number) -> number\n\nReturn the absolute value of the argument."
     return space.abs(w_val)
 
 def chr(w_ascii):

Modified: pypy/trunk/src/pypy/module/sysinterp.py
==============================================================================
--- pypy/trunk/src/pypy/module/sysinterp.py	(original)
+++ pypy/trunk/src/pypy/module/sysinterp.py	Fri Jun 25 19:34:55 2004
@@ -74,6 +74,8 @@
 w_stdout = space.wrap(cpy_sys.stdout)
 w_stderr = space.wrap(cpy_sys.stderr)
 
+w_pypy_objspaceclass = space.wrap(space.__class__.__name__)
+
 # ____________________________________________________________
 
 def setmodule(w_module):

Modified: pypy/trunk/src/pypy/module/sysmodule.py
==============================================================================
--- pypy/trunk/src/pypy/module/sysmodule.py	(original)
+++ pypy/trunk/src/pypy/module/sysmodule.py	Fri Jun 25 19:34:55 2004
@@ -12,6 +12,7 @@
 # Objects from interpreter-level
 from __interplevel__ import stdin, stdout, stderr, maxint
 from __interplevel__ import hexversion, platform
+from __interplevel__ import pypy_objspaceclass
 
 # Functions from interpreter-level
 from __interplevel__ import displayhook, _getframe, exc_info

Modified: pypy/trunk/src/pypy/objspace/std/objecttype.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/objecttype.py	(original)
+++ pypy/trunk/src/pypy/objspace/std/objecttype.py	Fri Jun 25 19:34:55 2004
@@ -33,7 +33,7 @@
     w_obj.__init__(space)
     return w_obj
 
-def descr__init__(space, __args__):
+def descr__init__(space, w_obj, __args__):
     pass
 
 # ____________________________________________________________

Modified: pypy/trunk/src/pypy/objspace/trivial.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/trivial.py	(original)
+++ pypy/trunk/src/pypy/objspace/trivial.py	Fri Jun 25 19:34:55 2004
@@ -7,7 +7,7 @@
 from pypy.interpreter import gateway
 from pypy.interpreter.baseobjspace import *
 from pypy.objspace.descroperation import DescrOperation, Object
-import operator, types, sys
+import types, sys
 import __builtin__ as cpy_builtin
 
 class CPyWrapper(object):
@@ -134,6 +134,9 @@
             # optional check for double-wrapping
             if isinstance(x, CPyWrapper):
                 raise TypeError, "wrapping an already-wrapped object"
+            # grumble grumble grumble recursive wrapping grumble
+            if isinstance(x, tuple):
+                return tuple([self.wrap(y) for y in x])
             return x
 
     def unwrap(self, w):
@@ -246,31 +249,51 @@
             nv = evalue
         raise OperationError, OperationError(nt, nv), etb
 
-    def _auto(name, sourcefn, classlocals):
-        s = """
-def %(name)s(self, x, *args):
-    try:
-        value = %(sourcefn)s(x, *args)
-    except:
-        self.reraise()
-    return self.wrap(value)
-""" % locals()
-        exec s in globals(), classlocals
-
     # from the built-ins
-    _auto('issubtype', 'issubclass', locals())
-    _auto('newtuple',  'tuple',      locals())
-    _auto('newlist',   'list',       locals())
-    _auto('newdict',   'dict',       locals())
-    _auto('newslice',  'slice',      locals())
-    is_true   = operator.truth
-    # 'is_true' is not called 'truth' because it returns a *non-wrapped* boolean
+    def issubtype(self, w_x, w_y):
+        try:
+            return issubclass(w_x, w_y)
+        except:
+            self.reraise()
+
+    def newtuple(self, args_w):
+        return tuple(args_w)
+
+    def newlist(self, args_w):
+        return list(args_w)
 
-    for _name in ('type', 'ord', 'round'):
-        _auto(_name, _name, locals())
+    def newdict(self, items_w):
+        try:
+            return dict(items_w)
+        except:
+            self.reraise()
 
-    def not_(self, w_obj):  # default implementation
-        return self.wrap(not self.is_true(w_obj))
+    def newslice(self, *args_w):
+        try:
+            return slice(*args_w)
+        except:
+            self.reraise()
+
+    def is_true(self, w_obj):
+        return not not w_obj
+
+    def not_(self, w_obj):
+        return not w_obj
+
+    def type(self, w_x):
+        return type(w_x)
+
+    def ord(self, w_x):
+        try:
+            return ord(w_x)
+        except:
+            self.reraise()
+
+    def round(self, w_x):
+        try:
+            return round(w_x)
+        except:
+            self.reraise()
 
     def iter(self, w_obj):
         if isinstance(w_obj, str) and not hasattr(w_obj, '__iter__'):



More information about the Pypy-commit mailing list