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

arigo at codespeak.net arigo at codespeak.net
Fri May 30 17:16:11 CEST 2003


Author: arigo
Date: Fri May 30 17:16:10 2003
New Revision: 731

Added:
   pypy/trunk/src/pypy/objspace/std/booltype.py
   pypy/trunk/src/pypy/objspace/std/dicttype.py
   pypy/trunk/src/pypy/objspace/std/floattype.py
   pypy/trunk/src/pypy/objspace/std/inttype.py
   pypy/trunk/src/pypy/objspace/std/listtype.py
   pypy/trunk/src/pypy/objspace/std/moduletype.py
   pypy/trunk/src/pypy/objspace/std/nonetype.py
   pypy/trunk/src/pypy/objspace/std/stringtype.py
   pypy/trunk/src/pypy/objspace/std/tupletype.py
Modified:
   pypy/trunk/src/pypy/interpreter/baseobjspace.py
   pypy/trunk/src/pypy/objspace/std/boolobject.py
   pypy/trunk/src/pypy/objspace/std/default.py
   pypy/trunk/src/pypy/objspace/std/dictobject.py
   pypy/trunk/src/pypy/objspace/std/floatobject.py
   pypy/trunk/src/pypy/objspace/std/intobject.py
   pypy/trunk/src/pypy/objspace/std/listobject.py
   pypy/trunk/src/pypy/objspace/std/moduleobject.py
   pypy/trunk/src/pypy/objspace/std/multimethod.py
   pypy/trunk/src/pypy/objspace/std/noneobject.py
   pypy/trunk/src/pypy/objspace/std/objspace.py
   pypy/trunk/src/pypy/objspace/std/stringobject.py
   pypy/trunk/src/pypy/objspace/std/test/test_typeobject.py
   pypy/trunk/src/pypy/objspace/std/tupleobject.py
   pypy/trunk/src/pypy/objspace/std/typeobject.py
Log:
that's it, type methods are now real multimethods just like the space's

Modified: pypy/trunk/src/pypy/interpreter/baseobjspace.py
==============================================================================
--- pypy/trunk/src/pypy/interpreter/baseobjspace.py	(original)
+++ pypy/trunk/src/pypy/interpreter/baseobjspace.py	Fri May 30 17:16:10 2003
@@ -223,6 +223,8 @@
     ('next',            'next',      1, ['next']),  # iterator interface
     ('call',            'call',      3, ['__call__']),
     ('get',             'get',       3, ['__get__']),
+    ('new',             'new',       3, ['__new__']),
+    ('init',            'init',      3, ['__init__']),
     ]
 
 ObjSpace.BuiltinModuleTable = [

Modified: pypy/trunk/src/pypy/objspace/std/boolobject.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/boolobject.py	(original)
+++ pypy/trunk/src/pypy/objspace/std/boolobject.py	Fri May 30 17:16:10 2003
@@ -1,9 +1,10 @@
 from pypy.objspace.std.objspace import *
+from booltype import W_BoolType
 
 
 class W_BoolObject(W_Object):
     delegate_once = {}
-    statictypename = 'bool'
+    statictype = W_BoolType
 
     def __init__(w_self, space, boolval):# please pass in a real bool, not an int
         W_Object.__init__(w_self, space)

Added: pypy/trunk/src/pypy/objspace/std/booltype.py
==============================================================================
--- (empty file)
+++ pypy/trunk/src/pypy/objspace/std/booltype.py	Fri May 30 17:16:10 2003
@@ -0,0 +1,7 @@
+from pypy.objspace.std.objspace import *
+from typeobject import W_TypeObject
+
+
+class W_BoolType(W_TypeObject):
+
+    typename = 'bool'

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	Fri May 30 17:16:10 2003
@@ -128,10 +128,11 @@
 # static types
 
 def default_type(space, w_obj):
-    w_type = w_obj.statictype
-    if w_type is None:
+    if w_obj.statictype is None:
         # XXX remove me, temporary
         return space.wrap(space.unwrap(w_obj).__class__)
-    return w_type
+    else:
+        w_type = space.get_typeinstance(w_obj.statictype)
+        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	Fri May 30 17:16:10 2003
@@ -1,4 +1,5 @@
-from objspace import *
+from pypy.objspace.std.objspace import *
+from dicttype import W_DictType
 from stringobject import W_StringObject
 from instmethobject import W_InstMethObject
 from pypy.interpreter.extmodule import make_builtin_func
@@ -33,7 +34,7 @@
 
 class W_DictObject(W_Object):
     delegate_once = {}
-    statictypename = 'dict'
+    statictype = W_DictType
 
     def __init__(w_self, space, list_pairs_w):
         W_Object.__init__(w_self, space)
@@ -59,33 +60,6 @@
     def cell(self,space,w_lookup):
         return space.wrap(self._cell(space,w_lookup))
 
-    def copy(w_self):
-        return W_DictObject(w_self.space,[(w_key,cell.get())
-                                          for w_key,cell in
-                                          w_self.non_empties()])
-    def items(w_self):
-        space = w_self.space
-        return space.newlist([ space.newtuple([w_key,cell.get()])
-                               for w_key,cell in
-                               w_self.non_empties()])
-
-    def keys(w_self):
-        space = w_self.space
-        return space.newlist([ w_key
-                               for w_key,cell in
-                               w_self.non_empties()])
-    
-    def values(w_self):
-        space = w_self.space
-        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()
@@ -169,5 +143,29 @@
             return space.newbool(r)
     return space.newbool(1)
         
-
 StdObjSpace.eq.register(eq_dict_dict, W_DictObject, W_DictObject)
+
+
+def dict_copy(space, w_self):
+    return W_DictObject(space, [(w_key,cell.get())
+                                      for w_key,cell in
+                                      w_self.non_empties()])
+def dict_items(space, w_self):
+    return space.newlist([ space.newtuple([w_key,cell.get()])
+                           for w_key,cell in
+                           w_self.non_empties()])
+
+def dict_keys(space, w_self):
+    return space.newlist([ w_key
+                           for w_key,cell in
+                           w_self.non_empties()])
+
+def dict_values(space, w_self):
+    return space.newlist([ cell.get()
+                           for w_key,cell in
+                           w_self.non_empties()])
+
+W_DictType.dict_copy  .register(dict_copy,   W_DictObject)
+W_DictType.dict_items .register(dict_items,  W_DictObject)
+W_DictType.dict_keys  .register(dict_keys,   W_DictObject)
+W_DictType.dict_values.register(dict_values, W_DictObject)

Added: pypy/trunk/src/pypy/objspace/std/dicttype.py
==============================================================================
--- (empty file)
+++ pypy/trunk/src/pypy/objspace/std/dicttype.py	Fri May 30 17:16:10 2003
@@ -0,0 +1,12 @@
+from pypy.objspace.std.objspace import *
+from typeobject import W_TypeObject
+
+
+class W_DictType(W_TypeObject):
+
+    typename = 'dict'
+
+    dict_copy   = MultiMethod('copy',   1)
+    dict_items  = MultiMethod('items',  1)
+    dict_keys   = MultiMethod('keys',   1)
+    dict_values = MultiMethod('values', 1)

Modified: pypy/trunk/src/pypy/objspace/std/floatobject.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/floatobject.py	(original)
+++ pypy/trunk/src/pypy/objspace/std/floatobject.py	Fri May 30 17:16:10 2003
@@ -1,4 +1,5 @@
-from objspace import *
+from pypy.objspace.std.objspace import *
+from floattype import W_FloatType
 
 ##############################################################
 # for the time being, all calls that are made to some external
@@ -17,7 +18,7 @@
        an argument"""
 
     delegate_once = {}
-    statictypename = 'float'
+    statictype = W_FloatType
     
     def __init__(w_self, space, floatval):
         W_Object.__init__(w_self, space)

Added: pypy/trunk/src/pypy/objspace/std/floattype.py
==============================================================================
--- (empty file)
+++ pypy/trunk/src/pypy/objspace/std/floattype.py	Fri May 30 17:16:10 2003
@@ -0,0 +1,7 @@
+from pypy.objspace.std.objspace import *
+from typeobject import W_TypeObject
+
+
+class W_FloatType(W_TypeObject):
+
+    typename = 'float'

Modified: pypy/trunk/src/pypy/objspace/std/intobject.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/intobject.py	(original)
+++ pypy/trunk/src/pypy/objspace/std/intobject.py	Fri May 30 17:16:10 2003
@@ -1,4 +1,5 @@
 from pypy.objspace.std.objspace import *
+from inttype import W_IntType
 from noneobject import W_NoneObject
 from boolobject import W_BoolObject
 from restricted_int import r_int, LONG_BIT
@@ -23,7 +24,7 @@
 class W_IntObject(W_Object):
 
     delegate_once = {}
-    statictypename = 'int'
+    statictype = W_IntType
     
     def __init__(w_self, space, intval):
         W_Object.__init__(w_self, space)

Added: pypy/trunk/src/pypy/objspace/std/inttype.py
==============================================================================
--- (empty file)
+++ pypy/trunk/src/pypy/objspace/std/inttype.py	Fri May 30 17:16:10 2003
@@ -0,0 +1,7 @@
+from pypy.objspace.std.objspace import *
+from typeobject import W_TypeObject
+
+
+class W_IntType(W_TypeObject):
+
+    typename = 'int'

Modified: pypy/trunk/src/pypy/objspace/std/listobject.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/listobject.py	(original)
+++ pypy/trunk/src/pypy/objspace/std/listobject.py	Fri May 30 17:16:10 2003
@@ -1,13 +1,15 @@
 from pypy.objspace.std.objspace import *
+from listtype import W_ListType
 from intobject import W_IntObject
 from sliceobject import W_SliceObject
 from instmethobject import W_InstMethObject
 from pypy.interpreter.extmodule import make_builtin_func
 from restricted_int import r_int, r_uint
 
+
 class W_ListObject(W_Object):
     delegate_once = {}
-    statictypename = 'list'
+    statictype = W_ListType
 
     def __init__(w_self, space, wrappeditems):
         W_Object.__init__(w_self, space)
@@ -27,45 +29,6 @@
         reprlist = [repr(w_item) for w_item in w_self.ob_item[:w_self.ob_size]]
         return "%s(%s)" % (w_self.__class__.__name__, ', '.join(reprlist))
 
-    def append(w_self, w_obj):
-        return list_append(w_self.space, w_self, w_obj)
-
-    append = implmethod().register(append, W_ANY)
-
-    def insert(w_self, w_idx, w_obj):
-        return list_insert(w_self.space, w_self, w_idx, w_obj)
-
-    insert = implmethod().register(insert, W_IntObject, W_ANY)
-
-    def extend(w_self, w_seq):
-        return list_extend(w_self.space, w_self, w_seq)
-
-    extend = implmethod().register(extend, W_ANY)
-
-    def pop(w_self, w_idx=-1):
-        return list_pop(w_self.space, w_self, w_idx)
-
-    pop = implmethod().register(pop, W_IntObject)
-
-    def remove(w_self, w_any):
-        return list_remove(w_self.space, w_self, w_any)
-
-    remove = implmethod().register(remove, W_ANY)
-
-    def index(w_self, w_any):
-        return list_index(w_self.space, w_self, w_any)
-
-    index = implmethod().register(index, W_ANY)
-
-    def count(w_self, w_any):
-        return list_count(w_self.space, w_self, w_any)
-
-    count = implmethod().register(count, W_ANY)
-
-    def reverse(w_self):
-        return list_reverse(w_self.space, w_self)
-
-    reverse = implmethod().register(reverse)
 
 def list_unwrap(space, w_list):
     items = [space.unwrap(w_item) for w_item in w_list.ob_item[:w_list.ob_size]]
@@ -410,6 +373,15 @@
         _reverse_slice(w_list.ob_item, 0, w_list.ob_size)
     return space.w_None
 
+W_ListType.list_append .register(list_append, W_ListObject, W_ANY)
+W_ListType.list_insert .register(list_insert, W_ListObject, W_IntObject, W_ANY)
+W_ListType.list_extend .register(list_extend, W_ListObject, W_ANY)
+W_ListType.list_pop    .register(list_pop,    W_ListObject, W_IntObject)
+W_ListType.list_remove .register(list_remove, W_ListObject, W_ANY)
+W_ListType.list_index  .register(list_index,  W_ListObject, W_ANY)
+W_ListType.list_count  .register(list_count,  W_ListObject, W_ANY)
+W_ListType.list_reverse.register(list_reverse,W_ListObject)
+
 """
 static PyMethodDef list_methods[] = {
     {"append",  (PyCFunction)listappend,  METH_O, append_doc},

Added: pypy/trunk/src/pypy/objspace/std/listtype.py
==============================================================================
--- (empty file)
+++ pypy/trunk/src/pypy/objspace/std/listtype.py	Fri May 30 17:16:10 2003
@@ -0,0 +1,35 @@
+from pypy.objspace.std.objspace import *
+from typeobject import W_TypeObject
+
+
+class W_ListType(W_TypeObject):
+
+    typename = 'list'
+
+    list_append = MultiMethod('append', 2)
+    list_insert = MultiMethod('insert', 3)
+    list_extend = MultiMethod('extend', 2)
+    list_pop    = MultiMethod('pop',    2)
+    list_remove = MultiMethod('remove', 2)
+    list_index  = MultiMethod('index',  2)
+    list_count  = MultiMethod('count',  2)
+    list_reverse= MultiMethod('reverse',1)
+
+
+# XXX right now, this is responsible for building a whole new list
+# XXX we'll worry about the __new__/__init__ distinction later
+def listtype_new(space, w_listtype, w_args, w_kwds):
+    if space.is_true(w_kwds):
+        raise OperationError(space.w_TypeError,
+                             space.wrap("no keyword arguments expected"))
+    args = space.unpackiterable(w_args)
+    if len(args) == 0:
+        list_w = []
+    elif len(args) == 1:
+        list_w = space.unpackiterable(args[0])
+    else:
+        raise OperationError(space.w_TypeError,
+                             space.wrap("list() takes at most 1 argument"))
+    return space.newlist(list_w)
+
+StdObjSpace.new.register(listtype_new, W_ListType, W_ANY, W_ANY)

Modified: pypy/trunk/src/pypy/objspace/std/moduleobject.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/moduleobject.py	(original)
+++ pypy/trunk/src/pypy/objspace/std/moduleobject.py	Fri May 30 17:16:10 2003
@@ -1,10 +1,11 @@
 from pypy.objspace.std.objspace import *
+from moduletype import W_ModuleType
 from dictobject import W_DictObject
 
 
 class W_ModuleObject(W_Object):
     delegate_once = {}
-    statictypename = 'module'
+    statictype = W_ModuleType
 
     def __init__(w_self, space, w_name):
         W_Object.__init__(w_self, space)

Added: pypy/trunk/src/pypy/objspace/std/moduletype.py
==============================================================================
--- (empty file)
+++ pypy/trunk/src/pypy/objspace/std/moduletype.py	Fri May 30 17:16:10 2003
@@ -0,0 +1,7 @@
+from pypy.objspace.std.objspace import *
+from typeobject import W_TypeObject
+
+
+class W_ModuleType(W_TypeObject):
+
+    typename = 'module'

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	Fri May 30 17:16:10 2003
@@ -4,18 +4,16 @@
 class FailedToImplement(Exception):
     "Signals the dispatcher to try harder."
 
-class W_ANY:
-    "Placeholder to allow dispatch on any value."
-    statictype = None
-
 
 class MultiMethod(object):
 
-    def __init__(self, operatorsymbol, arity, specialnames):
+    def __init__(self, operatorsymbol, arity, specialnames=None):
         "MultiMethod dispatching on the first 'arity' arguments."
         self.arity = arity
         self.operatorsymbol = operatorsymbol
         self.dispatch_table = {}
+        if specialnames is None:
+            specialnames = [operatorsymbol]
         self.specialnames = specialnames  # list like ['__xxx__', '__rxxx__']
 
     def register(self, function, *types):
@@ -34,39 +32,43 @@
         """Build a list of all possible combinations of delegated types,
         sorted by cost."""
         result = []
-        self.internal_buildchoices(types, (), (), (), result)
-        result.sort()
-        return [(delegators, function) for costs, delegators, function in result]
+        self.internal_buildchoices(types, (), (), result)
+        # the result is sorted by costs by construction.
+        # it is a list of (delegator, function) pairs.
+        return result
 
     def internal_buildchoices(self, initialtypes, currenttypes,
-                              currentcosts, currentdelegators, result):
+                              currentdelegators, result):
         if len(currenttypes) == self.arity:
             try:
                 function = self.dispatch_table[currenttypes]
             except KeyError:
                 pass
             else:
-                result.append((currentcosts, currentdelegators, function))
+                result.append((currentdelegators, function))
         else:
             nexttype = initialtypes[len(currenttypes)]
-            self.internal_buildchoices(initialtypes, currenttypes + (nexttype,),
-                                       currentcosts + (0,),
-                                       currentdelegators + (None,), result)
-            self.internal_buildchoices(initialtypes, currenttypes + (W_ANY,),
-                                       currentcosts + (1,),
-                                       currentdelegators + (None,), result)
-            delegators = getattr(nexttype, "delegate_once", {})
+            delegators = {}
+            while 1:
+                self.internal_buildchoices(initialtypes,
+                                           currenttypes + (nexttype,),
+                                           currentdelegators + (None,), result)
+                delegators.update(getattr(nexttype, "delegate_once", {}))
+                # before general delegation, try superclasses
+                if not nexttype.__bases__:
+                    break
+                nexttype, = nexttype.__bases__ # no multiple inheritance pleeease
             for othertype, delegator in delegators.items():
                 self.internal_buildchoices(initialtypes,
                                            currenttypes + (othertype,),
-                                           currentcosts + (2,),
                                            currentdelegators + (delegator,),
                                            result)
 
-    def slicetable(self, position, statictype):
+    def slicetable(self, position, slicetype):
         m = MultiMethod(self.operatorsymbol, self.arity, self.specialnames)
         for key, value in self.dispatch_table.iteritems():
-            if key[position].statictype == statictype:
+            if (key[position].statictype is not None and
+                issubclass(key[position].statictype, slicetype.__class__)):
                 m.dispatch_table[key] = value
         return m
 
@@ -114,6 +116,7 @@
                     arg = delegator(self.space, arg)
                 newargs.append(arg)
             newargs = tuple(newargs) + extraargs
+            # XXX 'prepend_space_argument' should now always be True anyway
             if prepend_space_argument:
                 newargs = (self.space,) + newargs
             try:
@@ -124,9 +127,9 @@
                     firstfailure = e
         raise firstfailure or FailedToImplement()
 
-    def slicetable(self, position, statictype):
+    def slicetable(self, position, slicetype):
         return BoundMultiMethod(self.space,
-            self.multimethod.slicetable(position, statictype))
+            self.multimethod.slicetable(position, slicetype))
 
     def is_empty(self):
         return self.multimethod.is_empty()

Modified: pypy/trunk/src/pypy/objspace/std/noneobject.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/noneobject.py	(original)
+++ pypy/trunk/src/pypy/objspace/std/noneobject.py	Fri May 30 17:16:10 2003
@@ -1,9 +1,10 @@
 from pypy.objspace.std.objspace import *
+from nonetype import W_NoneType
 
 
 class W_NoneObject(W_Object):
     delegate_once = {}
-    statictypename = 'NoneType'
+    statictype = W_NoneType
 
 
 def none_unwrap(space, w_none):

Added: pypy/trunk/src/pypy/objspace/std/nonetype.py
==============================================================================
--- (empty file)
+++ pypy/trunk/src/pypy/objspace/std/nonetype.py	Fri May 30 17:16:10 2003
@@ -0,0 +1,7 @@
+from pypy.objspace.std.objspace import *
+from typeobject import W_TypeObject
+
+
+class W_NoneType(W_TypeObject):
+
+    typename = 'NoneType'

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	Fri May 30 17:16:10 2003
@@ -18,19 +18,7 @@
     def get_builtin_impl_class(w_self):
         return w_self.__class__
 
-
-class implmethod(object):
-    def __init__(self):
-        self.dispatch_table = {}
-    def register(self, function, *types):
-        assert len(types) == function.func_code.co_argcount - 1, \
-               "wrong number of W_Xxx arguments to .register()"
-        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"
+W_ANY = W_Object  # synonyms for use in .register()
 
 
 ##################################################################
@@ -45,24 +33,26 @@
         pass
     AppFile.LOCAL_PATH = [PACKAGE_PATH]
 
-    BUILTIN_TYPES = {
-        'W_NoneObject':  'noneobject',
-        'W_BoolObject':  'boolobject',
-        'W_IntObject':   'intobject',
-        'W_FloatObject': 'floatobject',
-        'W_ListObject':  'listobject',
-        'W_DictObject':  'dictobject',
-        'W_StringObject':'stringobject',
-        'W_ModuleObject':'moduleobject',
-        'W_TupleObject': 'tupleobject',
-        }
+
+    def standard_types(self):
+        class result:
+            "Import here the types you want to have appear in __builtin__."
+
+            from booltype   import W_BoolType
+            from inttype    import W_IntType
+            from floattype  import W_FloatType
+            from tupletype  import W_TupleType
+            from listtype   import W_ListType
+            from dicttype   import W_DictType
+            from stringtype import W_StringType
+        return [value for key, value in result.__dict__.items()
+                      if not key.startswith('_')]   # don't look
+
 
     def initialize(self):
-        self.TYPE_CACHE = {}
         from noneobject    import W_NoneObject
         from boolobject    import W_BoolObject
         from cpythonobject import W_CPythonObject
-        from typeobject    import W_TypeObject, make_type_by_name
         self.w_None  = W_NoneObject(self)
         self.w_False = W_BoolObject(self, False)
         self.w_True  = W_BoolObject(self, True)
@@ -80,13 +70,11 @@
                 setattr(self, 'w_' + c.__name__, w_c)
                 newstuff[c.__name__] = w_c
         # make the types
-        for classname, modulename in self.BUILTIN_TYPES.iteritems():
-            mod = __import__(modulename, globals(), locals(), [classname])
-            cls = getattr(mod, classname)
-            w_type = make_type_by_name(self, cls.statictypename)
-            w_type.setup_builtin_type(cls)
-            setattr(self, 'w_' + cls.statictypename, w_type)
-            newstuff[cls.statictypename] = w_type
+        self.types_w = {}
+        for typeclass in self.standard_types():
+            w_type = self.get_typeinstance(typeclass)
+            setattr(self, 'w_' + typeclass.typename, w_type)
+            newstuff[typeclass.typename] = w_type
         
         self.make_builtins()
         self.make_sys()
@@ -97,6 +85,14 @@
 #        w_import = self.wrap(__import__)
 #        self.setitem(self.w_builtins, self.wrap("__import__"), w_import)
 
+    def get_typeinstance(self, typeclass):
+        # types_w maps each W_XxxType class to its unique-for-this-space instance
+        try:
+            w_type = self.types_w[typeclass]
+        except:
+            w_type = self.types_w[typeclass] = typeclass(self)
+        return w_type
+
     def wrap(self, x):
         "Wraps the Python value 'x' into one of the wrapper classes."
         if x is None:

Modified: pypy/trunk/src/pypy/objspace/std/stringobject.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/stringobject.py	(original)
+++ pypy/trunk/src/pypy/objspace/std/stringobject.py	Fri May 30 17:16:10 2003
@@ -1,4 +1,5 @@
 from pypy.objspace.std.objspace import *
+from stringtype import W_StringType
 from intobject   import W_IntObject
 from sliceobject import W_SliceObject
 from listobject import W_ListObject
@@ -12,9 +13,8 @@
 applicationfile = StdObjSpace.AppFile(__name__)
 
 class W_StringObject(W_Object):
-
     delegate_once = {}
-    statictypename = 'str'
+    statictype = W_StringType
 
     def __init__(w_self, space, str):
         W_Object.__init__(w_self, space)
@@ -30,34 +30,6 @@
     def hash(w_self):
         return W_IntObject(self, self._value.hash())
 
-    def join(w_self, w_list):
-        list = w_self.space.unpackiterable(w_list)
-        if list:
-            firstelem = 1
-            listlen = 0
-            reslen = 0  
-            for w_item in list:
-                reslen = reslen + w_item._value.len
-                listlen = listlen + 1
-
-            reslen = reslen + (listlen - 1) * w_self._value.len
-            res = CharArraySize(reslen)
-
-            pos = 0
-            for w_item in list:
-                if firstelem:
-                    res.setsubstring(pos, w_item._value.value())
-                    pos = pos + w_item._value.len 
-                    firstelem = 0
-                else:
-                    res.setsubstring(pos, w_self._value.value())
-                    pos = pos + w_self._value.len
-                    res.setsubstring(pos, w_item._value.value())
-                    pos = pos + w_item._value.len
-            return W_StringObject(w_self.space, res.value())
-        else:
-            return W_StringObject(w_self.space, "")
-
     def _char_isspace(ch):
         return ord(ch) in (9, 10, 11, 12, 13, 32)  
 
@@ -78,41 +50,39 @@
 
     def isspace(w_self):
        return is_generic(w_self, _char_isspace)
+   ## XXX fixme
 
-    def isdigit(w_self):
-        pass
+##    def isdigit(w_self):
+##        pass
 
-    def isupper(w_self):
-        pass
+##    def isupper(w_self):
+##        pass
 
-    def isupper(w_self):
-        pass
+##    def isupper(w_self):
+##        pass
     
-    def islower(w_self):
-        pass
+##    def islower(w_self):
+##        pass
 
-    def istitle(w_self):
-        pass
+##    def istitle(w_self):
+##        pass
 
-    def isalnum(w_self):
-        pass
+##    def isalnum(w_self):
+##        pass
 
-    def isalpha(w_self):
-        pass
+##    def isalpha(w_self):
+##        pass
 
-    isspace = implmethod().register(isspace)
-    isdigit = implmethod().register(isdigit)
-    isupper = implmethod().register(isupper)
-    islower = implmethod().register(islower)
-    istitle = implmethod().register(istitle)
-    isalnum = implmethod().register(isalnum)
-    isalpha = implmethod().register(isalpha)
+##    isspace = implmethod().register(isspace)
+##    isdigit = implmethod().register(isdigit)
+##    isupper = implmethod().register(isupper)
+##    islower = implmethod().register(islower)
+##    istitle = implmethod().register(istitle)
+##    isalnum = implmethod().register(isalnum)
+##    isalpha = implmethod().register(isalpha)
 
-    join = implmethod().register(join, W_ANY)
-    split = implmethod()
 
-
-def splitByWhitespace(w_self, w_none):
+def str_splitByWhitespace(space, w_self, w_none):
     res = []
     inword = 0
     value = w_self._value.value()
@@ -127,10 +97,10 @@
                 res.append(ch)
                 inword = 1
     for i in range(len(res)):
-        res[i] = W_StringObject(w_self.space, res[i])
-    return W_ListObject(w_self.space, res)
+        res[i] = W_StringObject(space, res[i])
+    return W_ListObject(space, res)
 
-def split(w_self, w_by):
+def str_split(space, w_self, w_by):
     res = []
     start = 0
     value = w_self._value.value()
@@ -147,12 +117,43 @@
     return W_ListObject(w_self.space, res)
 
 # XXX temporary hack
-W_StringObject.__dict__['split'].register(split, W_StringObject)
-
+W_StringType.str_split.register(str_split, W_StringObject, W_StringObject)
+W_StringType.str_split.register(str_splitByWhitespace,
+                                           W_StringObject, W_NoneObject)
 #We should erase the W_NoneObject, but register takes always
 #the same number of parameters. So you have to call split with
 #None as parameter instead of calling it without any parameter
-W_StringObject.__dict__['split'].register(splitByWhitespace, W_NoneObject)
+
+
+def str_join(space, w_self, w_list):
+    list = space.unpackiterable(w_list)
+    if list:
+        firstelem = 1
+        listlen = 0
+        reslen = 0  
+        for w_item in list:
+            reslen = reslen + w_item._value.len
+            listlen = listlen + 1
+
+        reslen = reslen + (listlen - 1) * w_self._value.len
+        res = CharArraySize(reslen)
+
+        pos = 0
+        for w_item in list:
+            if firstelem:
+                res.setsubstring(pos, w_item._value.value())
+                pos = pos + w_item._value.len 
+                firstelem = 0
+            else:
+                res.setsubstring(pos, w_self._value.value())
+                pos = pos + w_self._value.len
+                res.setsubstring(pos, w_item._value.value())
+                pos = pos + w_item._value.len
+        return W_StringObject(space, res.value())
+    else:
+        return W_StringObject(space, "")
+
+W_StringType.str_join.register(str_join, W_StringObject, W_ANY)
 
 
 def str_unwrap(space, w_str):
@@ -288,7 +289,7 @@
         r[i] = space.getitem(w_str, w(start + i*step))
     w_r = space.newlist(r)
     w_empty = space.newstring([])
-    return w_empty.join(w_r)
+    return str_join(w_empty, w_r)
 
 StdObjSpace.getitem.register(getitem_str_slice, 
                              W_StringObject, W_SliceObject)

Added: pypy/trunk/src/pypy/objspace/std/stringtype.py
==============================================================================
--- (empty file)
+++ pypy/trunk/src/pypy/objspace/std/stringtype.py	Fri May 30 17:16:10 2003
@@ -0,0 +1,10 @@
+from pypy.objspace.std.objspace import *
+from typeobject import W_TypeObject
+
+
+class W_StringType(W_TypeObject):
+
+    typename = 'str'
+
+    str_join  = MultiMethod('join', 2)
+    str_split = MultiMethod('split', 2)

Modified: pypy/trunk/src/pypy/objspace/std/test/test_typeobject.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/test/test_typeobject.py	(original)
+++ pypy/trunk/src/pypy/objspace/std/test/test_typeobject.py	Fri May 30 17:16:10 2003
@@ -37,6 +37,7 @@
 
     def test_float_sub(self):
         w = self.space.wrap
+        w(1.5)   # force floatobject imported
         for i in range(2):
             meth = tobj.PyMultimethodCode(self.space.sub, i, self.space.w_float)
             self.assertEqual(meth.multimethod.is_empty(), False)

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	Fri May 30 17:16:10 2003
@@ -1,12 +1,12 @@
 from pypy.objspace.std.objspace import *
+from tupletype import W_TupleType
 from intobject import W_IntObject
 from sliceobject import W_SliceObject
 
 
 class W_TupleObject(W_Object):
-
     delegate_once = {}
-    statictypename = 'tuple'
+    statictype = W_TupleType
 
     def __init__(w_self, space, wrappeditems):
         W_Object.__init__(w_self, space)

Added: pypy/trunk/src/pypy/objspace/std/tupletype.py
==============================================================================
--- (empty file)
+++ pypy/trunk/src/pypy/objspace/std/tupletype.py	Fri May 30 17:16:10 2003
@@ -0,0 +1,7 @@
+from pypy.objspace.std.objspace import *
+from typeobject import W_TypeObject
+
+
+class W_TupleType(W_TypeObject):
+
+    typename = 'tuple'

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	Fri May 30 17:16:10 2003
@@ -1,37 +1,36 @@
 from pypy.interpreter import pycode
 from pypy.objspace.std.objspace import *
-from pypy.objspace.std.dictobject import W_DictObject
 
 
 class W_TypeObject(W_Object):
     delegate_once = {}
-    statictypename = 'type'
+    #statictype = W_TypeType    (hacked into place in typetype.py)
 
-    def __init__(w_self, space, w_tpname):
+    def __init__(w_self, space):
         W_Object.__init__(w_self, space)
-        w_self.w_tpname = w_tpname
-        w_self.builtin_implementations = []
+        w_self.w_tpname = space.wrap(w_self.typename)
         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)
+        # import all multimethods of the space and of the type class
+        for multimethod in (hack_out_multimethods(space) +
+                            hack_out_multimethods(w_self)):
+            for i in range(len(multimethod.specialnames)):
+                w_self.multimethods[multimethod.specialnames[i]] = multimethod, i
+
+##    XXX remove me
+##    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"
@@ -48,13 +47,9 @@
         return space.newfunction(code, space.w_None, space.w_None)
 
 
-def make_type_by_name(space, tpname):
-    try:
-        w_type = space.TYPE_CACHE[tpname]
-    except KeyError:
-        w_type = space.TYPE_CACHE[tpname] = W_TypeObject(space,
-                                                         space.wrap(tpname))
-    return w_type
+def hack_out_multimethods(instance):
+    return [value for value in instance.__class__.__dict__.itervalues()
+                  if isinstance(value, MultiMethod)]
 
 
 class PyMultimethodCode(pycode.PyBaseCode):
@@ -63,14 +58,8 @@
         pycode.PyBaseCode.__init__(self)
         argnames = ['x%d'%(i+1) for i in range(multimethod.multimethod.arity)]
         if w_type is not None:
-            # '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
+            multimethod = multimethod.slicetable(bound_position, w_type)
+            argnames.insert(0, argnames.pop(bound_position))
         self.multimethod = multimethod
         self.co_name = multimethod.multimethod.operatorsymbol
         self.co_flags = 0
@@ -90,8 +79,7 @@
         dispatchargs = tuple(dispatchargs)
         initialtypes = tuple(initialtypes)
         try:
-            return multimethod.perform_call(dispatchargs, initialtypes,
-                prepend_space_argument = self.prepend_space_argument)
+            return multimethod.perform_call(dispatchargs, initialtypes)
         except FailedToImplement, e:
             if e.args:
                 raise OperationError(*e.args)
@@ -100,31 +88,34 @@
 
 
 def type_call(space, w_type, w_args, w_kwds):
+    w_newobject = space.new(w_type, w_args, w_kwds)
+    # XXX call __init__() later
+    return w_newobject
     
-    #        H  H   AA    CCC  K  K
-    #        H  H  A  A  C     K K
-    #        HHHH  A  A  C     KK
-    #        H  H  AAAA  C     K K
-    #        H  H  A  A   CCC  K  K
-
-    tpname = space.unwrap(w_type.w_tpname)
-    args = space.unpackiterable(w_args)
-    if tpname == 'type':
-        assert len(args) == 1
-        return space.type(args[0])
-    if tpname == 'list':
-        assert len(args) == 1
-        return space.newlist(space.unpackiterable(args[0]))
-    if tpname == 'tuple':
-        assert len(args) == 1
-        return space.newtuple(space.unpackiterable(args[0]))
-    if tpname == 'str':
-        assert len(args) == 1
-        return space.str(args[0])
-
-    import __builtin__
-    hacky = getattr(__builtin__, tpname)(
-        *space.unwrap(w_args), **space.unwrap(w_kwds))
-    return space.wrap(hacky)
+##    #        H  H   AA    CCC  K  K
+##    #        H  H  A  A  C     K K
+##    #        HHHH  A  A  C     KK
+##    #        H  H  AAAA  C     K K
+##    #        H  H  A  A   CCC  K  K
+
+##    tpname = space.unwrap(w_type.w_tpname)
+##    args = space.unpackiterable(w_args)
+##    if tpname == 'type':
+##        assert len(args) == 1
+##        return space.type(args[0])
+##    if tpname == 'list':
+##        assert len(args) == 1
+##        return space.newlist(space.unpackiterable(args[0]))
+##    if tpname == 'tuple':
+##        assert len(args) == 1
+##        return space.newtuple(space.unpackiterable(args[0]))
+##    if tpname == 'str':
+##        assert len(args) == 1
+##        return space.str(args[0])
+
+##    import __builtin__
+##    hacky = getattr(__builtin__, tpname)(
+##        *space.unwrap(w_args), **space.unwrap(w_kwds))
+##    return space.wrap(hacky)
 
 StdObjSpace.call.register(type_call, W_TypeObject, W_ANY, W_ANY)


More information about the Pypy-commit mailing list