[pypy-svn] r8969 - in pypy/dist/pypy: interpreter module objspace/std objspace/std/test

pedronis at codespeak.net pedronis at codespeak.net
Mon Feb 7 20:26:08 CET 2005


Author: pedronis
Date: Mon Feb  7 20:26:07 2005
New Revision: 8969

Added:
   pypy/dist/pypy/objspace/std/model.py   (props changed)
      - copied unchanged from r8967, pypy/branch/dist-simpler-multimethods/pypy/objspace/std/model.py
Modified:
   pypy/dist/pypy/interpreter/gateway.py
   pypy/dist/pypy/interpreter/pycode.py
   pypy/dist/pypy/module/__builtin__interp.py
   pypy/dist/pypy/objspace/std/boolobject.py
   pypy/dist/pypy/objspace/std/booltype.py
   pypy/dist/pypy/objspace/std/default.py
   pypy/dist/pypy/objspace/std/dictobject.py
   pypy/dist/pypy/objspace/std/dicttype.py
   pypy/dist/pypy/objspace/std/fake.py
   pypy/dist/pypy/objspace/std/floatobject.py
   pypy/dist/pypy/objspace/std/floattype.py
   pypy/dist/pypy/objspace/std/intobject.py
   pypy/dist/pypy/objspace/std/inttype.py
   pypy/dist/pypy/objspace/std/itertype.py
   pypy/dist/pypy/objspace/std/listobject.py
   pypy/dist/pypy/objspace/std/longobject.py
   pypy/dist/pypy/objspace/std/longtype.py
   pypy/dist/pypy/objspace/std/multimethod.py
   pypy/dist/pypy/objspace/std/noneobject.py
   pypy/dist/pypy/objspace/std/objspace.py
   pypy/dist/pypy/objspace/std/register_all.py
   pypy/dist/pypy/objspace/std/sliceobject.py
   pypy/dist/pypy/objspace/std/stdtypedef.py
   pypy/dist/pypy/objspace/std/stringobject.py
   pypy/dist/pypy/objspace/std/stringtype.py
   pypy/dist/pypy/objspace/std/test/test_multimethod.py
   pypy/dist/pypy/objspace/std/tupleobject.py
   pypy/dist/pypy/objspace/std/tupletype.py
   pypy/dist/pypy/objspace/std/typeobject.py
   pypy/dist/pypy/objspace/std/unicodeobject.py
Log:

merged dist-simpler-multimethods branch.



Modified: pypy/dist/pypy/interpreter/gateway.py
==============================================================================
--- pypy/dist/pypy/interpreter/gateway.py	(original)
+++ pypy/dist/pypy/interpreter/gateway.py	Mon Feb  7 20:26:07 2005
@@ -14,12 +14,14 @@
 
 from pypy.tool import hack
 from pypy.interpreter.error import OperationError 
-from pypy.interpreter import eval, pycode
+from pypy.interpreter import eval
 from pypy.interpreter.function import Function, Method
 from pypy.interpreter.baseobjspace import W_Root,ObjSpace,Wrappable
 from pypy.interpreter.argument import Arguments
 from pypy.tool.cache import Cache 
 
+NoneNotWrapped = object()
+
 class Signature:
     def __init__(self, func=None, argnames=None, varargname=None,
                  kwargname=None, name = None):
@@ -127,7 +129,16 @@
     assert new_sig.varargname is None,(
         "built-in function %r has conflicting rest args specs" % orig_sig.func)
     new_sig.varargname = argname[:-2]
-        
+
+def unwrap_spec_check_w_args(orig_sig, new_sig):
+    argname = orig_sig.next()
+    assert argname.startswith('w_'), (
+        "rest arguments arg %s of built-in function %r should start 'w_'" %
+        (argname, orig_sig.func))
+    assert new_sig.varargname is None,(
+        "built-in function %r has conflicting rest args specs" % orig_sig.func)
+    new_sig.varargname = argname[2:]
+      
 # recipes for checking interp2app func argumes wrt unwrap_spec
 unwrap_spec_checks = {
     ObjSpace: unwrap_spec_check_space,
@@ -136,6 +147,7 @@
     Arguments: unwrap_spec_check_arguments,
     '*': unwrap_spec_check_starargs,
     'args_w': unwrap_spec_check_args_w,
+    'w_args': unwrap_spec_check_w_args,    
 }
 
 def unwrap_spec_emit_space(orig_sig, new_sig):
@@ -178,6 +190,13 @@
              (new_sig.through_scope_w))
     new_sig.through_scope_w += 1
     new_sig.run_args.append("self.args_w")
+
+def unwrap_spec_emit_w_args(orig_sig, new_sig):
+    cur = new_sig.through_scope_w
+    new_sig.setfastscope.append(
+        "self.w_args = scope_w[%d]" % cur)
+    new_sig.through_scope_w += 1
+    new_sig.run_args.append("self.w_args")
         
 # recipes for emitting unwrapping code for arguments of a interp2app func
 # wrt a unwrap_spec
@@ -188,6 +207,7 @@
     Arguments: unwrap_spec_emit_arguments,
     '*': unwrap_spec_emit_starargs,
     'args_w': unwrap_spec_emit_args_w,
+    'w_args': unwrap_spec_emit_w_args,
 }
 
 # unwrap_spec_check/emit for str,int,float
@@ -257,10 +277,12 @@
         #  'self' is used to specify a self method argument
         #  baseobjspace.W_Root is for wrapped arguments to keep wrapped
         #  argument.Arguments is for a final rest arguments Arguments object
-        # 'args_w' for unpacktuple applied rest arguments
+        # 'args_w' for unpacktuple applied to rest arguments
+        # 'w_args' for rest arguments passed as wrapped tuple
         # str,int,float: unwrap argument as such type
         
         # First extract the signature from the (CPython-level) code object
+        from pypy.interpreter import pycode
         argnames, varargname, kwargname = pycode.cpython_code_signature(func.func_code)
 
         if unwrap_spec is None:
@@ -459,6 +481,7 @@
                 raise ValueError, ("function name must start with 'app_'; "
                                    "%r does not" % app.func_name)
             app_name = app.func_name[4:]
+        self.__name__ = app.func_name
         self.name = app_name
         self._staticcode = app.func_code
         self._staticglobals = app.func_globals
@@ -466,6 +489,7 @@
 
     def getcode(self, space):
         "NOT_RPYTHON"
+        from pypy.interpreter import pycode
         code = pycode.PyCode(space)
         code._from_code(self._staticcode)
         return code
@@ -518,6 +542,7 @@
         self._code = BuiltinCode(f, ismethod=ismethod,
                                   spacearg=spacearg,
                                   unwrap_spec=unwrap_spec)
+        self.__name__ = f.func_name
         self.name = app_name
         self._staticdefs = list(f.func_defaults or ())
         #if self._staticdefs:
@@ -531,8 +556,8 @@
         "NOT_RPYTHON"
         defs_w = []
         for val in self._staticdefs:
-            if val is None:
-                defs_w.append(val)
+            if val is NoneNotWrapped:
+                defs_w.append(None)
             else:
                 defs_w.append(space.wrap(val))
         return defs_w

Modified: pypy/dist/pypy/interpreter/pycode.py
==============================================================================
--- pypy/dist/pypy/interpreter/pycode.py	(original)
+++ pypy/dist/pypy/interpreter/pycode.py	Mon Feb  7 20:26:07 2005
@@ -6,6 +6,7 @@
 
 import dis
 from pypy.interpreter import eval
+from pypy.interpreter.gateway import NoneNotWrapped
 from pypy.tool.cache import Cache 
 
 # helper
@@ -194,7 +195,8 @@
                           w_argcount, w_nlocals, w_stacksize, w_flags,
                           w_codestring, w_constants, w_names,
                           w_varnames, w_filename, w_name, w_firstlineno,
-                          w_lnotab, w_freevars=None, w_cellvars=None):
+                          w_lnotab, w_freevars=NoneNotWrapped,
+                          w_cellvars=NoneNotWrapped):
         code = space.allocate_instance(PyCode, w_subtype)
         code.__init__(space)
         # XXX typechecking everywhere!

Modified: pypy/dist/pypy/module/__builtin__interp.py
==============================================================================
--- pypy/dist/pypy/module/__builtin__interp.py	(original)
+++ pypy/dist/pypy/module/__builtin__interp.py	Mon Feb  7 20:26:07 2005
@@ -5,6 +5,7 @@
 from pypy.interpreter.pycode import PyCode
 from pypy.interpreter.error import OperationError
 from pypy.interpreter.baseobjspace import BaseWrappable, W_Root
+from pypy.interpreter.gateway import NoneNotWrapped
 
 import __builtin__ as cpy_builtin
 
@@ -225,7 +226,7 @@
 compile.unwrap_spec = [str,str,str,int,int]
 
 
-def eval(w_source, w_globals=None, w_locals=None):
+def eval(w_source, w_globals=NoneNotWrapped, w_locals=NoneNotWrapped):
     w = space.wrap
 
     if space.is_true(space.isinstance(w_source, space.w_str)):
@@ -259,7 +260,7 @@
     space.delattr(w_object, w_name)
     return space.w_None
 
-def getattr(w_object, w_name, w_defvalue=None):
+def getattr(w_object, w_name, w_defvalue=NoneNotWrapped):
     try:
         return space.getattr(w_object, w_name)
     except OperationError, e:
@@ -278,9 +279,7 @@
 def hex(w_val):
     return space.hex(w_val)
 
-def round(w_val, w_n=None):
-    if w_n is None:
-        w_n = space.wrap(0)
+def round(w_val, w_n=0):
     return space.round(w_val, w_n)
 
 def id(w_object):
@@ -295,7 +294,7 @@
 def _issubtype(w_cls1, w_cls2):
     return space.issubtype(w_cls1, w_cls2)
 
-def iter(w_collection_or_callable, w_sentinel=None):
+def iter(w_collection_or_callable, w_sentinel=NoneNotWrapped):
     if w_sentinel is None:
         return space.iter(w_collection_or_callable)
     else:
@@ -308,8 +307,6 @@
     return space.ord(w_val)
 
 def pow(w_base, w_exponent, w_modulus=None):
-    if w_modulus is None:
-        w_modulus = space.w_None
     return space.pow(w_base, w_exponent, w_modulus)
 
 def repr(w_object):

Modified: pypy/dist/pypy/objspace/std/boolobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/boolobject.py	(original)
+++ pypy/dist/pypy/objspace/std/boolobject.py	Mon Feb  7 20:26:07 2005
@@ -16,22 +16,20 @@
         """ representation for debugging purposes """
         return "%s(%s)" % (w_self.__class__.__name__, w_self.boolval)
 
+    def unwrap(w_self):
+        return w_self.boolval
+
 registerimplementation(W_BoolObject)
 
 # bool-to-int delegation requires translating the .boolvar attribute
 # to an .intval one
-def delegate__Bool(space, w_bool):
-    return intobject.W_IntObject(space, int(w_bool.boolval))
-delegate__Bool.result_class = intobject.W_IntObject
-delegate__Bool.priority = PRIORITY_PARENT_TYPE
+def delegate_Bool2Int(w_bool):
+    return intobject.W_IntObject(w_bool.space, int(w_bool.boolval))
 
 
 def nonzero__Bool(space, w_bool):
     return w_bool
 
-def unwrap__Bool(space, w_bool):
-    return w_bool.boolval
-
 def repr__Bool(space, w_bool):
     if w_bool.boolval:
         return space.wrap('True')

Modified: pypy/dist/pypy/objspace/std/booltype.py
==============================================================================
--- pypy/dist/pypy/objspace/std/booltype.py	(original)
+++ pypy/dist/pypy/objspace/std/booltype.py	Mon Feb  7 20:26:07 2005
@@ -5,7 +5,7 @@
 
 
 def descr__new__(space, w_booltype, w_obj=None):
-    if w_obj is not None and space.is_true(w_obj):
+    if space.is_true(w_obj):
         return space.w_True
     else:
         return space.w_False

Modified: pypy/dist/pypy/objspace/std/default.py
==============================================================================
--- pypy/dist/pypy/objspace/std/default.py	(original)
+++ pypy/dist/pypy/objspace/std/default.py	Mon Feb  7 20:26:07 2005
@@ -13,7 +13,7 @@
 
 # __init__ should succeed if called internally as a multimethod
 
-def init__ANY(space, w_obj, w_args, w_kwds):
+def init__ANY(space, w_obj, __args__):
     pass
 
 
@@ -216,9 +216,6 @@
 
 # ugh
 
-class UnwrapError(Exception):
-    pass
-
 def typed_unwrap_error_msg(space, expected, w_obj):
     w = space.wrap
     type_name = space.str_w(space.getattr(space.type(w_obj),w("__name__")))
@@ -236,11 +233,5 @@
     raise OperationError(space.w_TypeError,
                          typed_unwrap_error_msg(space, "float", w_obj))
 
-def unwrap__ANY(space, w_obj):
-    if isinstance(w_obj, BaseWrappable):
-        return w_obj
-    else:
-        raise UnwrapError, 'cannot unwrap %r' % (w_obj,)
-
 
 register_all(vars())

Modified: pypy/dist/pypy/objspace/std/dictobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/dictobject.py	(original)
+++ pypy/dist/pypy/objspace/std/dictobject.py	Mon Feb  7 20:26:07 2005
@@ -98,40 +98,40 @@
                 freeslot = entry
             perturb >>= 5
 
-registerimplementation(W_DictObject)
+    def unwrap(w_dict):
+        space = w_dict.space
+        result = {}
+        for entry in w_dict.non_empties():
+            # XXX generic mixed types unwrap
+            result[space.unwrap(entry.w_key)] = space.unwrap(entry.w_value)
+        return result
 
+registerimplementation(W_DictObject)
 
-def unwrap__Dict(space, w_dict):
-    result = {}
-    for entry in w_dict.non_empties():
-        result[space.unwrap(entry.w_key)] = space.unwrap(entry.w_value) # XXX generic mixed types unwrap
-    return result
 
-def init__Dict(space, w_dict, w_args, w_kwds):
+def init__Dict(space, w_dict, __args__):
+    w_src, w_kwds = __args__.parse('dict',
+                          (['seq_or_map'], None, 'kwargs'), # signature
+                          [W_DictObject(space, [])])        # default argument
     dict_clear__Dict(space, w_dict)
-    args = space.unpackiterable(w_args)
-    if len(args) == 0:
-        pass
-    elif len(args) == 1:
-        # XXX do dict({...}) with dict_update__Dict_Dict()
-        try:
-            space.getattr(args[0], space.wrap("keys"))
-        except OperationError:
-            list_of_w_pairs = space.unpackiterable(args[0])
-            for w_pair in list_of_w_pairs:
-                pair = space.unpackiterable(w_pair)
-                if len(pair)!=2:
-                    raise OperationError(space.w_ValueError,
-                                 space.wrap("dict() takes a sequence of pairs"))
-                w_k, w_v = pair
-                setitem__Dict_ANY_ANY(space, w_dict, w_k, w_v)
-        else:
-            from pypy.objspace.std.dicttype import dict_update__ANY_ANY
-            dict_update__ANY_ANY(space, w_dict, args[0])
+    # XXX do dict({...}) with dict_update__Dict_Dict()
+    try:
+        space.getattr(w_src, space.wrap("keys"))
+    except OperationError:
+        list_of_w_pairs = space.unpackiterable(w_src)
+        for w_pair in list_of_w_pairs:
+            pair = space.unpackiterable(w_pair)
+            if len(pair)!=2:
+                raise OperationError(space.w_ValueError,
+                             space.wrap("dict() takes a sequence of pairs"))
+            w_k, w_v = pair
+            setitem__Dict_ANY_ANY(space, w_dict, w_k, w_v)
     else:
-        raise OperationError(space.w_TypeError,
-                             space.wrap("dict() takes at most 1 argument"))
-    space.call_method(w_dict, 'update', w_kwds)
+        if space.is_true(w_src):
+            from pypy.objspace.std.dicttype import dict_update__ANY_ANY
+            dict_update__ANY_ANY(space, w_dict, w_src)
+    if space.is_true(w_kwds):
+        space.call_method(w_dict, 'update', w_kwds)
 
 def getitem__Dict_ANY(space, w_dict, w_lookup):
     entry = w_dict.lookdict(w_dict.hash(w_lookup), w_lookup)

Modified: pypy/dist/pypy/objspace/std/dicttype.py
==============================================================================
--- pypy/dist/pypy/objspace/std/dicttype.py	(original)
+++ pypy/dist/pypy/objspace/std/dicttype.py	Mon Feb  7 20:26:07 2005
@@ -8,7 +8,7 @@
 dict_has_key    = MultiMethod('has_key',       2)
 dict_clear      = MultiMethod('clear',         1)
 dict_get        = MultiMethod('get',           3, defaults=(None,))
-dict_pop        = MultiMethod('pop',           2, varargs=True)
+dict_pop        = MultiMethod('pop',           2, w_varargs=True)
 dict_popitem    = MultiMethod('popitem',       1)
 dict_setdefault = MultiMethod('setdefault',    3, defaults=(None,))
 dict_update     = MultiMethod('update',        2)

Modified: pypy/dist/pypy/objspace/std/fake.py
==============================================================================
--- pypy/dist/pypy/objspace/std/fake.py	(original)
+++ pypy/dist/pypy/objspace/std/fake.py	Mon Feb  7 20:26:07 2005
@@ -4,7 +4,7 @@
 from pypy.interpreter.function import Function
 from pypy.objspace.std.stdtypedef import *
 from pypy.objspace.std.objspace import W_Object, StdObjSpace
-from pypy.objspace.std.default import UnwrapError
+from pypy.objspace.std.model import UnwrapError
 from pypy.tool.cache import Cache 
 
 # this file automatically generates non-reimplementations of CPython
@@ -83,13 +83,12 @@
         def __init__(w_self, space, val):
             W_Object.__init__(w_self, space)
             w_self.val = val
+        def unwrap(w_self):
+            return w_self.val
     # cannot write to W_Fake.__name__ in Python 2.2!
     W_Fake = type(W_Object)('W_Fake%s'%(cpy_type.__name__.capitalize()),
                             (W_Object,),
                             dict(W_Fake.__dict__.items()))
-    def fake_unwrap(space, w_obj):
-        return w_obj.val
-    StdObjSpace.unwrap.register(fake_unwrap, W_Fake)
     W_Fake.typedef.fakedcpytype = cpy_type
     return W_Fake
 

Modified: pypy/dist/pypy/objspace/std/floatobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/floatobject.py	(original)
+++ pypy/dist/pypy/objspace/std/floatobject.py	Mon Feb  7 20:26:07 2005
@@ -21,14 +21,19 @@
         W_Object.__init__(w_self, space)
         w_self.floatval = floatval
 
+    def unwrap(w_self):
+        return w_self.floatval
+
 
 registerimplementation(W_FloatObject)
 
+# bool-to-float delegation
+def delegate_Bool2Float(w_bool):
+    return W_FloatObject(w_bool.space, float(w_bool.boolval))
+
 # int-to-float delegation
-def delegate__Int(space, w_intobj):
-    return W_FloatObject(space, float(w_intobj.intval))
-delegate__Int.result_class = W_FloatObject
-delegate__Int.priority = PRIORITY_CHANGE_TYPE
+def delegate_Int2Float(w_intobj):
+    return W_FloatObject(w_intobj.space, float(w_intobj.intval))
 
 
 # float__Float is supposed to do nothing, unless it has
@@ -49,9 +54,6 @@
 def float_w__Float(space, w_float):
     return w_float.floatval
 
-def unwrap__Float(space, w_float):
-    return w_float.floatval
-
 def app_repr__Float(f):
     r = "%.17g"%f
     for c in r:

Modified: pypy/dist/pypy/objspace/std/floattype.py
==============================================================================
--- pypy/dist/pypy/objspace/std/floattype.py	(original)
+++ pypy/dist/pypy/objspace/std/floattype.py	Mon Feb  7 20:26:07 2005
@@ -1,11 +1,9 @@
 from pypy.objspace.std.stdtypedef import *
 from pypy.interpreter.error import OperationError
 
-def descr__new__(space, w_floattype, w_value=None):
+def descr__new__(space, w_floattype, w_value=0.0):
     from pypy.objspace.std.floatobject import W_FloatObject
-    if w_value is None:
-        value = 0.0
-    elif space.is_true(space.isinstance(w_value, space.w_str)):
+    if space.is_true(space.isinstance(w_value, space.w_str)):
         try:
             value = float(space.str_w(w_value))
         except ValueError, e:

Modified: pypy/dist/pypy/objspace/std/intobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/intobject.py	(original)
+++ pypy/dist/pypy/objspace/std/intobject.py	Mon Feb  7 20:26:07 2005
@@ -28,6 +28,9 @@
         """ representation for debugging purposes """
         return "%s(%d)" % (w_self.__class__.__name__, w_self.intval)
 
+    def unwrap(w_self):
+        return int(w_self.intval)
+
 
 registerimplementation(W_IntObject)
 
@@ -43,9 +46,6 @@
 def int_w__Int(space, w_int1):
     return int(w_int1.intval)
 
-def unwrap__Int(space, w_int1):
-    return int(w_int1.intval)
-
 def repr__Int(space, w_int1):
     a = w_int1.intval
     res = str(a)

Modified: pypy/dist/pypy/objspace/std/inttype.py
==============================================================================
--- pypy/dist/pypy/objspace/std/inttype.py	(original)
+++ pypy/dist/pypy/objspace/std/inttype.py	Mon Feb  7 20:26:07 2005
@@ -1,14 +1,13 @@
 from pypy.objspace.std.stdtypedef import *
 from pypy.objspace.std.strutil import string_to_int
 from pypy.interpreter.error import OperationError
+from pypy.interpreter.gateway import NoneNotWrapped
 
-def descr__new__(space, w_inttype, w_value=None, w_base=None):
+def descr__new__(space, w_inttype, w_value=0, w_base=NoneNotWrapped):
     from pypy.objspace.std.intobject import W_IntObject
     if w_base is None:
         # check for easy cases
-        if w_value is None:
-            value = 0
-        elif isinstance(w_value, W_IntObject):
+        if isinstance(w_value, W_IntObject):
             value = w_value.intval
         elif space.is_true(space.isinstance(w_value, space.w_str)):
             try:

Modified: pypy/dist/pypy/objspace/std/itertype.py
==============================================================================
--- pypy/dist/pypy/objspace/std/itertype.py	(original)
+++ pypy/dist/pypy/objspace/std/itertype.py	Mon Feb  7 20:26:07 2005
@@ -2,5 +2,5 @@
 
 # ____________________________________________________________
 
-iter_typedef = StdTypeDef("sequence-iterator",
+iter_typedef = StdTypeDef("sequenceiterator",
     )

Modified: pypy/dist/pypy/objspace/std/listobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/listobject.py	(original)
+++ pypy/dist/pypy/objspace/std/listobject.py	Mon Feb  7 20:26:07 2005
@@ -29,52 +29,47 @@
         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 unwrap(w_list):
+        space = w_list.space
+        items = [space.unwrap(w_item) for w_item in w_list.ob_item[:w_list.ob_size]]# XXX generic mixed types unwrap
+        return list(items)
+
 
 registerimplementation(W_ListObject)
 
 
-def unwrap__List(space, w_list): 
-    items = [space.unwrap(w_item) for w_item in w_list.ob_item[:w_list.ob_size]]# XXX generic mixed types unwrap
-    return list(items)
-
-def init__List(space, w_list, w_args, w_kwds):
-    if space.is_true(w_kwds):
-        raise OperationError(space.w_TypeError,
-                             space.wrap("no keyword arguments expected"))
+def init__List(space, w_list, __args__):
+    w_iterable, = __args__.parse('list',
+                               (['sequence'], None, None),   # signature
+                               [W_ListObject(space, [])])    # default argument
     w_list.ob_size = 0  # XXX think about it later
-    args = space.unpackiterable(w_args)
-    if len(args) == 0:
-        pass   # empty list
-    elif len(args) == 1:
-        w_iterable = args[0]
-        length = 0
+	
+    length = 0
+    try:
+        length = space.int_w(space.len(w_iterable))
+        if length < 0:
+            length = 8 
+    except OperationError, e:
+        pass # for now
+    _list_resize(w_list, length)
+    w_iterator = space.iter(w_iterable)
+    while True:
         try:
-            length = space.int_w(space.len(w_iterable))
-            if length < 0:
-                length = 8 
+            w_item = space.next(w_iterator)
         except OperationError, e:
-            pass # for now
-        _list_resize(w_list, length)
-        w_iterator = space.iter(w_iterable)
-        while True:
-            try:
-                w_item = space.next(w_iterator)
-            except OperationError, e:
-                if not e.match(space, space.w_StopIteration):
-                    raise
-                break  # done
-            _ins1(w_list, w_list.ob_size, w_item)
-    else:
-        raise OperationError(space.w_TypeError,
-                             space.wrap("list() takes at most 1 argument"))
+            if not e.match(space, space.w_StopIteration):
+                raise
+            break  # done
+        _ins1(w_list, w_list.ob_size, w_item)
+
 
 def len__List(space, w_list):
     result = w_list.ob_size
     return W_IntObject(space, result)
 
-def getitem__List_Int(space, w_list, w_index):
+def getitem__List_ANY(space, w_list, w_index):
     items = w_list.ob_item
-    idx = w_index.intval
+    idx = space.int_w(w_index)
     if idx < 0:
         idx += w_list.ob_size
     if idx < 0 or idx >= w_list.ob_size:
@@ -129,9 +124,8 @@
     list_extend__List_ANY(space, w_list1, w_iterable2)
     return w_list1
 
-def mul__List_Int(space, w_list, w_int):
+def mul_list_times(space, w_list, times):
     w_res = W_ListObject(space, [])
-    times = w_int.intval
     src = w_list.ob_item
     size = w_list.ob_size
     newlen = size * times  # XXX check overflow
@@ -145,8 +139,11 @@
     w_res.ob_size = p
     return w_res
 
-def mul__Int_List(space, w_int, w_list):
-    return mul__List_Int(space, w_list, w_int)
+def mul__List_ANY(space, w_list, w_times):
+    return mul_list_times(space, w_list, space.int_w(w_times))
+
+def mul__ANY_List(space, w_times, w_list):
+    return mul_list_times(space, w_list, space.int_w(w_times))
 
 def eq__List_List(space, w_list1, w_list2):
     items1 = w_list1.ob_item
@@ -188,8 +185,8 @@
 # upto here, lists are nearly identical to tuples, despite the
 # fact that we now support over-allocation!
 
-def delitem__List_Int(space, w_list, w_idx):
-    i = w_idx.intval
+def delitem__List_ANY(space, w_list, w_idx):
+    i = space.int_w(w_idx)
     if i < 0:
         i += w_list.ob_size
     if i < 0 or i >= w_list.ob_size:
@@ -217,9 +214,9 @@
         _del_slice(w_list, i, i+1)
     return space.w_None
 
-def setitem__List_Int_ANY(space, w_list, w_index, w_any):
+def setitem__List_ANY_ANY(space, w_list, w_index, w_any):
     items = w_list.ob_item
-    idx = w_index.intval
+    idx = space.int_w(w_index)
     if idx < 0:
         idx += w_list.ob_size
     if idx < 0 or idx >= w_list.ob_size:

Modified: pypy/dist/pypy/objspace/std/longobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/longobject.py	(original)
+++ pypy/dist/pypy/objspace/std/longobject.py	Mon Feb  7 20:26:07 2005
@@ -17,9 +17,25 @@
         assert isinstance(longval, long)
         w_self.longval = longval
 
+    def unwrap(w_self):
+        return w_self.longval
+
 registerimplementation(W_LongObject)
 
 
+# bool-to-long
+def delegate_Bool2Long(w_bool):
+    return W_LongObject(w_bool.space, long(w_bool.boolval))
+
+# int-to-long delegation
+def delegate_Int2Long(w_intobj):
+    return W_LongObject(w_intobj.space, long(w_intobj.intval))
+
+# long-to-float delegation
+def delegate_Long2Float(w_longobj):
+    return W_FloatObject(w_longobj.space, float(w_longobj.longval))
+
+
 # long__Long is supposed to do nothing, unless it has
 # a derived long object, where it should return
 # an exact one.
@@ -56,9 +72,6 @@
         raise OperationError(space.w_OverflowError,
                              space.wrap("long int too large to convert to int"))        
 
-def unwrap__Long(space, w_long):
-    return w_long.longval
-
 def repr__Long(space, w_long):
     return space.wrap(repr(w_long.longval))
 
@@ -223,35 +236,47 @@
 
 register_all(vars())
 
-# delegations must be registered manually because we have more than one
-# long-to-something delegation
+# register implementations of ops that recover int op overflows
 
-# int-to-long delegation
-def delegate_from_int(space, w_intobj):
-    return W_LongObject(space, long(w_intobj.intval))
-delegate_from_int.result_class = W_LongObject
-delegate_from_int.priority = PRIORITY_CHANGE_TYPE
-
-StdObjSpace.delegate.register(delegate_from_int, W_IntObject)
-
-# long-to-int delegation
-def delegate_to_int(space, w_longobj):
-    if -sys.maxint-1 <= w_longobj.longval <= sys.maxint:
-        return W_IntObject(space, int(w_longobj.longval))
-    else:
-        # note the 'return' here -- hack
-        return FailedToImplement(space.w_OverflowError,
-                   space.wrap("long int too large to convert to int"))
-delegate_to_int.result_class = W_IntObject
-delegate_to_int.priority = PRIORITY_CHANGE_TYPE
-delegate_to_int.can_fail = True
-
-StdObjSpace.delegate.register(delegate_to_int, W_LongObject)
-
-# long-to-float delegation
-def delegate_to_float(space, w_longobj):
-    return W_FloatObject(space, float(w_longobj.longval))
-delegate_to_float.result_class = W_FloatObject
-delegate_to_float.priority = PRIORITY_CHANGE_TYPE
+# binary ops
+for opname in ['add', 'sub', 'mul', 'div', 'floordiv', 'truediv', 'mod', 'divmod']:
+    exec """
+def %(opname)s_ovr__Int_Int(space, w_int1, w_int2):
+    w_long1 = delegate_Int2Long(w_int1)
+    w_long2 = delegate_Int2Long(w_int2)
+    return %(opname)s__Long_Long(space, w_long1, w_long2)
+""" % {'opname': opname}
+
+    getattr(StdObjSpace.MM, opname).register(globals()['%s_ovr__Int_Int' %opname], W_IntObject, W_IntObject, order=1)
+
+# unary ops
+for opname in ['neg', 'abs']:
+    exec """
+def %(opname)s_ovr__Int(space, w_int1):
+    w_long1 = delegate_Int2Long(w_int1)
+    return %(opname)s__Long(space, w_long1)
+""" % {'opname': opname}
+
+    getattr(StdObjSpace.MM, opname).register(globals()['%s_ovr__Int' %opname], W_IntObject, order=1)
+
+# lshift
+def lshift_ovr__Int_Int(space, w_int1, w_cnt):
+    w_long1 = delegate_Int2Long(w_int1)
+    return lshift__Long_Int(space, w_long1, w_cnt)
+
+StdObjSpace.MM.lshift.register(lshift_ovr__Int_Int, W_IntObject, W_IntObject, order=1)
+
+# pow
+def pow_ovr__Int_Int_None(space, w_int1, w_int2, w_none3):
+    w_long1 = delegate_Int2Long(w_int1)
+    w_long2 = delegate_Int2Long(w_int2)
+    return pow__Long_Long_None(space, w_long1, w_long2, w_none3)
+
+def pow_ovr__Int_Int_Int(space, w_int1, w_int2, w_int3):
+    w_long1 = delegate_Int2Long(w_int1)
+    w_long2 = delegate_Int2Long(w_int2)
+    w_long3 = delegate_Int2Long(w_int3)
+    return pow__Long_Long_Long(space, w_long1, w_long2, w_long3)
 
-StdObjSpace.delegate.register(delegate_to_float, W_LongObject)
+StdObjSpace.MM.pow.register(pow_ovr__Int_Int_None, W_IntObject, W_IntObject, W_NoneObject, order=1)
+StdObjSpace.MM.pow.register(pow_ovr__Int_Int_Int , W_IntObject, W_IntObject, W_IntObject,  order=1)

Modified: pypy/dist/pypy/objspace/std/longtype.py
==============================================================================
--- pypy/dist/pypy/objspace/std/longtype.py	(original)
+++ pypy/dist/pypy/objspace/std/longtype.py	Mon Feb  7 20:26:07 2005
@@ -2,14 +2,13 @@
 from pypy.objspace.std.strutil import string_to_long
 from pypy.interpreter.error import OperationError
 from pypy.objspace.std.inttype import int_typedef
+from pypy.interpreter.gateway import NoneNotWrapped
 
-def descr__new__(space, w_longtype, w_value=None, w_base=None):
+def descr__new__(space, w_longtype, w_value=0, w_base=NoneNotWrapped):
     from pypy.objspace.std.longobject import W_LongObject
     if w_base is None:
         # check for easy cases
-        if w_value is None:
-            value = 0L
-        elif isinstance(w_value, W_LongObject):
+        if isinstance(w_value, W_LongObject):
             value = w_value.longval
         elif space.is_true(space.isinstance(w_value, space.w_str)):
             try:

Modified: pypy/dist/pypy/objspace/std/multimethod.py
==============================================================================
--- pypy/dist/pypy/objspace/std/multimethod.py	(original)
+++ pypy/dist/pypy/objspace/std/multimethod.py	Mon Feb  7 20:26:07 2005
@@ -1,507 +1,260 @@
-from pypy.interpreter.baseobjspace import OperationError
-from pypy.tool.cache import Cache 
 
-class FailedToImplement(Exception):
-    "Signals the dispatcher to try harder."
-
-class W_ANY:
-    "Catch-all in case multimethods don't find anything else."
-    typedef = None
-
-
-# This file defines three major classes:
-#
-#   MultiMethod is the class you instantiate explicitly.
-#   It is essentially just a collection of registered functions.
-#   If xxx is a MultiMethod, StdObjSpace.xxx is xxx again,
-#   and space.xxx is a BoundMultiMethod.
-#
-#   UnboundMultiMethod is a MultiMethod on which one argument
-#   (typically the first one) has been restricted to be of some
-#   statically known type. It is obtained by the syntax
-#   W_XxxType.yyy, where W_XxxType is the static type class,
-#   or explicitly by calling 'xxx.slice(typeclass, arg_position)'.
-#   Its dispatch table is always a subset of the original MultiMethod's
-#   dispatch table.
-#
-#   The registration of a new function to a MultiMethod will be propagated
-#   to all of its matching UnboundMultiMethod instances.  The registration of
-#   a function directly to an UnboundMultiMethod will register the function
-#   to its base MultiMethod and invoke the same behavior.
-#
-#   BoundMultiMethod is a MultiMethod or UnboundMultiMethod which
-#   has been bound to a specific object space. It is obtained by
-#   'space.xxx' or explicitly by calling 'xxx.get(space)'.
-
-class AbstractMultiMethod(object):
-    """Abstract base class for MultiMethod and UnboundMultiMethod
-    i.e. the classes that are not bound to a specific space instance."""
 
-    def __init__(self, operatorsymbol, arity):
-        "NOT_RPYTHON: cannot create new multimethods dynamically"
-        self.arity = arity
-        self.operatorsymbol = operatorsymbol
-        self.dispatch_table = {}
-        self.cache_table = Cache()
-        self.compilation_cache_table = {}
-        self.cache_delegator_key = None
-        self.dispatch_arity = 0
-
-    def __repr__(self):
-        return '<%s %s>' % (self.__class__.__name__, self.operatorsymbol)
-
-    def register(self, function, *types):
-        """NOT_RPYTHON: cannot register new multimethod
-                        implementations dynamically"""
-        assert len(types) == self.arity
-        functions = self.dispatch_table.setdefault(types, [])
-        if function in functions:
-            return False
-        functions.append(function)
-        self.cache_table.clear()
-        self.compilation_cache_table.clear()
-        self.adjust_dispatch_arity(types)
-        return True
-
-    def adjust_dispatch_arity(self, types):
-        "NOT_RPYTHON"
-        width = len(types)
-        while width > self.dispatch_arity and types[width-1] is W_ANY:
-            width -= 1
-        self.dispatch_arity = width
-
-    def compile_calllist(self, argclasses, delegate):
-        """Compile a list of calls to try for the given classes of the
-        arguments. Return a function that should be called with the
-        actual arguments."""
-        if delegate.key is not self.cache_delegator_key:
-            self.cache_table.clear()
-            self.compilation_cache_table.clear()
-            self.cache_delegator_key = delegate.key
-        return self.cache_table.getorbuild(argclasses,
-                                           self.do_compile_calllist,
-                                           delegate)
-
-    def do_compile_calllist(self, argclasses, delegate):
-        "NOT_RPYTHON"
-        calllist = []
-        self.internal_buildcalllist(argclasses, delegate, calllist)
-        calllist = tuple(calllist)
-        try:
-            result = self.compilation_cache_table[calllist]
-        except KeyError:
-            result = self.internal_compilecalllist(calllist)
-            self.compilation_cache_table[calllist] = result
-        return result
-
-    def internal_compilecalllist(self, calllist):
-        "NOT_RPYTHON"
-        source, glob = self.internal_sourcecalllist(calllist)
-        # compile the function
-        exec source in glob
-        return glob['do']
-
-    def internal_sourcecalllist(self, calllist):
-        """NOT_RPYTHON
-        Translate a call list into the source of a Python function
-        which is optimized and doesn't do repeated conversions on the
-        same arguments."""
-        if len(calllist) == 1:
-            fn, conversions = calllist[0]
-            if conversions == ((),) * len(conversions):
-                # no conversion, just calling a single function: return
-                # that function directly
-                return '', {'do': fn}
-        
-        #print '**** compile **** ', self.operatorsymbol, [
-        #    t.__name__ for t in argclasses]
-        arglist = ['a%d'%i for i in range(self.dispatch_arity)] + ['*extraargs']
-        source = ['def do(space,%s):' % ','.join(arglist)]
-        converted = [{(): ('a%d'%i, False)} for i in range(self.dispatch_arity)]
-
-        def make_conversion(argi, convtuple):
-            if convtuple in converted[argi]:
-                return converted[argi][convtuple]
-            else:
-                prev, can_fail = make_conversion(argi, convtuple[:-1])
-                new = '%s_%d' % (prev, len(converted[argi]))
-                fname = all_functions.setdefault(convtuple[-1],
-                                                 'd%d' % len(all_functions))
-                if can_fail:
-                    source.append(' if isinstance(%s, FailedToImplement):' % prev)
-                    source.append('  %s = %s' % (new, prev))
-                    source.append(' else:')
-                    indent = '  '
-                else:
-                    indent = ' '
-                source.append('%s%s = %s(space,%s)' % (indent, new, fname, prev))
-                can_fail = can_fail or getattr(convtuple[-1], 'can_fail', False)
-                converted[argi][convtuple] = new, can_fail
-                return new, can_fail
-
-        all_functions = {}
-        has_firstfailure = False
-        for fn, conversions in calllist:
-            # make the required conversions
-            fname = all_functions.setdefault(fn, 'f%d' % len(all_functions))
-            arglist = []
-            failcheck = []
-            for i in range(self.dispatch_arity):
-                argname, can_fail = make_conversion(i, conversions[i])
-                arglist.append(argname)
-                if can_fail:
-                    failcheck.append(argname)
-            arglist.append('*extraargs')
-            source.append(    ' try:')
-            for argname in failcheck:
-                source.append('  if isinstance(%s, FailedToImplement):' % argname)
-                source.append('   raise %s' % argname)
-            source.append(    '  return %s(space,%s)' % (
-                fname, ','.join(arglist)))
-            if has_firstfailure:
-                source.append(' except FailedToImplement:')
-            else:
-                source.append(' except FailedToImplement, firstfailure:')
-                has_firstfailure = True
-            source.append(    '  pass')
-
-        # complete exhaustion
-        if has_firstfailure:
-            source.append(' raise firstfailure')
-        else:
-            source.append(' raise FailedToImplement()')
-        source.append('')
-
-        glob = {'FailedToImplement': FailedToImplement}
-        for fn, fname in all_functions.items():
-            glob[fname] = fn
-        return '\n'.join(source), glob
-
-    def internal_buildcalllist(self, argclasses, delegate, calllist):
-        """NOT_RPYTHON
-        Build a list of calls to try for the given classes of the
-        arguments. The list contains 'calls' of the following form:
-        (function-to-call, list-of-list-of-converters)
-        The list of converters contains a list of converter functions per
-        argument, with [] meaning that no conversion is needed for
-        that argument."""
-        # look for an exact match first
-        arity = self.dispatch_arity
-        assert arity == len(argclasses)
-        dispatchclasses = tuple([(c,) for c in argclasses])
-        choicelist = self.buildchoices(dispatchclasses)
-        seen_functions = {}
-        no_conversion = [()] * arity
-        for signature, function in choicelist:
-            calllist.append((function, tuple(no_conversion)))
-            seen_functions[function] = 1
-
-        # proceed by expanding the last argument by delegation, step by step
-        # until no longer possible, and then the previous argument, and so on.
-        expanded_args = ()
-        expanded_dispcls = ()
-
-        for argi in range(arity-1, -1, -1):
-            # growing tuple of dispatch classes we can delegate to
-            curdispcls = dispatchclasses[argi]
-            assert len(curdispcls) == 1
-            # maps each dispatch class to a list of converters
-            curargs = {curdispcls[0]: []}
-            # reduce dispatchclasses to the arguments before this one
-            # (on which no delegation has been tried yet)
-            dispatchclasses = dispatchclasses[:argi]
-            no_conversion = no_conversion[:argi]
-            
-            while 1:
-                choicelist = delegate.buildchoices((curdispcls,))
-                # the list is sorted by priority
-                progress = False
-                for (t,), function in choicelist:
-                    if function is None:
-                        # this marks a decrease in the priority.
-                        # Don't try delegators with lower priority if
-                        # we have already progressed.
-                        if progress:
-                            break
-                    else:
-                        assert hasattr(function, 'result_class'), (
-                            "delegator %r must have a result_class" % function)
-                        nt = function.result_class
-                        if nt not in curargs:
-                            curdispcls += (nt,)
-                            srcconvs = curargs[t]
-                            if not getattr(function, 'trivial_delegation',False):
-                                srcconvs = srcconvs + [function]
-                            curargs[nt] = srcconvs
-                            progress = True
-                else:
-                    if not progress:
-                        break  # no progress, and delegators list exhausted
-
-                # progress: try again to dispatch with this new set of types
-                choicelist = self.buildchoices(
-                    dispatchclasses + (curdispcls,) + expanded_dispcls)
-                for signature, function in choicelist:
-                    if function not in seen_functions:
-                        seen_functions[function] = 1
-                        # collect arguments: arguments after position argi...
-                        after_argi = [tuple(expanded_args[j][signature[j]])
-                                      for j in range(argi+1-arity, 0)]  # nb. j<0
-                        # collect arguments: argument argi...
-                        arg_argi = tuple(curargs[signature[argi]])
-                        # collect all arguments
-                        newargs = no_conversion + [arg_argi] + after_argi
-                        # record the call
-                        calllist.append((function, tuple(newargs)))
-                # end of while 1: try on delegating the same argument i
-
-            # proceed to the next argument
-            expanded_args = (curargs,) + expanded_args
-            expanded_dispcls = (curdispcls,) + expanded_dispcls
-
-    def buildchoices(self, allowedtypes):
-        """NOT_RPYTHON
-        Build a list of all possible implementations we can dispatch to,
-        sorted best-first, ignoring delegation."""
-        # 'types' is a tuple of tuples of classes, one tuple of classes per
-        # argument. (After delegation, we need to call buildchoice() with
-        # more than one possible class for a single argument.)
-        result = []
-        self.internal_buildchoices(allowedtypes, (), result)
-        self.postprocessresult(allowedtypes, result)
-        #print self.operatorsymbol, allowedtypes, result
-        # the result is a list a tuples (function, signature).
-        return result
-
-    def postprocessresult(self, allowedtypes, result):
-        "NOT_RPYTHON"
+class FailedToImplement(Exception):
+    pass
 
-    def internal_buildchoices(self, initialtypes, currenttypes, result):
-        "NOT_RPYTHON"
-        if len(currenttypes) == self.dispatch_arity:
-            currenttypes += (W_ANY,) * (self.arity - self.dispatch_arity)
-            for func in self.dispatch_table.get(currenttypes, []):
-                if func not in result:   # ignore duplicates
-                    result.append((currenttypes, func))
-        else:
-            classtuple = initialtypes[len(currenttypes)]
-            for nexttype in classtuple:
-                self.internal_buildchoices(initialtypes,
-                                           currenttypes + (nexttype,),
-                                           result)
 
-    def is_empty(self):
-        return not self.dispatch_table
+def raiseFailedToImplement():
+    raise FailedToImplement
 
 
-class MultiMethod(AbstractMultiMethod):
+class MultiMethodTable:
 
-    def __init__(self, operatorsymbol, arity, specialnames=None, **extras):
+    def __init__(self, arity, root_class, argnames_before=[], argnames_after=[]):
         """NOT_RPYTHON: cannot create new multimethods dynamically.
-        MultiMethod dispatching on the first 'arity' arguments.
+        MultiMethod-maker dispatching on exactly 'arity' arguments.
         """
-        AbstractMultiMethod.__init__(self, operatorsymbol, arity)
         if arity < 1:
             raise ValueError, "multimethods cannot dispatch on nothing"
-        if specialnames is None:
-            specialnames = [operatorsymbol]
-        self.specialnames = specialnames  # e.g. ['__xxx__', '__rxxx__']
-        self.extras = extras
-        self.unbound_versions = {}
-
+        self.arity = arity
+        self.root_class = root_class
+        self.dispatch_tree = {}
+        self.argnames_before = argnames_before
+        self.argnames_after = argnames_after
 
-    def __get__(self, space, cls=None):
-        if space is None:
-            return self
+    def register(self, function, *types, **kwds):
+        try:
+            order = kwds.pop('order')
+        except KeyError:
+            order = 0
+        assert not kwds
+        assert len(types) == self.arity
+        node = self.dispatch_tree
+        for type in types[:-1]:
+            node = node.setdefault(type, {})
+        lst = node.setdefault(types[-1], [])
+        if order >= len(lst):
+            lst += [None] * (order+1 - len(lst))
+        assert lst[order] is None, "duplicate function for %r@%d" % (
+            types, order)
+        lst[order] = function
+
+    def install(self, prefix, list_of_typeorders, baked_perform_call=True):
+        "NOT_RPYTHON: initialization-time only"
+        assert len(list_of_typeorders) == self.arity
+        installer = Installer(self, prefix, list_of_typeorders,
+                              baked_perform_call=baked_perform_call)
+        return installer.install()
+
+    def install_if_not_empty(self, prefix, list_of_typeorders):
+        "NOT_RPYTHON: initialization-time only"
+        assert len(list_of_typeorders) == self.arity
+        installer = Installer(self, prefix, list_of_typeorders)
+        if installer.is_empty():
+            return None
         else:
-            return BoundMultiMethod(space, self)
+            return installer.install()        
+        
+    
+
+    # ____________________________________________________________
+    # limited dict-like interface to the dispatch table
 
-    get = __get__
+    def getfunctions(self, types):
+        assert len(types) == self.arity
+        node = self.dispatch_tree
+        for type in types:
+            node = node[type]
+        return [fn for fn in node if fn is not None]
 
-    def slice(self, typeclass, bound_position=0):
-        "NOT_RPYTHON"
+    def has_signature(self, types):
         try:
-            return self.unbound_versions[typeclass, bound_position]
+            self.getfunctions(types)
         except KeyError:
-            m = UnboundMultiMethod(self, typeclass, bound_position)
-            self.unbound_versions[typeclass, bound_position] = m
-            return m
-
-    def register(self, function, *types):
-        """NOT_RPYTHON: cannot register new multimethod
-                        implementations dynamically"""
-        if not AbstractMultiMethod.register(self, function, *types):
             return False
-        # register the function into unbound versions that match
-        for m in self.unbound_versions.values():
-            if m.match(types):
-                AbstractMultiMethod.register(m, function, *types)
-        return True
-
-
-class DelegateMultiMethod(MultiMethod):
-
-    def __init__(self):
-        "NOT_RPYTHON: cannot create new multimethods dynamically."
-        MultiMethod.__init__(self, 'delegate', 1, [])
-        self.key = object()
-
-    def register(self, function, *types):
-        """NOT_RPYTHON: cannot register new multimethod
-                        implementations dynamically"""
-        if not AbstractMultiMethod.register(self, function, *types):
-            return False
-        self.key = object()   # change the key to force recomputation
-        return True
-
-    def postprocessresult(self, allowedtypes, result):
-        "NOT_RPYTHON"
-        # add delegation from a class to the *first* immediate parent class
-        # and to W_ANY
-        arg1types, = allowedtypes
-        for t in arg1types:
-            if t.__bases__:
-                base = t.__bases__[0]
-                def delegate_to_parent_class(space, a):
-                    return a
-                delegate_to_parent_class.trivial_delegation = True
-                delegate_to_parent_class.result_class = base
-                delegate_to_parent_class.priority = 0
-                # hard-wire it at priority 0
-                result.append(((t,), delegate_to_parent_class))
-
-                def delegate_to_any(space, a):
-                    return a
-                delegate_to_any.trivial_delegation = True
-                delegate_to_any.result_class = W_ANY
-                delegate_to_any.priority = -999
-                # hard-wire it at priority -999
-                result.append(((t,), delegate_to_any))
-
-        # sort the results in priority order, and insert None marks
-        # between jumps in the priority values. Higher priority values
-        # first.
-        by_priority = {} # classify delegators by priority
-        for signature, function in result:
-            assert hasattr(function, 'priority'), (
-                "delegator %r must have a priority" % function)
-            sublist = by_priority.setdefault(function.priority, [])
-            sublist.append((signature, function))
-        delegators = by_priority.items()
-        delegators.sort()
-        delegators.reverse()
-        del result[:]
-        for priority, sublist in delegators:
-            if result:
-                result.append(((None,), None))
-            result += sublist
-
-
-class UnboundMultiMethod(AbstractMultiMethod):
-
-    def __init__(self, basemultimethod, typeclass, bound_position=0):
-        "NOT_RPYTHON: cannot create new multimethods dynamically."
-        AbstractMultiMethod.__init__(self,
-                                     basemultimethod.operatorsymbol,
-                                     basemultimethod.arity)
-        self.basemultimethod = basemultimethod
-        self.typeclass = typeclass
-        self.bound_position = bound_position
-        # get all the already-registered matching functions from parent
-        for types, functions in basemultimethod.dispatch_table.iteritems():
-            if self.match(types):
-                self.dispatch_table[types] = functions
-                self.adjust_dispatch_arity(types)
-        #print basemultimethod.operatorsymbol, typeclass, self.dispatch_table
-
-    def register(self, function, *types):
-        """NOT_RPYTHON: cannot register new multimethod
-                        implementations dynamically"""
-        if not AbstractMultiMethod.register(self, function, *types):
-            return False
-        # propagate the function registeration to the base multimethod
-        # and possibly other UnboundMultiMethods
-        self.basemultimethod.register(function, *types)
-        return True
-
-    def match(self, types):
-        "NOT_RPYTHON"
-        # check if the 'types' signature statically corresponds to the
-        # restriction of the present UnboundMultiMethod.
-        # Only accept an exact match; having merely subclass should
-        # be taken care of by the general look-up rules.
-        t = types[self.bound_position].typedef
-        return t is self.typeclass or (
-            getattr(t, 'could_also_match', None) is self.typeclass)
-
-    def __get__(self, space, cls=None):
-        if space is None:
-            return self
         else:
-            return BoundMultiMethod(space, self)
+            return True
+
+    def signatures(self):
+        result = []
+        def enum_keys(types_so_far, node):
+            for type, subnode in node.items():
+                next_types = types_so_far+(type,)
+                if isinstance(subnode, dict):
+                    enum_keys(next_types, subnode)
+                else:
+                    assert len(next_types) == self.arity
+                    result.append(next_types)
+        enum_keys((), self.dispatch_tree)
+        return result
+
 
-    get = __get__
+# ____________________________________________________________
 
+class Installer:
 
-class BoundMultiMethod:
-    ASSERT_BASE_TYPE = object
+    prefix_memo = {}
 
-    def __init__(self, space, multimethod):
-        self.space = space
+    def __init__(self, multimethod, prefix, list_of_typeorders, baked_perform_call=True):
         self.multimethod = multimethod
+        # avoid prefix clashes, user code should supply different prefixes
+        # itself for nice names in tracebacks
+        n = 1
+        while prefix in self.prefix_memo:
+            n += 1
+            prefix = "%s%d" % (prefix,n)
+        self.prefix = prefix
+        self.prefix_memo[prefix] = 1
+        self.list_of_typeorders = list_of_typeorders
+        self.subtree_cache = {}
+        self.to_install = []
+        self.non_empty = self.build_tree([], multimethod.dispatch_tree)
 
-    def __eq__(self, other):
-        return (self.__class__ == other.__class__ and
-                self.space == other.space and
-                self.multimethod == other.multimethod)
-
-    def __ne__(self, other):
-        return self != other
-
-    def __hash__(self):
-        return hash((self.__class__, self.space, self.multimethod))
-
-    def __call__(self, *args):
-        if len(args) < self.multimethod.arity:
-            raise TypeError, ("multimethod needs at least %d arguments" %
-                              self.multimethod.arity)
-        try:
-            return self.perform_call(*args)
-        except FailedToImplement, e:
-            if e.args:
-                raise OperationError(e.args[0], e.args[1])
-            else:
-                # raise a TypeError for a FailedToImplement
-                initialtypes = [a.__class__
-                                for a in args[:self.multimethod.dispatch_arity]]
-                if len(initialtypes) <= 1:
-                    plural = ""
-                else:
-                    plural = "s"
-                debugtypenames = [t.__name__ for t in initialtypes]
-                message = "unsupported operand type%s for %s (%s)" % (
-                    plural, self.multimethod.operatorsymbol,
-                    ', '.join(debugtypenames))
-                w_value = self.space.wrap(message)
-                raise OperationError(self.space.w_TypeError, w_value)
-
-    def perform_call(self, *args):
-        for a in args:
-            assert isinstance(a, self.ASSERT_BASE_TYPE), (
-                "'%s' multimethod got a non-wrapped argument: %r" % (
-                self.multimethod.operatorsymbol, a))
-        arity = self.multimethod.dispatch_arity
-        argclasses = tuple([a.__class__ for a in args[:arity]])
-        delegate = self.space.delegate.multimethod
-        fn = self.multimethod.compile_calllist(argclasses, delegate)
-        return fn(self.space, *args)
+        self.baked_perform_call = baked_perform_call
+        
+        if self.non_empty:
+            perform = [(None, prefix, 0)]
+        else:
+            perform = []
+
+        self.perform_call = self.build_function(None, prefix+'_perform_call',
+                                                None, perform)
 
     def is_empty(self):
-        return self.multimethod.is_empty()
+        return not self.non_empty
 
-    def __repr__(self):
-        return '<Bound %r>'%(self.multimethod,)
+    def install(self):
+        #f = open('LOGFILE', 'a')
+        #print >> f, '_'*60
+        #import pprint
+        #pprint.pprint(self.list_of_typeorders, f)
+        for target, funcname, func, source, fallback in self.to_install:
+            if target is not None:
+                if hasattr(target, funcname) and fallback:
+                    continue
+                #print >> f, target.__name__, funcname
+                #if source:
+                #    print >> f, source
+                #else:
+                #    print >> f, '*\n'
+                setattr(target, funcname, func)
+        #f.close()
+        return self.perform_call
+
+    def build_tree(self, types_so_far, dispatch_node):
+        key = tuple(types_so_far)
+        if key in self.subtree_cache:
+            return self.subtree_cache[key]
+        non_empty = False
+        typeorder = self.list_of_typeorders[len(types_so_far)]
+        for next_type in typeorder:
+            if self.build_single_method(typeorder, types_so_far, next_type,
+                                        dispatch_node):
+                non_empty = True
+        self.subtree_cache[key] = non_empty
+        return non_empty
+
+    def build_single_method(self, typeorder, types_so_far, next_type,
+                            dispatch_node):
+        funcname = '__'.join([self.prefix] + [t.__name__ for t in types_so_far])
+
+        order = typeorder[next_type]
+        #order = [(next_type, None)] + order
+
+        things_to_call = []
+        for type, conversion in order:
+            if type not in dispatch_node:
+                # there is no possible completion of types_so_far+[type]
+                # that could lead to a registered function.
+                continue
+            match = dispatch_node[type]
+            if isinstance(match, dict):
+                if self.build_tree(types_so_far+[type], match):
+                    call = funcname + '__' + type.__name__
+                    call_selfarg_index = len(types_so_far) + 1
+                    things_to_call.append((conversion, call,
+                                           call_selfarg_index))
+            else:
+                for func in match:   # list of functions
+                    if func is not None:
+                        things_to_call.append((conversion, func, None))
+
+        if things_to_call:
+            funcname = intern(funcname)
+            self.build_function(next_type, funcname, len(types_so_far),
+                                things_to_call)
+            return True
+        else:
+            return False
 
+    def build_function(self, target, funcname, func_selfarg_index,
+                       things_to_call):
+        # support for inventing names for the entries in things_to_call
+        # which are real function objects instead of strings
+        miniglobals = {'FailedToImplement': FailedToImplement}
+        def invent_name(obj):
+            if isinstance(obj, str):
+                return obj
+            name = obj.__name__
+            n = 1
+            while name in miniglobals:
+                n += 1
+                name = '%s%d' % (obj.__name__, n)
+            miniglobals[name] = obj
+            return name
+
+        funcargs = ['arg%d' % i for i in range(self.multimethod.arity)]
+
+        bodylines = []
+        for conversion, call, call_selfarg_index in things_to_call:
+            callargs = funcargs[:]
+            if conversion is not None:
+                to_convert = func_selfarg_index
+                callargs[to_convert] = '%s(%s)' % (
+                    invent_name(conversion), callargs[to_convert])
+            callname = invent_name(call)
+            if call_selfarg_index is not None:
+                # fallback on root_class
+                self.build_function(self.multimethod.root_class,
+                                    callname, call_selfarg_index, [])
+                callname = '%s.%s' % (callargs.pop(call_selfarg_index), callname)
+            callargs = (self.multimethod.argnames_before +
+                        callargs + self.multimethod.argnames_after)
+            bodylines.append('return %s(%s)' % (callname, ', '.join(callargs)))
+
+        fallback = False
+        if not bodylines:
+            miniglobals['raiseFailedToImplement'] = raiseFailedToImplement
+            bodylines = ['return raiseFailedToImplement()']
+            fallback = True
+
+
+        # protect all lines apart from the last one by a try:except:
+        for i in range(len(bodylines)-2, -1, -1):
+            bodylines[i:i+1] = ['try:',
+                                '    ' + bodylines[i],
+                                'except FailedToImplement:',
+                                '    pass']
 
-class error(Exception):
-    "Thrown to you when you do something wrong with multimethods."
+        if func_selfarg_index is not None:
+            selfargs = [funcargs.pop(func_selfarg_index)]
+        else:
+            selfargs = []
+        funcargs = (selfargs + self.multimethod.argnames_before +
+                    funcargs + self.multimethod.argnames_after)
+
+        if target is None and not self.baked_perform_call:
+            return funcargs, bodylines[0][len('return '):], miniglobals, fallback
+
+        # indent mode
+        bodylines = ['    ' + line for line in bodylines]
+
+        bodylines.insert(0, 'def %s(%s):' % (funcname, ', '.join(funcargs)))
+        bodylines.append('')
+        source = '\n'.join(bodylines)
+        #print source
+        #print "*"*60
+        exec source in miniglobals
+        func = miniglobals[funcname]
+        self.to_install.append((target, funcname, func, source, fallback))
+        return func

Modified: pypy/dist/pypy/objspace/std/noneobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/noneobject.py	(original)
+++ pypy/dist/pypy/objspace/std/noneobject.py	Mon Feb  7 20:26:07 2005
@@ -8,10 +8,11 @@
 
 class W_NoneObject(W_Object):
     from pypy.objspace.std.nonetype import none_typedef as typedef
-registerimplementation(W_NoneObject)
 
-def unwrap__None(space, w_none):
-    return None
+    def unwrap(w_self):
+        return None
+
+registerimplementation(W_NoneObject)
 
 def nonzero__None(space, w_none):
     return space.w_False

Modified: pypy/dist/pypy/objspace/std/objspace.py
==============================================================================
--- pypy/dist/pypy/objspace/std/objspace.py	(original)
+++ pypy/dist/pypy/objspace/std/objspace.py	Mon Feb  7 20:26:07 2005
@@ -1,36 +1,15 @@
 from pypy.objspace.std.register_all import register_all
-from pypy.interpreter.baseobjspace import *
+from pypy.interpreter.baseobjspace import ObjSpace, BaseWrappable
+from pypy.interpreter.error import OperationError
 from pypy.interpreter.typedef import get_unique_interplevel_subclass
 from pypy.interpreter.typedef import instantiate
 from pypy.tool.cache import Cache 
-from pypy.objspace.std.multimethod import *
+from pypy.objspace.std.model import W_Object, W_ANY, MultiMethod, StdTypeModel
+from pypy.objspace.std.multimethod import FailedToImplement
 from pypy.objspace.descroperation import DescrOperation
 from pypy.objspace.std import stdtypedef
 import types
 
-class W_Object(W_Root, object):
-    "Parent base class for wrapped objects."
-    typedef = None
-
-    def __init__(w_self, space):
-        w_self.space = space     # XXX not sure this is ever used any more
-
-    def __repr__(self):
-        s = '%s(%s)' % (
-            self.__class__.__name__,
-           #', '.join(['%s=%r' % keyvalue for keyvalue in self.__dict__.items()])
-            getattr(self, 'name', '')
-            )
-        if hasattr(self, 'w__class__'):
-            s += ' instance of %s' % self.w__class__
-        return '<%s>' % s
-
-# delegation priorities
-PRIORITY_SAME_TYPE    = 2  # converting between several impls of the same type
-PRIORITY_PARENT_TYPE  = 1  # converting to a base type (e.g. bool -> int)
-PRIORITY_PARENT_IMPL  = 0  # hard-wired in multimethod.py (W_IntObject->W_Object)
-PRIORITY_CHANGE_TYPE  = -1 # changing type altogether (e.g. int -> float)
-PRIORITY_ANY          = -999 # hard-wired in multimethod.py (... -> W_ANY)
 
 def registerimplementation(implcls):
     # this function should ultimately register the implementation class somewhere
@@ -47,139 +26,31 @@
 
     PACKAGE_PATH = 'objspace.std'
 
-    def standard_types(self):
-        "NOT_RPYTHON: only for initializing the space."
-        class result:
-            "Import here the types you want to have appear in __builtin__."
-
-            from pypy.objspace.std.objecttype import object_typedef
-            from pypy.objspace.std.booltype   import bool_typedef
-            from pypy.objspace.std.inttype    import int_typedef
-            from pypy.objspace.std.floattype  import float_typedef
-            from pypy.objspace.std.tupletype  import tuple_typedef
-            from pypy.objspace.std.listtype   import list_typedef
-            from pypy.objspace.std.dicttype   import dict_typedef
-            from pypy.objspace.std.basestringtype import basestring_typedef
-            from pypy.objspace.std.stringtype import str_typedef
-            from pypy.objspace.std.typetype   import type_typedef
-            from pypy.objspace.std.slicetype  import slice_typedef
-            from pypy.objspace.std.longtype   import long_typedef
-            from pypy.objspace.std.unicodetype import unicode_typedef
-        return [value for key, value in result.__dict__.items()
-                      if not key.startswith('_')]   # don't look
-
-    def clone_exception_hierarchy(self):
-        "NOT_RPYTHON: only for initializing the space."
-        from pypy.objspace.std.typeobject import W_TypeObject
-        from pypy.interpreter import gateway
-        w = self.wrap
-        def app___init__(self, *args):
-            self.args = args
-        w_init = w(gateway.app2interp(app___init__))
-        def app___str__(self):
-            l = len(self.args)
-            if l == 0:
-                return ''
-            elif l == 1:
-                return str(self.args[0])
-            else:
-                return str(self.args)
-        w_str = w(gateway.app2interp(app___str__))
-        import exceptions
-
-        # to create types, we should call the standard type object;
-        # but being able to do that depends on the existence of some
-        # of the exceptions...
-        
-        self.w_Exception = W_TypeObject(
-            self,
-            'Exception',
-            [self.w_object],
-            {'__init__': w_init,
-             '__str__': w_str},
-            )
-        done = {'Exception': self.w_Exception}
-
-        # some of the complexity of the following is due to the fact
-        # that we need to create the tree root first, but the only
-        # connections we have go in the inconvenient direction...
-        
-        for k in dir(exceptions):
-            if k not in done:
-                v = getattr(exceptions, k)
-                if not isinstance(v, type(Exception)):
-                    continue
-                if not issubclass(v, Exception):
-                    continue
-                stack = [k]
-                while stack:
-                    next = stack[-1]
-                    if next not in done:
-                        v = getattr(exceptions, next)
-                        b = v.__bases__[0]
-                        if b.__name__ not in done:
-                            stack.append(b.__name__)
-                            continue
-                        else:
-                            base = done[b.__name__]
-                            newtype = W_TypeObject(
-                                self,
-                                next,
-                                [base],
-                                {},
-                                )
-                            setattr(self,
-                                    'w_' + next,
-                                    newtype)
-                            done[next] = newtype
-                            stack.pop()
-                    else:
-                        stack.pop()
-        return done
-                            
     def initialize(self):
         "NOT_RPYTHON: only for initializing the space."
         self._typecache = Cache()
 
-        # The object implementations that we want to 'link' into PyPy must be
-        # imported here.  This registers them into the multimethod tables,
-        # *before* the type objects are built from these multimethod tables.
-        from pypy.objspace.std import objectobject
-        from pypy.objspace.std import boolobject
-        from pypy.objspace.std import intobject
-        from pypy.objspace.std import floatobject
-        from pypy.objspace.std import tupleobject
-        from pypy.objspace.std import listobject
-        from pypy.objspace.std import dictobject
-        from pypy.objspace.std import stringobject
-        from pypy.objspace.std import typeobject
-        from pypy.objspace.std import sliceobject
-        from pypy.objspace.std import longobject
-        from pypy.objspace.std import noneobject
-        from pypy.objspace.std import iterobject
-        from pypy.objspace.std import unicodeobject
-        from pypy.objspace.std import fake
+        # Import all the object types and implementations
+        self.model = StdTypeModel()
+
+        # install all the MultiMethods into the space instance
+        for name, mm in self.MM.__dict__.items():
+            if isinstance(mm, MultiMethod) and not hasattr(self, name):
+                exprargs, expr, miniglobals, fallback = (
+                    mm.install_not_sliced(self.model.typeorder, baked_perform_call=False))
+
+                func = stdtypedef.make_perform_trampoline('__mm_'+name,
+                                                          exprargs, expr, miniglobals,
+                                                          mm)
+                
+                                                  # e.g. add(space, w_x, w_y)
+                boundmethod = func.__get__(self)  # bind the 'space' argument
+                setattr(self, name, boundmethod)  # store into 'space' instance
+
         # hack to avoid imports in the time-critical functions below
-        global W_ObjectObject, W_BoolObject, W_IntObject, W_FloatObject
-        global W_TupleObject, W_ListObject, W_DictObject, W_StringObject
-        global W_TypeObject, W_SliceObject, W_LongObject, W_NoneObject
-        global W_SeqIterObject, W_UnicodeObject, fake_type
-        W_ObjectObject = objectobject.W_ObjectObject
-        W_BoolObject = boolobject.W_BoolObject
-        W_IntObject = intobject.W_IntObject
-        W_FloatObject = floatobject.W_FloatObject
-        W_TupleObject = tupleobject.W_TupleObject
-        W_ListObject = listobject.W_ListObject
-        W_DictObject = dictobject.W_DictObject
-        W_StringObject = stringobject.W_StringObject
-        W_TypeObject = typeobject.W_TypeObject
-        W_SliceObject = sliceobject.W_SliceObject
-        W_LongObject = longobject.W_LongObject
-        W_NoneObject = noneobject.W_NoneObject
-        W_SeqIterObject = iterobject.W_SeqIterObject
-        W_UnicodeObject = unicodeobject.W_UnicodeObject
-        fake_type = fake.fake_type
-        # end of hacks
+        for cls in self.model.typeorder:
+            globals()[cls.__name__] = cls
+
         # singletons
         self.w_None  = W_NoneObject(self)
         self.w_False = W_BoolObject(self, False)
@@ -193,12 +64,11 @@
                         "None" : self.w_None,
                         "NotImplemented": self.w_NotImplemented,
                         "Ellipsis": self.w_Ellipsis,
-#                        "long": self.wrap(long),  # XXX temporary
                         }
 
         # types
         self.types_w = {}
-        for typedef in self.standard_types():
+        for typedef in self.model.pythontypes:
             w_type = self.gettypeobject(typedef)
             setattr(self, 'w_' + typedef.name, w_type)
             for_builtins[typedef.name] = w_type
@@ -206,9 +76,17 @@
         # dummy old-style classes types
         self.w_classobj = W_TypeObject(self, 'classobj', [self.w_object], {})
         self.w_instance = W_TypeObject(self, 'instance', [self.w_object], {})
-        
+
         # exceptions
-        ##for_builtins.update(self.clone_exception_hierarchy())
+        mod = self.setup_exceptions(for_builtins)
+
+        # install things in the __builtin__ module
+        self.make_builtins(for_builtins)
+
+        w_exceptions = self.wrap(mod)
+        self.sys.setbuiltinmodule(w_exceptions, 'exceptions')
+
+    def setup_exceptions(self, for_builtins):
         ## hacking things in
         from pypy.module import exceptionsinterp as ex
         def call(w_type, w_args):
@@ -237,15 +115,10 @@
             self.setitem(w_dic, self.wrap("__doc__"), ex.__doc__)
         finally:
             del self.call # revert to the class' method
-        
-        self.make_builtins(for_builtins)
         # XXX refine things, clean up, create a builtin module...
         # but for now, we do a regular one.
         from pypy.interpreter.module import Module
-        
-        m = Module(self, self.wrap("exceptions"), w_dic)
-        w_exceptions = self.wrap(m)
-        self.sys.setbuiltinmodule(w_exceptions, 'exceptions')
+        return Module(self, self.wrap("exceptions"), w_dic)
 
     def gettypeobject(self, typedef):
         # types_w maps each StdTypeDef instance to its
@@ -298,7 +171,8 @@
             if hasattr(self, 'w_' + x.__name__):
                 w_result = getattr(self, 'w_' + x.__name__)
                 assert isinstance(w_result, W_TypeObject)
-                return w_result 
+                return w_result
+        from fake import fake_type
         if isinstance(x, type):
             ft = fake_type(x)
             return self.gettypeobject(ft.typedef)
@@ -306,6 +180,11 @@
         return ft(self, x)
     wrap._specialize_ = "argtypes"
 
+    def unwrap(self, w_obj):
+        if isinstance(w_obj, BaseWrappable):
+            return w_obj
+        return w_obj.unwrap()
+
     def newint(self, intval):
         return W_IntObject(self, intval)
 
@@ -367,31 +246,6 @@
                 len(t), expected_length)
         return t
 
-
-    class MM:
-        "Container for multimethods."
-        #is_data_descr = MultiMethod('is_data_descr', 1, []) # returns an unwrapped bool
-        #getdict = MultiMethod('getdict', 1, [])  # get '.__dict__' attribute
-        next    = MultiMethod('next', 1, ['next'])     # iterator interface
-        call    = MultiMethod('call', 1, ['__call__'], varargs=True, keywords=True)
-        #getattribute = MultiMethod('getattr', 2, ['__getattribute__'])  # XXX hack
-        # special visible multimethods
-        delegate = DelegateMultiMethod()          # delegators
-        int_w   = MultiMethod('int_w', 1, [])     # returns an unwrapped int
-        str_w   = MultiMethod('str_w', 1, [])     # returns an unwrapped string
-        float_w = MultiMethod('float_w', 1, [])   # returns an unwrapped float      
-        unwrap  = MultiMethod('unwrap', 1, [])    # returns an unwrapped object
-        issubtype = MultiMethod('issubtype', 2, [])
-        id = MultiMethod('id', 1, [])
-        init = MultiMethod('__init__', 1, varargs=True, keywords=True)
-
-    int_w   = MM.int_w
-    str_w   = MM.str_w
-    float_w = MM.float_w
-    unwrap  = MM.unwrap
-    delegate = MM.delegate
-    #is_true = MM.is_true
-
     def is_(self, w_one, w_two):
         # XXX a bit of hacking to gain more speed 
         if w_one is w_two:
@@ -405,20 +259,21 @@
         else:
             return DescrOperation.is_true(self, w_obj)
 
-# add all regular multimethods to StdObjSpace
-for _name, _symbol, _arity, _specialnames in ObjSpace.MethodTable:
-    if not hasattr(StdObjSpace.MM, _name):
-        if _name == 'pow':
-            mm = MultiMethod(_symbol, _arity, _specialnames, defaults=(None,))
-        else:
-            mm = MultiMethod(_symbol, _arity, _specialnames)
-        setattr(StdObjSpace.MM, _name, mm)
-    if not hasattr(StdObjSpace, _name):
-        setattr(StdObjSpace, _name, getattr(StdObjSpace.MM, _name))
-
-# import the common base W_ObjectObject as well as
-# default implementations of some multimethods for all objects
-# that don't explicitly override them or that raise FailedToImplement
-from pypy.objspace.std.register_all import register_all
-import pypy.objspace.std.objectobject
-import pypy.objspace.std.default
+
+    class MM:
+        "Container for multimethods."
+        call    = MultiMethod('call', 1, ['__call__'], general__args__=True)
+        init    = MultiMethod('__init__', 1, general__args__=True)
+        # special visible multimethods
+        int_w   = MultiMethod('int_w', 1, [])     # returns an unwrapped int
+        str_w   = MultiMethod('str_w', 1, [])     # returns an unwrapped string
+        float_w = MultiMethod('float_w', 1, [])   # returns an unwrapped float
+
+        # add all regular multimethods here
+        for _name, _symbol, _arity, _specialnames in ObjSpace.MethodTable:
+            if _name not in locals():
+                mm = MultiMethod(_symbol, _arity, _specialnames)
+                locals()[_name] = mm
+                del mm
+
+        pow.extras['defaults'] = (None,)

Modified: pypy/dist/pypy/objspace/std/register_all.py
==============================================================================
--- pypy/dist/pypy/objspace/std/register_all.py	(original)
+++ pypy/dist/pypy/objspace/std/register_all.py	Mon Feb  7 20:26:07 2005
@@ -74,17 +74,17 @@
 
 
 def op_negated(function):
-    def op(space, w_1, w_2, function=function):
+    def op(space, w_1, w_2):
         return space.not_(function(space, w_1, w_2))
     return op
 
 def op_swapped(function):
-    def op(space, w_1, w_2, function=function):
+    def op(space, w_1, w_2):
         return function(space, w_2, w_1)
     return op
 
 def op_swapped_negated(function):
-    def op(space, w_1, w_2, function=function):
+    def op(space, w_1, w_2):
         return space.not_(function(space, w_2, w_1))
     return op
 
@@ -110,16 +110,17 @@
     table, thus favouring swapping the arguments over negating the result.
     """
     from pypy.objspace.std.objspace import StdObjSpace, W_ANY
-    originaltable = {}
+    originalentries = {}
     for op in OPERATORS:
-        originaltable[op] = getattr(StdObjSpace.MM, op).dispatch_table.copy()
+        originalentries[op] = getattr(StdObjSpace.MM, op).signatures()
 
     for op1, op2, correspondance in OP_CORRESPONDANCES:
         mirrorfunc = getattr(StdObjSpace.MM, op2)
-        for types, functions in originaltable[op1].iteritems():
+        for types in originalentries[op1]:
             t1, t2 = types
             if t1 is t2:
-                if types not in mirrorfunc.dispatch_table:
+                if not mirrorfunc.has_signature(types):
+                    functions = getattr(StdObjSpace.MM, op1).getfunctions(types)
                     assert len(functions) == 1, ('Automatic'
                             ' registration of comparison functions'
                             ' only work when there is a single method for'

Modified: pypy/dist/pypy/objspace/std/sliceobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/sliceobject.py	(original)
+++ pypy/dist/pypy/objspace/std/sliceobject.py	Mon Feb  7 20:26:07 2005
@@ -18,6 +18,10 @@
         w_self.w_stop = w_stop
         w_self.w_step = w_step
 
+    def unwrap(w_slice):
+        space = w_slice.space
+        return slice(space.unwrap(w_slice.w_start), space.unwrap(w_slice.w_stop), space.unwrap(w_slice.w_step))
+
 registerimplementation(W_SliceObject)
 
 def app_repr__Slice(aslice):
@@ -43,7 +47,4 @@
     raise OperationError(space.w_TypeError,
                          space.wrap("unhashable type"))
 
-def unwrap__Slice(space, w_slice):
-    return slice(space.unwrap(w_slice.w_start), space.unwrap(w_slice.w_stop), space.unwrap(w_slice.w_step))
-
 register_all(vars())

Modified: pypy/dist/pypy/objspace/std/stdtypedef.py
==============================================================================
--- pypy/dist/pypy/objspace/std/stdtypedef.py	(original)
+++ pypy/dist/pypy/objspace/std/stdtypedef.py	Mon Feb  7 20:26:07 2005
@@ -1,7 +1,7 @@
 from pypy.interpreter import eval, function, gateway
 from pypy.interpreter.error import OperationError
 from pypy.interpreter.typedef import TypeDef, GetSetProperty, Member
-from pypy.objspace.std.multimethod import MultiMethod, FailedToImplement
+from pypy.objspace.std.model import MultiMethod, FailedToImplement
 
 __all__ = ['StdTypeDef', 'newmethod', 'gateway',
            'GetSetProperty', 'Member', 'attrproperty', 'attrproperty_w',
@@ -24,9 +24,9 @@
     if b is object_typedef:
         return True
     while a is not b:
-        a = a.base
         if a is None:
             return False
+        a = a.base
     return True
 
 def attrproperty(name):
@@ -77,16 +77,11 @@
 
     if isinstance(typedef, StdTypeDef):
         # get all the sliced multimethods
-        multimethods = slicemultimethods(space.__class__, typedef)
-        for name, code in multimethods.items():
-            # compute the slice and ignore the multimethod if empty
-            if not code.computeslice(space):
-                continue
-            # create a Function around the sliced multimethod code
-            fn = function.Function(space, code, defs_w=code.getdefaults(space))
+        multimethods = slicemultimethods(space, typedef)
+        for name, gateway in multimethods.items():
             assert name not in rawdict, 'name clash: %s in %s_typedef' % (
                 name, typedef.name)
-            rawdict[name] = fn
+            rawdict[name] = gateway
 
     # compute the bases
     if typedef is object_typedef:
@@ -111,150 +106,266 @@
             result.append(value)
     return result
 
-def make_frameclass_for_arity(arity, varargs, keywords, isspecial):
-    argnames = []
-    for i in range(arity):
-        argnames.append('arg%dof%d'%(i+1, arity))
-    if varargs:
-        argnames.append('var_args')
-    if keywords:
-        argnames.append('kw_args')
-    self_args_assigning = []
-    for i in range(len(argnames)):
-        self_args_assigning.append('        self.%s = args[%i]'%(argnames[i], i))
-    self_args_assigning = "\n".join(self_args_assigning)
-    self_args = ", ".join(['self.'+ a for a in argnames])
-    name = 'MmFrameOfArity%d'%arity
-    if varargs:
-        name += "Var"
-    if keywords:
-        name += "KW"
-    if isspecial:
-        name = "Special" + name
-    d = locals()
-    template = mmtemplate
-    if isspecial:
-        template += specialmmruntemplate
+##def make_frameclass_for_arity(arity, varargs, keywords, isspecial):
+##    argnames = []
+##    for i in range(arity):
+##        argnames.append('arg%dof%d'%(i+1, arity))
+##    if varargs:
+##        argnames.append('var_args')
+##    if keywords:
+##        argnames.append('kw_args')
+##    self_args_assigning = []
+##    for i in range(len(argnames)):
+##        self_args_assigning.append('        self.%s = args[%i]'%(argnames[i], i))
+##    self_args_assigning = "\n".join(self_args_assigning)
+##    self_args = ", ".join(['self.'+ a for a in argnames])
+##    name = 'MmFrameOfArity%d'%arity
+##    if varargs:
+##        name += "Var"
+##    if keywords:
+##        name += "KW"
+##    if isspecial:
+##        name = "Special" + name
+##    d = locals()
+##    template = mmtemplate
+##    if isspecial:
+##        template += specialmmruntemplate
+##    else:
+##        template += mmruntemplate
+###    print template%d
+##    exec template%d in globals(), d
+##    return d[name]
+##
+##_frameclass_for_arity_cache = {}
+##def frameclass_for_arity(arity, varargs, keywords, isspecial):
+##    try:
+##        return _frameclass_for_arity_cache[(arity, varargs, keywords, isspecial)]
+##    except KeyError:
+##        r = _frameclass_for_arity_cache[(arity, varargs, keywords, isspecial)] = \
+##                make_frameclass_for_arity(arity, varargs, keywords, isspecial)
+##        return r
+
+
+def sliced_typeorders(typeorder, multimethod, typedef, i, local=False):
+    list_of_typeorders = [typeorder] * multimethod.arity
+    prefix = '_mm_' + multimethod.name
+    if not local:
+        # slice
+        sliced_typeorder = {}
+        for type, order in typeorder.items():
+            thistypedef = getattr(type, 'typedef', None)
+            if issubtypedef(thistypedef, typedef):
+                lst = []
+                for target_type, conversion in order:
+                    targettypedef = getattr(target_type, 'typedef', None)
+                    if targettypedef == typedef:
+                        lst.append((target_type, conversion))
+                sliced_typeorder[type] = lst
+        list_of_typeorders[i] = sliced_typeorder
+        prefix += '_%sS%d' % (typedef.name, i)
+    else:
+        prefix = typedef.name +'_mth'+prefix
+    return prefix, list_of_typeorders
+
+def typeerrormsg(space, operatorsymbol, args_w):
+    type_names = [ space.type(w_arg).name for w_arg in args_w ]
+    if len(args_w) > 1:
+        plural = 's'
     else:
-        template += mmruntemplate
-#    print template%d
-    exec template%d in globals(), d
-    return d[name]
+        plural = ''
+    msg = "unsupported operand type%s for %s (%s)" % (
+                    plural, operatorsymbol,
+                    ', '.join(type_names))    
+    return space.wrap(msg)
+
+def make_perform_trampoline(prefix, exprargs, expr, miniglobals,  multimethod, selfindex=0,
+                            allow_NotImplemented_results=False):
+    # mess to figure out how to put a gateway around executing expr
+    argnames = ['_%d'%(i+1) for i in range(multimethod.arity)]
+    explicit_argnames = multimethod.extras.get('argnames', [])
+    argnames[len(argnames)-len(explicit_argnames):] = explicit_argnames
+    solid_arglist = ['w_'+name for name in argnames]
+    wrapper_arglist = solid_arglist[:]
+    if multimethod.extras.get('varargs_w', False):
+        wrapper_arglist.append('args_w')
+    if multimethod.extras.get('w_varargs', False):
+        wrapper_arglist.append('w_args')        
+    if multimethod.extras.get('keywords', False):
+        raise Exception, "no longer supported, use __args__"
+    if multimethod.extras.get('general__args__', False):
+        wrapper_arglist.append('__args__')
+
+    miniglobals.update({ 'OperationError': OperationError,                         
+                         'typeerrormsg': typeerrormsg})
     
-_frameclass_for_arity_cache = {}
-def frameclass_for_arity(arity, varargs, keywords, isspecial):
-    try:
-        return _frameclass_for_arity_cache[(arity, varargs, keywords, isspecial)]
-    except KeyError:
-        r = _frameclass_for_arity_cache[(arity, varargs, keywords, isspecial)] = \
-                make_frameclass_for_arity(arity, varargs, keywords, isspecial)
-        return r
+    app_defaults = multimethod.extras.get('defaults', ())
+    i = len(argnames) - len(app_defaults)
+    wrapper_signature = wrapper_arglist[:]
+    for app_default in app_defaults:
+        name = wrapper_signature[i]
+        wrapper_signature[i] = '%s=%s' % (name, name)
+        miniglobals[name] = app_default
+        i += 1
+
+    wrapper_signature.insert(0, wrapper_signature.pop(selfindex))
+    wrapper_sig  = ', '.join(wrapper_signature)
+
+    src = []
+    dest = []
+    for wrapper_arg,expr_arg in zip(['space']+wrapper_arglist, exprargs):
+        if wrapper_arg != expr_arg:
+            src.append(wrapper_arg)
+            dest.append(expr_arg)
+    renaming = ', '.join(dest) +" = "+', '.join(src)
+
+    if allow_NotImplemented_results and len(multimethod.specialnames) > 1:
+        # turn FailedToImplement into NotImplemented
+        code = """def %s_perform_call(space, %s):
+                      %s
+                      try:
+                          return %s
+                      except FailedToImplement, e:
+                          if e.args:
+                              raise OperationError(e.args[0], e.args[1])
+                          else:
+                              return space.w_NotImplemented
+"""        % (prefix, wrapper_sig, renaming, expr)
+    else:
+        # turn FailedToImplement into nice TypeErrors
+        code = """def %s_perform_call(space, %s):
+                      %s
+                      try:
+                          w_res = %s
+                      except FailedToImplement, e:
+                          if e.args:
+                              raise OperationError(e.args[0], e.args[1])
+                          else:
+                              raise OperationError(space.w_TypeError,
+                                  typeerrormsg(space, %r, [%s]))
+                      if w_res is None:
+                          w_res = space.w_None
+                      return w_res
+"""        % (prefix, wrapper_sig, renaming, expr,
+              multimethod.operatorsymbol, ', '.join(solid_arglist))
+    exec code in miniglobals
+    return miniglobals["%s_perform_call" % prefix]
+
+def wrap_trampoline_in_gateway(func, methname, multimethod):
+    unwrap_spec = [gateway.ObjSpace] + [gateway.W_Root]*multimethod.arity
+    if multimethod.extras.get('varargs_w', False):
+        unwrap_spec.append('args_w')
+    if multimethod.extras.get('w_varargs', False):
+        unwrap_spec.append('w_args')        
+    if multimethod.extras.get('general__args__', False):
+        unwrap_spec.append(gateway.Arguments)
+    return gateway.interp2app(func, app_name=methname, unwrap_spec=unwrap_spec)
 
-def slicemultimethod(multimethod, typeclass, result):
+def slicemultimethod(space, multimethod, typedef, result, local=False):
+    from pypy.objspace.std.objecttype import object_typedef
     for i in range(len(multimethod.specialnames)):
         # each MultimethodCode embeds a multimethod
-        name = multimethod.specialnames[i]
-        if name in result:
+        methname = multimethod.specialnames[i]
+        if methname in result:
             # conflict between e.g. __lt__ and
             # __lt__-as-reversed-version-of-__gt__
-            code = result[name]
-            if code.bound_position < i:
+            gw = result[methname]
+            if gw.bound_position < i:
                 continue
-        mmframeclass = frameclass_for_arity(multimethod.arity,
-                                            multimethod.extras.get('varargs', False),
-                                            multimethod.extras.get('keywords', False),
-                                            len(multimethod.specialnames) > 1)
-        code = MultimethodCode(multimethod, mmframeclass, typeclass, i)
-        result[name] = code
 
-def slicemultimethods(spaceclass, typeclass):
+        prefix, list_of_typeorders = sliced_typeorders(
+            space.model.typeorder, multimethod, typedef, i, local=local)
+        exprargs, expr, miniglobals, fallback = multimethod.install(prefix, list_of_typeorders,
+                                                                    baked_perform_call=False)
+        if fallback:
+            continue   # skip empty multimethods
+        trampoline = make_perform_trampoline(prefix, exprargs, expr, miniglobals,
+                                             multimethod, i,
+                                             allow_NotImplemented_results=True)
+        gw = wrap_trampoline_in_gateway(trampoline, methname, multimethod)
+        gw.bound_position = i   # for the check above
+        result[methname] = gw
+
+def slicemultimethods(space, typedef):
     result = {}
     # import and slice all multimethods of the space.MM container
-    for multimethod in hack_out_multimethods(spaceclass.MM.__dict__):
-        slicemultimethod(multimethod, typeclass, result)
+    for multimethod in hack_out_multimethods(space.MM.__dict__):
+        slicemultimethod(space, multimethod, typedef, result)
     # import all multimethods defined directly on the type without slicing
-    for multimethod in typeclass.local_multimethods:
-        slicemultimethod(multimethod, None, result)
+    for multimethod in typedef.local_multimethods:
+        slicemultimethod(space, multimethod, typedef, result, local=True)
     return result
 
-class MultimethodCode(eval.Code):
-    """A code object that invokes a multimethod."""
+##class MultimethodCode(eval.Code):
+##    """A code object that invokes a multimethod."""
     
-    def __init__(self, multimethod, framecls, typeclass, bound_position=0):
-        "NOT_RPYTHON: initialization-time only."
-        eval.Code.__init__(self, multimethod.operatorsymbol)
-        self.basemultimethod = multimethod
-        self.typeclass = typeclass
-        self.bound_position = bound_position
-        self.framecls = framecls
-        argnames = ['_%d'%(i+1) for i in range(multimethod.arity)]
-        explicit_argnames = multimethod.extras.get('argnames', [])
-        argnames[len(argnames)-len(explicit_argnames):] = explicit_argnames
-        varargname = kwargname = None
-        # XXX do something about __call__ and __init__ which still use
-        # XXX packed arguments: w_args, w_kwds instead of *args_w, **kwds_w
-        if multimethod.extras.get('varargs', False):
-            varargname = 'args'
-        if multimethod.extras.get('keywords', False):
-            kwargname = 'keywords'
-        self.sig = argnames, varargname, kwargname
-
-    def computeslice(self, space):
-        "NOT_RPYTHON: initialization-time only."
-        if self.typeclass is None:
-            slice = self.basemultimethod
-        else:
-            slice = self.basemultimethod.slice(self.typeclass,
-                                               self.bound_position)
-        if slice.is_empty():
-            return False
-        else:
-            self.mm = slice.get(space)
-            return True
-
-    def signature(self):
-        return self.sig
-
-    def getdefaults(self, space):
-        return [space.wrap(x)
-                for x in self.basemultimethod.extras.get('defaults', ())]
-
-    def create_frame(self, space, w_globals, closure=None):
-        return self.framecls(space, self)
-
-mmtemplate = """
-class %(name)s(eval.Frame):
-
-    def setfastscope(self, scope_w):
-        args = list(scope_w)
-        args.insert(0, args.pop(self.code.bound_position))
-%(self_args_assigning)s
-
-    def getfastscope(self):
-        raise OperationError(self.space.w_TypeError,
-          self.space.wrap("cannot get fastscope of a MmFrame"))
-"""
-
-mmruntemplate = """
-    def run(self):
-        "Call the multimethod, raising a TypeError if not implemented."
-        w_result = self.code.mm(%(self_args)s)
-        # we accept a real None from operations with no return value
-        if w_result is None:
-            w_result = self.space.w_None
-        return w_result
-"""
-
-specialmmruntemplate = """
-
-    def run(self):
-        "Call the multimethods, possibly returning a NotImplemented."
-        try:
-            return self.code.mm.perform_call(%(self_args)s)
-        except FailedToImplement, e:
-            if e.args:
-                raise OperationError(e.args[0], e.args[1])
-            else:
-                return self.space.w_NotImplemented
+##    def __init__(self, multimethod, framecls, typeclass, bound_position=0):
+##        "NOT_RPYTHON: initialization-time only."
+##        eval.Code.__init__(self, multimethod.operatorsymbol)
+##        self.basemultimethod = multimethod
+##        self.typeclass = typeclass
+##        self.bound_position = bound_position
+##        self.framecls = framecls
+##        argnames = ['_%d'%(i+1) for i in range(multimethod.arity)]
+##        explicit_argnames = multimethod.extras.get('argnames', [])
+##        argnames[len(argnames)-len(explicit_argnames):] = explicit_argnames
+##        varargname = kwargname = None
+##        # XXX do something about __call__ and __init__ which still use
+##        # XXX packed arguments: w_args, w_kwds instead of *args_w, **kwds_w
+##        if multimethod.extras.get('varargs', False):
+##            varargname = 'args'
+##        if multimethod.extras.get('keywords', False):
+##            kwargname = 'keywords'
+##        self.sig = argnames, varargname, kwargname
+
+##    def computeslice(self, space):
+##        "NOT_RPYTHON: initialization-time only."
+##        self.mm = self.basemultimethod.__get__(space, slice=(
+##            self.typeclass, self.bound_position))
+##        return not self.mm.is_empty()
+
+##    def signature(self):
+##        return self.sig
+
+##    def getdefaults(self, space):
+##        return [space.wrap(x)
+##                for x in self.basemultimethod.extras.get('defaults', ())]
+
+##    def create_frame(self, space, w_globals, closure=None):
+##        return self.framecls(space, self)
+
+##mmtemplate = """
+##class %(name)s(eval.Frame):
+
+##    def setfastscope(self, scope_w):
+##        args = list(scope_w)
+##        args.insert(0, args.pop(self.code.bound_position))
+##%(self_args_assigning)s
+
+##    def getfastscope(self):
+##        raise OperationError(self.space.w_TypeError,
+##          self.space.wrap("cannot get fastscope of a MmFrame"))
+##"""
+
+##mmruntemplate = """
+##    def run(self):
+##        "Call the multimethod, raising a TypeError if not implemented."
+##        w_result = self.code.mm(%(self_args)s)
+##        # we accept a real None from operations with no return value
+##        if w_result is None:
+##            w_result = self.space.w_None
+##        return w_result
+##"""
+
+##specialmmruntemplate = """
+
+##    def run(self):
+##        "Call the multimethods, possibly returning a NotImplemented."
+##        try:
+##            return self.code.mm.perform_call(%(self_args)s)
+##        except FailedToImplement, e:
+##            if e.args:
+##                raise OperationError(e.args[0], e.args[1])
+##            else:
+##                return self.space.w_NotImplemented
 
-"""
+##"""

Modified: pypy/dist/pypy/objspace/std/stringobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/stringobject.py	(original)
+++ pypy/dist/pypy/objspace/std/stringobject.py	Mon Feb  7 20:26:07 2005
@@ -14,7 +14,6 @@
                   def ord__String(space, w_str):
                   def string_richcompare(space, w_str1, w_str2, op):
                   def str_w__String(space, w_str):
-                  def unwrap__String(space, w_str):
 __add__           def add__String_String(space, w_left, w_right):
 __class__
 __contains__
@@ -23,7 +22,7 @@
 __eq__            def eq__String_String(space, w_str1, w_str2):
 __ge__            def ge__String_String(space, w_str1, w_str2):
 __getattribute__
-__getitem__       def getitem__String_Int(space, w_str, w_int): def getitem__String_Slice(space, w_str, w_slice):
+__getitem__       def getitem__String_ANY(space, w_str, w_int): def getitem__String_Slice(space, w_str, w_slice):
 __getslice__
 __gt__            def gt__String_String(space, w_str1, w_str2):
 __hash__          def hash__String(space, w_str):
@@ -40,12 +39,12 @@
 __setattr__
 __str__           def str__String(space, w_str):
 capitalize        def str_capitalize__String(space, w_self):
-center            def str_center__String_Int(space, w_self):
-count             def str_count__String_String_Int_Int(space, w_self): [optional arguments not supported now]
+center            def str_center__String_ANY(space, w_self):
+count             def str_count__String_String_ANY_ANY(space, w_self): [optional arguments not supported now]
 decode            !Unicode not supported now
 encode            !Unicode not supported now
 endswith          str_endswith__String_String    [optional arguments not supported now]
-expandtabs        str_expandtabs__String_Int
+expandtabs        str_expandtabs__String_ANY
 find              OK
 index             OK
 isalnum           def str_isalnum__String(space, w_self): def _isalnum(ch):
@@ -64,7 +63,7 @@
 rindex            OK
 rjust             def str_rjust__String_ANY(space, w_self, w_arg):
 rstrip            def str_rstrip__String_String(space, w_self, w_chars):
-split             def str_split__String_None_Int(space, w_self, w_none, w_maxsplit=-1):def str_split__String_String_Int(space, w_self, w_by, w_maxsplit=-1):
+split             def str_split__String_None_ANY(space, w_self, w_none, w_maxsplit=-1):def str_split__String_String_ANY(space, w_self, w_by, w_maxsplit=-1):
 splitlines        def str_splitlines__String_String(space, w_self, w_keepends):
 startswith        str_startswith__String_String    [optional arguments not supported now]
 strip             def str_strip__String_String(space, w_self, w_chars):
@@ -100,6 +99,9 @@
         """ representation for debugging purposes """
         return "%s(%r)" % (w_self.__class__.__name__, w_self._value)
 
+    def unwrap(w_self):
+        return w_self._value
+
 
 registerimplementation(W_StringObject)
 
@@ -767,9 +769,6 @@
 
 def str_w__String(space, w_str):
     return w_str._value
-    
-def unwrap__String(space, w_str):
-    return w_str._value
 
 def hash__String(space, w_str):
     w_hash = w_str.w_hash
@@ -891,8 +890,8 @@
     else:
         return space.w_False
 
-def getitem__String_Int(space, w_str, w_int):
-    ival = space.int_w(w_int)
+def getitem__String_ANY(space, w_str, w_index):
+    ival = space.int_w(w_index)
     str = w_str._value
     slen = len(str)
     if ival < 0:
@@ -913,9 +912,8 @@
     w_empty = space.newstring([])
     return str_join__String_ANY(space, w_empty, w_r)
 
-def mul__String_Int(space, w_str, w_mul):
+def mul_string_times(space, w_str, mul):
     input = w_str._value
-    mul = space.int_w(w_mul)
     if mul < 0:
         return space.wrap("")
     input_len = len(input)
@@ -932,8 +930,11 @@
 
     return space.wrap("".join(buffer))
 
-def mul__Int_String(space, w_mul, w_str):
-    return mul__String_Int(space, w_str, w_mul)
+def mul__String_ANY(space, w_str, w_times):
+    return mul_string_times(space, w_str, space.int_w(w_times))
+
+def mul__ANY_String(space, w_mul, w_str):
+    return mul_string_times(space, w_str, space.int_w(w_times))
 
 def add__String_String(space, w_left, w_right):
     right = w_right._value

Modified: pypy/dist/pypy/objspace/std/stringtype.py
==============================================================================
--- pypy/dist/pypy/objspace/std/stringtype.py	(original)
+++ pypy/dist/pypy/objspace/std/stringtype.py	Mon Feb  7 20:26:07 2005
@@ -39,15 +39,12 @@
 
 # ____________________________________________________________
 
-def descr__new__(space, w_stringtype, w_obj=None):
+def descr__new__(space, w_stringtype, w_obj=''):
     from pypy.objspace.std.stringobject import W_StringObject
-    if w_obj is None:
-        value = ''
-    else:
-        w_obj = space.str(w_obj)
-        if space.is_true(space.is_(w_stringtype, space.w_str)):
-            return w_obj  # XXX might be reworked when space.str() typechecks
-        value = space.str_w(w_obj)
+    w_obj = space.str(w_obj)
+    if space.is_true(space.is_(w_stringtype, space.w_str)):
+        return w_obj  # XXX might be reworked when space.str() typechecks
+    value = space.str_w(w_obj)
     w_obj = space.allocate_instance(W_StringObject, w_stringtype)
     w_obj.__init__(space, value)
     return w_obj

Modified: pypy/dist/pypy/objspace/std/test/test_multimethod.py
==============================================================================
--- pypy/dist/pypy/objspace/std/test/test_multimethod.py	(original)
+++ pypy/dist/pypy/objspace/std/test/test_multimethod.py	Mon Feb  7 20:26:07 2005
@@ -1,145 +1,94 @@
 import autopath
+from py.test import raises
 
 from pypy.objspace.std.multimethod import *
 
-BoundMultiMethod.ASSERT_BASE_TYPE = object
 
+class W_Root(object):
+    pass
 
-objspacename = 'std'
+class W_IntObject(W_Root):
+    pass
 
-class X:
-    def __init__(self, value):
-        self.value = value
-    def __repr__(self):
-        return '<X %r>' % self.value
+class W_BoolObject(W_Root):
+    pass
 
-def from_y_to_x(space, yinstance):
-    return X(yinstance)
-
-from_y_to_x.result_class = X
-from_y_to_x.priority = 2
-
-def from_x_to_str(space, xinstance):
-    #if xinstance.value:
-    return w('!' + repr(xinstance.value))
-    #else:
-    #    return []
-
-from_x_to_str.result_class = str
-from_x_to_str.priority = 2
-
-
-class Y:
-    def __init__(self, value):
-        self.value = value
-    def __repr__(self):
-        return '<Y %r>' % self.value
-    def __nonzero__(self):
-        return self.value != 666
-
-
-def add_x_x(space, x1, x2):
-    return "add_x_x", x1, x2
-
-def add_x_y(space, x1, y2):
-    if x1.value < 0:
-        raise FailedToImplement(ValueError, 'not good')
-    return "add_x_y", x1, y2
-
-def add_y_y(space, y1, y2):
-    return "add_y_y", y1, y2
-
-def add_string_string(space, x, y):
-    return "add_string_string", x, y
-
-def add_int_string(space, x, y):
-    return "add_int_string", x, y
-
-def add_int_any(space, y1, o2):
-    return "add_int_any", y1, o2
-
-class FakeObjSpace:
-    add = MultiMethod('+', 2, [])
-    add.register(add_x_x,           X,   X)
-    add.register(add_x_y,           X,   Y)
-    add.register(add_y_y,           Y,   Y)
-    add.register(add_string_string, str, str)
-    add.register(add_int_string,    int, str)
-    add.register(add_int_any,       int, object)
-
-    delegate = DelegateMultiMethod()
-    delegate.register(from_y_to_x,    Y)
-    delegate.register(from_x_to_str,  X)
+class W_StringObject(W_Root):
+    pass
+
+def delegate_b2i(w_x):
+    assert isinstance(w_x, W_BoolObject)
+    return W_IntObject()
+
+add = MultiMethodTable(2, root_class=W_Root, argnames_before=['space'])
+
+def add__Int_Int(space, w_x, w_y):
+    assert space == 'space'
+    assert isinstance(w_x, W_IntObject)
+    assert isinstance(w_y, W_IntObject)
+    return 'fine'
+
+add.register(add__Int_Int, W_IntObject, W_IntObject)
+
+
+def setup_module(mod):
+    typeorder = {
+        W_IntObject: [(W_IntObject, None)],
+        W_BoolObject: [(W_BoolObject, None), (W_IntObject, delegate_b2i)],
+        W_StringObject: [(W_StringObject, None)],
+        }
+    mod.typeorder = typeorder
+    mod.add1 = add.install('__add', [typeorder, typeorder])
+
+
+def test_simple():
+    space = 'space'
+    w_x = W_IntObject()
+    w_y = W_IntObject()
+    assert add1(space, w_x, w_y) == 'fine'
+
+def test_failtoimplement():
+    space = 'space'
+    w_x = W_IntObject()
+    w_s = W_StringObject()
+    raises(FailedToImplement, "add1(space, w_x, w_s)")
+    raises(FailedToImplement, "add1(space, w_s, w_x)")
+
+def test_delegate():
+    space = 'space'
+    w_x = W_IntObject()
+    w_s = W_StringObject()
+    w_b = W_BoolObject()
+    assert add1(space, w_x, w_b) == 'fine'
+    assert add1(space, w_b, w_x) == 'fine'
+    assert add1(space, w_b, w_b) == 'fine'
+    raises(FailedToImplement, "add1(space, w_b, w_s)")
+    raises(FailedToImplement, "add1(space, w_s, w_b)")
+
+def test_not_baked():
+    add2 = add.install('__add2', [typeorder, typeorder],baked_perform_call=False)
+    assert add2[0] == ['space', 'arg0', 'arg1']
+    assert add2[1] == 'arg0.__add2(space, arg1)'
+    assert isinstance(add2[2], dict)
+    assert not add2[3]
+
+def test_empty():
+    add3_installer = Installer(add, '__add3', [{},{}])
+    assert add3_installer.is_empty()
+    assert len(add3_installer.to_install) == 1
+    assert add3_installer.to_install[0][0] is None
+
+def test_empty_direct():
+    assert not add.install_if_not_empty('__add4', [{},{}])
+
+
+def test_empty_not_baked():
+    add5_installer = Installer(add, '__add5', [{},{}], baked_perform_call=False)
+    assert add5_installer.is_empty()
+    assert len(add5_installer.to_install) == 0
+    add5 = add5_installer.install()
+    assert add5[0] == ['space', 'arg0', 'arg1']
+    assert add5[1] == 'raiseFailedToImplement()'
+    assert isinstance(add5[2], dict)
+    assert add5[3]
     
-    def wrap(self, x):
-        return '<wrapped %r>' % (x,)
-    w_TypeError = 'w_TypeError'
-
-##def w(x, cache={}):
-##    if type(x) in cache:
-##        Stub = cache[type(x)]
-##    else:
-##        Stub = type(type(x))('%s_stub' % type(x).__name__, (type(x),), {})
-##        Stub.dispatchclass = Stub
-##        cache[type(x)] = Stub
-##    return Stub(x)
-
-##X.dispatchclass = X
-##Y.dispatchclass = Y
-
-def w(x):
-    return x
-
-
-class TestMultiMethod:
-    def setup_method(self,method):
-        # only run when testing stdobjectspace 
-        #XXX removed: self.space
-        self.space = FakeObjSpace()
-
-    def test_non_delegate(self):
-        space = self.space
-        
-        r = space.add(X(2), X(5))
-        assert repr(r) == "('add_x_x', <X 2>, <X 5>)"
-        
-        r = space.add(X(3), Y(4))
-        assert repr(r) == "('add_x_y', <X 3>, <Y 4>)"
-
-        r = space.add(Y(0), Y(20))
-        assert repr(r) == "('add_y_y', <Y 0>, <Y 20>)"
-
-        r = space.add(w(-3), w([7,6,5]))
-        assert repr(r) == "('add_int_any', -3, [7, 6, 5])"
-
-        r = space.add(w(5), w("test"))
-        assert repr(r) == "('add_int_string', 5, 'test')"
-
-        r = space.add(w("x"), w("y"))
-        assert repr(r) == "('add_string_string', 'x', 'y')"
-        
-    def test_delegate_y_to_x(self):
-        space = self.space
-        r = space.add(Y(-1), X(7))
-        assert repr(r) == "('add_x_x', <X <Y -1>>, <X 7>)"
-        
-        r = space.add(Y(1), X(7))
-        assert repr(r) == "('add_x_x', <X <Y 1>>, <X 7>)"
-        
-        r = space.add(X(-3), Y(20))
-        assert repr(r) == "('add_x_x', <X -3>, <X <Y 20>>)"
-       
-    def test_no_operation_defined(self):
-        space = self.space
-        raises(OperationError, space.add, w([3]), w(4))
-        raises(OperationError, space.add, w(3.0), w('bla'))
-        #raises(OperationError, space.add, X(0), w("spam"))
-        #raises(OperationError, space.add, Y(666), w("egg"))
-
-    def test_delegate_x_to_str(self):
-        space = self.space
-        r = space.add(X(42), w("spam"))
-        assert repr(r) == "('add_string_string', '!42', 'spam')"
-
-        r = space.add(Y(20), w("egg"))
-        assert repr(r) == "('add_string_string', '!<Y 20>', 'egg')"

Modified: pypy/dist/pypy/objspace/std/tupleobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/tupleobject.py	(original)
+++ pypy/dist/pypy/objspace/std/tupleobject.py	Mon Feb  7 20:26:07 2005
@@ -16,22 +16,23 @@
         reprlist = [repr(w_item) for w_item in w_self.wrappeditems]
         return "%s(%s)" % (w_self.__class__.__name__, ', '.join(reprlist))
 
+    def unwrap(w_tuple):
+        space = w_tuple.space
+        items = [space.unwrap(w_item) for w_item in w_tuple.wrappeditems] # XXX generic mixed types unwrap
+        return tuple(items)
 
-registerimplementation(W_TupleObject)
 
+registerimplementation(W_TupleObject)
 
-def unwrap__Tuple(space, w_tuple): 
-    items = [space.unwrap(w_item) for w_item in w_tuple.wrappeditems] # XXX generic mixed types unwrap
-    return tuple(items)
 
 def len__Tuple(space, w_tuple):
     result = len(w_tuple.wrappeditems)
     return W_IntObject(space, result)
 
-def getitem__Tuple_Int(space, w_tuple, w_index):
+def getitem__Tuple_ANY(space, w_tuple, w_index):
     items = w_tuple.wrappeditems
     try:
-        w_item = items[w_index.intval]
+        w_item = items[space.int_w(w_index)]
     except IndexError:
         raise OperationError(space.w_IndexError,
                              space.wrap("tuple index out of range"))
@@ -63,14 +64,15 @@
     items2 = w_tuple2.wrappeditems
     return W_TupleObject(space, items1 + items2)
 
-def mul__Tuple_Int(space, w_tuple, w_int):
+def mul_tuple_times(space, w_tuple, times):
     items = w_tuple.wrappeditems
-    times = w_int.intval
-    return W_TupleObject(space, items * times)
+    return W_TupleObject(space, items * times)    
 
+def mul__Tuple_ANY(space, w_tuple, w_times):
+    return mul_tuple_times(space, w_tuple, space.int_w(w_times))
 
-def mul__Int_Tuple(space, w_int, w_tuple):
-    return mul__Tuple_Int(space, w_tuple, w_int)
+def mul__ANY_Tuple(space, w_times, w_tuple):
+    return mul_tuple_times(space, w_tuple, space.int_w(w_times))
 
 def eq__Tuple_Tuple(space, w_tuple1, w_tuple2):
     items1 = w_tuple1.wrappeditems

Modified: pypy/dist/pypy/objspace/std/tupletype.py
==============================================================================
--- pypy/dist/pypy/objspace/std/tupletype.py	(original)
+++ pypy/dist/pypy/objspace/std/tupletype.py	Mon Feb  7 20:26:07 2005
@@ -1,7 +1,7 @@
 from pypy.objspace.std.stdtypedef import *
+from pypy.interpreter.gateway import NoneNotWrapped
 
-
-def descr__new__(space, w_tupletype, w_items=None):
+def descr__new__(space, w_tupletype, w_items=NoneNotWrapped):
     from pypy.objspace.std.tupleobject import W_TupleObject
     if w_items is None:
         tuple_w = []

Modified: pypy/dist/pypy/objspace/std/typeobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/typeobject.py	(original)
+++ pypy/dist/pypy/objspace/std/typeobject.py	Mon Feb  7 20:26:07 2005
@@ -170,24 +170,29 @@
                              space.wrap("attribute '__dict__' of type objects "
                                         "is not writable"))
 
+    def unwrap(w_self):
+        if hasattr(w_self.instancetypedef, 'fakedcpytype'):
+            return w_self.instancetypedef.fakedcpytype
+        from pypy.objspace.std.model import UnwrapError
+        raise UnwrapError(w_self)
 
-def call__Type(space, w_type, w_args, w_kwds):
-    args = Arguments.frompacked(space, w_args, w_kwds)
+
+def call__Type(space, w_type, __args__):
     # special case for type(x)
     if space.is_true(space.is_(w_type, space.w_type)):
         try:
-            w_obj, = args.fixedunpack(1)
+            w_obj, = __args__.fixedunpack(1)
         except ValueError:
             pass
         else:
             return space.type(w_obj)
     # invoke the __new__ of the type
     w_newfunc = space.getattr(w_type, space.wrap('__new__'))
-    w_newobject = space.call_args(w_newfunc, args.prepend(w_type))
+    w_newobject = space.call_args(w_newfunc, __args__.prepend(w_type))
     # maybe invoke the __init__ of the type
     if space.is_true(space.isinstance(w_newobject, w_type)):
         w_descr = space.lookup(w_newobject, '__init__')
-        space.get_and_call_args(w_descr, w_newobject, args)
+        space.get_and_call_args(w_descr, w_newobject, __args__)
     return w_newobject
 
 def issubtype__Type_Type(space, w_type1, w_type2):
@@ -229,11 +234,6 @@
 # XXX __delattr__
 # XXX __hash__ ??
 
-def unwrap__Type(space, w_type):
-    if hasattr(w_type.instancetypedef, 'fakedcpytype'):
-        return w_type.instancetypedef.fakedcpytype
-    raise FailedToImplement
-
 # ____________________________________________________________
 
 

Modified: pypy/dist/pypy/objspace/std/unicodeobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/unicodeobject.py	(original)
+++ pypy/dist/pypy/objspace/std/unicodeobject.py	Mon Feb  7 20:26:07 2005
@@ -5,10 +5,10 @@
 W_UnicodeObject = fake_type(unicode)
 
 # string-to-unicode delegation
-def delegate__String(space, w_str):
+def delegate_String2Unicode(w_str):
+    space = w_str.space
     return W_UnicodeObject(space, unicode(space.str_w(w_str)))
-delegate__String.result_class = W_UnicodeObject
-delegate__String.priority = PRIORITY_CHANGE_TYPE
+
 
 def eq__Unicode_ANY(space, w_uni, w_other):
     try:



More information about the Pypy-commit mailing list