[pypy-svn] rev 696 - in pypy/trunk/src/pypy: interpreter objspace/std

arigo at codespeak.net arigo at codespeak.net
Thu May 29 17:21:49 CEST 2003


Author: arigo
Date: Thu May 29 17:21:48 2003
New Revision: 696

Modified:
   pypy/trunk/src/pypy/interpreter/baseobjspace.py
   pypy/trunk/src/pypy/objspace/std/default.py
   pypy/trunk/src/pypy/objspace/std/dictobject.py
   pypy/trunk/src/pypy/objspace/std/funcobject.py
   pypy/trunk/src/pypy/objspace/std/instmethobject.py
   pypy/trunk/src/pypy/objspace/std/multimethod.py
   pypy/trunk/src/pypy/objspace/std/objspace.py
   pypy/trunk/src/pypy/objspace/std/tupleobject.py
   pypy/trunk/src/pypy/objspace/std/typeobject.py
Log:
nice general methods for our built-in objects

Modified: pypy/trunk/src/pypy/interpreter/baseobjspace.py
==============================================================================
--- pypy/trunk/src/pypy/interpreter/baseobjspace.py	(original)
+++ pypy/trunk/src/pypy/interpreter/baseobjspace.py	Thu May 29 17:21:48 2003
@@ -222,6 +222,7 @@
     ('iter',            'iter',      1, ['__iter__']),
     ('next',            'next',      1, ['next']),  # iterator interface
     ('call',            'call',      3, ['__call__']),
+    ('get',             'get',       3, ['__get__']),
     ]
 
 ObjSpace.BuiltinModuleTable = [

Modified: pypy/trunk/src/pypy/objspace/std/default.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/default.py	(original)
+++ pypy/trunk/src/pypy/objspace/std/default.py	Thu May 29 17:21:48 2003
@@ -49,13 +49,24 @@
     #w_type = space.type(w_obj)
     #w_typename = space.getattr(w_type, space.wrap('__name__'))
     #...
-    
-    # XXX as long as don't have types...
+
+    w_type = space.type(w_obj)
     if space.is_true(space.eq(w_attr, space.wrap('__class__'))):
-        return space.wrap(space.unwrap(w_obj).__class__)
+        return w_type
 
+    # XXX implement lookup as a multimethod
+    from typeobject import W_TypeObject
+    if isinstance(w_type, W_TypeObject):  # XXX must always be true at some point
+        try:
+            w_value = w_type.lookup(space, w_attr)
+        except KeyError:
+            pass
+        else:
+            return space.get(w_value, w_obj, w_type)
+        
     raise OperationError(space.w_AttributeError, w_attr)
 
+
 StdObjSpace.getattr.register(default_getattr, W_ANY, W_ANY)
 
 def default_setattr(space, w_obj, w_attr, w_value):
@@ -92,3 +103,23 @@
             return space.w_True
 
 StdObjSpace.contains.register(default_contains, W_ANY, W_ANY)
+
+
+# '__get__(descr, inst, cls)' returns 'descr' by default
+
+def default_get(space, w_descr, w_inst, w_cls):
+    return w_descr
+
+StdObjSpace.get.register(default_get, W_ANY, W_ANY, W_ANY)
+
+
+# static types
+
+def default_type(space, w_obj):
+    w_type = w_obj.statictype
+    if w_type is None:
+        # XXX remove me, temporary
+        return space.wrap(space.unwrap(w_obj).__class__)
+    return w_type
+
+StdObjSpace.type.register(default_type, W_ANY)

Modified: pypy/trunk/src/pypy/objspace/std/dictobject.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/dictobject.py	(original)
+++ pypy/trunk/src/pypy/objspace/std/dictobject.py	Thu May 29 17:21:48 2003
@@ -33,6 +33,7 @@
 
 class W_DictObject(W_Object):
     delegate_once = {}
+    statictypename = 'dict'
 
     def __init__(w_self, space, list_pairs_w):
         W_Object.__init__(w_self, space)
@@ -79,7 +80,13 @@
         return space.newlist([ cell.get()
                                for w_key,cell in
                                w_self.non_empties()])
-                
+
+    copy   = implmethod().register(copy)
+    items  = implmethod().register(items)
+    keys   = implmethod().register(keys)
+    values = implmethod().register(values)
+    
+
 def dict_is_true(space, w_dict):
     return not not w_dict.non_empties()
 
@@ -132,22 +139,22 @@
 
 StdObjSpace.contains.register(contains_dict_any, W_DictObject, W_ANY)
 
-def getattr_dict(space, w_dict, w_attr):
-    if space.is_true(space.eq(w_attr, space.wrap('copy'))):
-        w_builtinfn = make_builtin_func(space, W_DictObject.copy)
-        return W_InstMethObject(space, w_dict, w_builtinfn)
-    if space.is_true(space.eq(w_attr, space.wrap('items'))):
-        w_builtinfn = make_builtin_func(space, W_DictObject.items)
-        return W_InstMethObject(space, w_dict, w_builtinfn)
-    if space.is_true(space.eq(w_attr, space.wrap('keys'))):
-        w_builtinfn = make_builtin_func(space, W_DictObject.keys)
-        return W_InstMethObject(space, w_dict, w_builtinfn)
-    if space.is_true(space.eq(w_attr, space.wrap('values'))):
-        w_builtinfn = make_builtin_func(space, W_DictObject.values)
-        return W_InstMethObject(space, w_dict, w_builtinfn)
-    raise FailedToImplement(space.w_AttributeError)
+##def getattr_dict(space, w_dict, w_attr):
+##    if space.is_true(space.eq(w_attr, space.wrap('copy'))):
+##        w_builtinfn = make_builtin_func(space, W_DictObject.copy)
+##        return W_InstMethObject(space, w_dict, w_builtinfn)
+##    if space.is_true(space.eq(w_attr, space.wrap('items'))):
+##        w_builtinfn = make_builtin_func(space, W_DictObject.items)
+##        return W_InstMethObject(space, w_dict, w_builtinfn)
+##    if space.is_true(space.eq(w_attr, space.wrap('keys'))):
+##        w_builtinfn = make_builtin_func(space, W_DictObject.keys)
+##        return W_InstMethObject(space, w_dict, w_builtinfn)
+##    if space.is_true(space.eq(w_attr, space.wrap('values'))):
+##        w_builtinfn = make_builtin_func(space, W_DictObject.values)
+##        return W_InstMethObject(space, w_dict, w_builtinfn)
+##    raise FailedToImplement(space.w_AttributeError)
 
-StdObjSpace.getattr.register(getattr_dict, W_DictObject, W_ANY)
+##StdObjSpace.getattr.register(getattr_dict, W_DictObject, W_ANY)
 
 def eq_dict_dict(space, w_left, w_right):
     if len(w_left.data) != len(w_right.data):

Modified: pypy/trunk/src/pypy/objspace/std/funcobject.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/funcobject.py	(original)
+++ pypy/trunk/src/pypy/objspace/std/funcobject.py	Thu May 29 17:21:48 2003
@@ -1,6 +1,7 @@
 from __future__ import nested_scopes
 from pypy.objspace.std.objspace import *
 import pypy.interpreter.pyframe
+from pypy.objspace.std.instmethobject import W_InstMethObject
 
 
 class W_FuncObject(W_Object):
@@ -35,3 +36,9 @@
     return w_ret
 
 StdObjSpace.call.register(func_call, W_FuncObject, W_ANY, W_ANY)
+
+
+def func_get(space, w_function, w_instance, w_cls):
+    return W_InstMethObject(space, w_instance, w_function)
+
+StdObjSpace.get.register(func_get, W_FuncObject, W_ANY, W_ANY)

Modified: pypy/trunk/src/pypy/objspace/std/instmethobject.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/instmethobject.py	(original)
+++ pypy/trunk/src/pypy/objspace/std/instmethobject.py	Thu May 29 17:21:48 2003
@@ -29,3 +29,6 @@
     return w_ret
 
 StdObjSpace.call.register(instmeth_call, W_InstMethObject, W_ANY, W_ANY)
+
+
+# XXX do __get__ for instance methods

Modified: pypy/trunk/src/pypy/objspace/std/multimethod.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/multimethod.py	(original)
+++ pypy/trunk/src/pypy/objspace/std/multimethod.py	Thu May 29 17:21:48 2003
@@ -103,7 +103,7 @@
                 w_value = self.space.wrap(message)
                 raise OperationError(self.space.w_TypeError, w_value)
 
-    def perform_call(self, args, initialtypes):
+    def perform_call(self, args, initialtypes, prepend_space_argument=True):
         extraargs = args[self.multimethod.arity:]
         choicelist = self.multimethod.buildchoices(initialtypes)
         firstfailure = None
@@ -114,8 +114,10 @@
                     arg = delegator(self.space, arg)
                 newargs.append(arg)
             newargs = tuple(newargs) + extraargs
+            if prepend_space_argument:
+                newargs = (self.space,) + newargs
             try:
-                return function(self.space, *newargs)
+                return function(*newargs)
             except FailedToImplement, e:
                 # we got FailedToImplement, record the first such error
                 if firstfailure is None:

Modified: pypy/trunk/src/pypy/objspace/std/objspace.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/objspace.py	(original)
+++ pypy/trunk/src/pypy/objspace/std/objspace.py	Thu May 29 17:21:48 2003
@@ -19,6 +19,18 @@
         return w_self.__class__
 
 
+class implmethod(object):
+    def __init__(self):
+        self.dispatch_table = {}
+    def register(self, function, *types):
+        if types in self.dispatch_table:
+            raise error, "we already got an implementation for %r" % types
+        self.dispatch_table[types] = function
+        return self
+    def __get__(self, instance, cls=None):
+        raise "XXX come back later"
+
+
 ##################################################################
 
 class StdObjSpace(ObjSpace):
@@ -37,10 +49,11 @@
         'W_IntObject':   'intobject',
         'W_FloatObject': 'floatobject',
         #'W_ListObject': 'listobject',
+        'W_DictObject':  'dictobject',
         }
-    TYPE_CACHE = {}
 
     def initialize(self):
+        self.TYPE_CACHE = {}
         from noneobject    import W_NoneObject
         from boolobject    import W_BoolObject
         from cpythonobject import W_CPythonObject

Modified: pypy/trunk/src/pypy/objspace/std/tupleobject.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/tupleobject.py	(original)
+++ pypy/trunk/src/pypy/objspace/std/tupleobject.py	Thu May 29 17:21:48 2003
@@ -5,6 +5,9 @@
 
 class W_TupleObject(W_Object):
 
+    delegate_once = {}
+    statictypename = 'tuple'
+
     def __init__(w_self, space, wrappeditems):
         W_Object.__init__(w_self, space)
         w_self.wrappeditems = wrappeditems   # a list of wrapped values

Modified: pypy/trunk/src/pypy/objspace/std/typeobject.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/typeobject.py	(original)
+++ pypy/trunk/src/pypy/objspace/std/typeobject.py	Thu May 29 17:21:48 2003
@@ -1,5 +1,6 @@
 from pypy.interpreter import pycode
 from pypy.objspace.std.objspace import *
+from pypy.objspace.std.dictobject import W_DictObject
 
 
 class W_TypeObject(W_Object):
@@ -10,12 +11,41 @@
         W_Object.__init__(w_self, space)
         w_self.w_tpname = w_tpname
         w_self.builtin_implementations = []
-        w_self.multimethods = [value for key, value in space.__dict__.iteritems()
-                                     if isinstance(value, MultiMethod)]
+        w_self.multimethods = {}
+        # HACK to get to the multimethods of the space
+        for key, value in space.__class__.__dict__.iteritems():
+            if isinstance(value, MultiMethod):
+                for i in range(len(value.specialnames)):
+                    w_self.multimethods[value.specialnames[i]] = value, i
 
     def setup_builtin_type(w_self, implementation):
         implementation.statictype = w_self
         w_self.builtin_implementations.append(implementation)
+        
+        for key, value in implementation.__dict__.iteritems():
+            if isinstance(value, implmethod):
+                try:
+                    multimethod, bound_pos = w_self.multimethods[key]
+                except KeyError:
+                    sample = value.dispatch_table.keys()[0]
+                    multimethod = MultiMethod('%s()' % key, len(sample)+1, [])
+                    w_self.multimethods[key] = multimethod, None
+                for types, func in value.dispatch_table.iteritems():
+                    multimethod.register(func, implementation, *types)
+
+    def lookup(w_self, space, w_key):
+        "XXX at some point, turn this into a multimethod"
+        key = space.unwrap(w_key)
+        assert isinstance(key, str)
+        try:
+            multimethod, bound_pos = w_self.multimethods[key]
+        except KeyError:
+            raise KeyError
+        multimethod = multimethod.__get__(space, None)
+        code = PyMultimethodCode(multimethod, bound_pos, w_self)
+        if code.multimethod.is_empty():
+            raise KeyError
+        return space.newfunction(code, space.w_None, space.w_None)
 
 
 def make_type_by_name(space, tpname):
@@ -33,8 +63,14 @@
         pycode.PyBaseCode.__init__(self)
         argnames = ['x%d'%(i+1) for i in range(multimethod.multimethod.arity)]
         if w_type is not None:
-            multimethod = multimethod.slicetable(bound_position, w_type)
-            argnames.insert(0, argnames.pop(bound_position))
+            # 'bound_pos' hack mode on
+            multimethod = multimethod.slicetable(bound_position or 0, w_type)
+            # 'bound_pos' hack mode off
+            if bound_position:
+                argnames.insert(0, argnames.pop(bound_position))
+        # 'bound_pos' hack mode on
+        self.prepend_space_argument = bound_position is not None
+        # 'bound_pos' hack mode off
         self.multimethod = multimethod
         self.co_name = multimethod.multimethod.operatorsymbol
         self.co_flags = 0
@@ -54,7 +90,8 @@
         dispatchargs = tuple(dispatchargs)
         initialtypes = tuple(initialtypes)
         try:
-            return multimethod.perform_call(dispatchargs, initialtypes)
+            return multimethod.perform_call(dispatchargs, initialtypes,
+                prepend_space_argument = self.prepend_space_argument)
         except FailedToImplement, e:
             if e.args:
                 raise OperationError(*e.args)


More information about the Pypy-commit mailing list