[pypy-commit] pypy kill-multimethod: Remove pypy.objspace.std.multimethod and make tests pass again.

Manuel Jacob noreply at buildbot.pypy.org
Tue Feb 25 06:00:27 CET 2014


Author: Manuel Jacob
Branch: kill-multimethod
Changeset: r69400:0f3b67d218ae
Date: 2014-02-25 05:38 +0100
http://bitbucket.org/pypy/pypy/changeset/0f3b67d218ae/

Log:	Remove pypy.objspace.std.multimethod and make tests pass again.

diff --git a/pypy/objspace/std/builtinshortcut.py b/pypy/objspace/std/builtinshortcut.py
--- a/pypy/objspace/std/builtinshortcut.py
+++ b/pypy/objspace/std/builtinshortcut.py
@@ -1,7 +1,6 @@
 from pypy.interpreter.baseobjspace import ObjSpace
 from pypy.interpreter.error import OperationError
 from pypy.objspace.descroperation import DescrOperation
-from pypy.objspace.std.multimethod import FailedToImplement
 from pypy.objspace.std.boolobject import W_BoolObject
 from rpython.tool.sourcetools import func_with_new_name
 
diff --git a/pypy/objspace/std/model.py b/pypy/objspace/std/model.py
--- a/pypy/objspace/std/model.py
+++ b/pypy/objspace/std/model.py
@@ -3,7 +3,6 @@
 to provide in this version of PyPy, along with conversion rules.
 """
 
-from pypy.objspace.std.multimethod import MultiMethodTable, FailedToImplement
 from pypy.interpreter.baseobjspace import W_Root, ObjSpace
 import pypy.interpreter.pycode
 import pypy.interpreter.special
@@ -266,88 +265,3 @@
 
 class UnwrapError(Exception):
     pass
-
-
-class StdObjSpaceMultiMethod(MultiMethodTable):
-
-    def __init__(self, operatorsymbol, arity, specialnames=None, **extras):
-        """NOT_RPYTHON: cannot create new multimethods dynamically.
-        """
-        MultiMethodTable.__init__(self, arity, W_ANY,
-                                  argnames_before = ['space'])
-        self.operatorsymbol = operatorsymbol
-        if specialnames is None:
-            specialnames = [operatorsymbol]
-        assert isinstance(specialnames, list)
-        self.specialnames = specialnames  # e.g. ['__xxx__', '__rxxx__']
-        self.extras = extras
-        # transform  '+'  =>  'add'  etc.
-        for line in ObjSpace.MethodTable:
-            realname, symbolname = line[:2]
-            if symbolname == operatorsymbol:
-                self.name = realname
-                break
-        else:
-            self.name = operatorsymbol
-
-        if extras.get('general__args__', False):
-            self.argnames_after = ['__args__']
-        if extras.get('varargs_w', False):
-            self.argnames_after = ['args_w']
-        self.argnames_after += extras.get('extra_args', [])
-
-    def install_not_sliced(self, typeorder, baked_perform_call=True):
-        return self.install(prefix = '__mm_' + self.name,
-                list_of_typeorders = [typeorder]*self.arity,
-                baked_perform_call=baked_perform_call)
-
-    def merge_with(self, other):
-        # Make a new 'merged' multimethod including the union of the two
-        # tables.  In case of conflict, pick the entry from 'self'.
-        if self.arity != other.arity:
-            return self      # XXX that's the case of '**'
-        operatorsymbol = '%s_merge_%s' % (self.name, other.name)
-        assert self.extras == other.extras
-        mm = StdObjSpaceMultiMethod(operatorsymbol, self.arity, **self.extras)
-        #
-        def merge(node1, node2):
-            assert type(node1) is type(node2)
-            if isinstance(node1, dict):
-                d = node1.copy()
-                d.update(node2)
-                for key in node1:
-                    if key in node2:
-                        d[key] = merge(node1[key], node2[key])
-                return d
-            else:
-                assert isinstance(node1, list)
-                assert node1
-                return node1     # pick the entry from 'self'
-        #
-        mm.dispatch_tree = merge(self.dispatch_tree, other.dispatch_tree)
-        return mm
-
-NOT_MULTIMETHODS = set(
-    ['delattr', 'delete', 'get', 'id', 'inplace_div', 'inplace_floordiv',
-     'inplace_lshift', 'inplace_mod', 'inplace_pow', 'inplace_rshift',
-     'inplace_truediv', 'is_', 'set', 'setattr', 'type', 'userdel',
-     'isinstance', 'issubtype', 'int', 'ord'])
-# XXX should we just remove those from the method table or we're happy
-#     with just not having multimethods?
-
-class MM:
-    """StdObjSpace multimethods"""
-
-    call    = StdObjSpaceMultiMethod('call', 1, ['__call__'],
-                                     general__args__=True)
-    init    = StdObjSpaceMultiMethod('__init__', 1, general__args__=True)
-    getnewargs = StdObjSpaceMultiMethod('__getnewargs__', 1)
-
-    # add all regular multimethods here
-    for _name, _symbol, _arity, _specialnames in ObjSpace.MethodTable:
-        if _name not in locals() and _name not in NOT_MULTIMETHODS:
-            mm = StdObjSpaceMultiMethod(_symbol, _arity, _specialnames)
-            locals()[_name] = mm
-            del mm
-
-    pow.extras['defaults'] = (None,)
diff --git a/pypy/objspace/std/multimethod.py b/pypy/objspace/std/multimethod.py
deleted file mode 100644
--- a/pypy/objspace/std/multimethod.py
+++ /dev/null
@@ -1,973 +0,0 @@
-
-from rpython.tool.sourcetools import compile2
-
-# This provide two compatible implementations of "multimethods".  A
-# multimethod is a callable object which chooses and calls a real
-# function from a table of pre-registered functions.  The choice depends
-# on the '__class__' of all arguments.  For example usages see
-# test_multimethod.
-
-# These multimethods support delegation: for each class A we must
-# provide a "typeorder", which is list of pairs (B, converter) where B
-# is a class and 'converter' is a function that can convert from an
-# instance of A to an instance of B.  If 'converter' is None it is
-# assumed that the instance needs no conversion.  The first entry in the
-# typeorder of a class A must almost always be (A, None).
-
-# A slightly non-standard feature of PyPy's multimethods is the way in
-# which they interact with normal subclassing.  Basically, they don't.
-# Suppose that A is a parent class of B.  Then a function registered for
-# an argument class A only accepts an instance whose __class__ is A, not
-# B.  To make it accept an instance of B, the typeorder for B must
-# contain (A, None).  An exception to this strict rule is if C is
-# another subclass of A which is not mentioned at all in the typeorder;
-# in this case C is considered to be equivalent to A.
-
-
-class FailedToImplement(Exception):
-    def __new__(cls, *args):
-        if cls is FailedToImplement:
-            assert not args, "use FailedToImplementArgs!"
-        return Exception.__new__(cls, *args)
-
-    def get_w_value(self, space):
-        return None
-
-    def get_w_type(self, space):
-        return None
-
-    def __str__(self):
-        return '<FailedToImplement(None, None)>'
-
-class FailedToImplementArgs(FailedToImplement):
-    def __init__(self, w_type=None, w_value=None):
-        self.w_type  = w_type
-        self.w_value = w_value
-
-    def get_w_value(self, space):
-        # convenience: same semantics as with OperationError
-        return self.w_value
-
-    def get_w_type(self, space):
-        return self.w_type
-
-    def __str__(self):
-        return '<FailedToImplement(%s, %s)>' % (self.w_type, self.w_value)
-
-
-
-def raiseFailedToImplement():
-    raise FailedToImplement
-
-
-class MultiMethodTable:
-
-    def __init__(self, arity, root_class, argnames_before=[], argnames_after=[]):
-        """NOT_RPYTHON: cannot create new multimethods dynamically.
-        MultiMethod-maker dispatching on exactly 'arity' arguments.
-        """
-        if arity < 1:
-            raise ValueError, "multimethods cannot dispatch on nothing"
-        self.arity = arity
-        self.root_class = root_class
-        self.dispatch_tree = {}
-        self.argnames_before = list(argnames_before)
-        self.argnames_after = list(argnames_after)
-
-    def register(self, function, *types, **kwds):
-        assert len(types) == self.arity
-        assert kwds.keys() == [] or kwds.keys() == ['order']
-        order = kwds.get('order', 0)
-        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,
-                base_typeorder=None, installercls=None):
-        "NOT_RPYTHON: initialization-time only"
-        assert len(list_of_typeorders) == self.arity
-        installercls = installercls or Installer
-        installer = installercls(self, prefix, list_of_typeorders,
-                                 baked_perform_call=baked_perform_call,
-                                 base_typeorder=base_typeorder)
-        return installer.install()
-
-    def install_if_not_empty(self, prefix, list_of_typeorders,
-                             base_typeorder=None, installercls=None):
-        "NOT_RPYTHON: initialization-time only"
-        assert len(list_of_typeorders) == self.arity
-        installercls = installercls or Installer
-        installer = installercls(self, prefix, list_of_typeorders,
-                                 base_typeorder=base_typeorder)
-        if installer.is_empty():
-            return None
-        else:
-            return installer.install()
-
-
-
-    # ____________________________________________________________
-    # limited dict-like interface to the dispatch table
-
-    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 has_signature(self, types):
-        try:
-            self.getfunctions(types)
-        except KeyError:
-            return False
-        else:
-            return True
-
-    def signatures(self):
-        """NOT_RPYTHON"""
-        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
-
-# ____________________________________________________________
-# Installer version 1
-
-class InstallerVersion1:
-    """NOT_RPYTHON"""
-
-    instance_counter = 0
-
-    mmfunccache = {}
-
-    prefix_memo = {}
-
-    def __init__(self, multimethod, prefix, list_of_typeorders,
-                 baked_perform_call=True, base_typeorder=None):
-        self.__class__.instance_counter += 1
-        self.multimethod = multimethod
-        # avoid prefix clashes, user code should supply different prefixes
-        # itself for nice names in tracebacks
-        base_prefix = prefix
-        n = 1
-        while prefix in self.prefix_memo:
-            n += 1
-            prefix = "%s%d" % (base_prefix, n)
-        self.prefix = prefix
-        self.prefix_memo[prefix] = 1
-        self.list_of_typeorders = list_of_typeorders
-        self.check_typeorders()
-        self.subtree_cache = {}
-        self.to_install = []
-        self.non_empty = self.build_tree([], multimethod.dispatch_tree)
-
-        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 check_typeorders(self):
-        # xxx we use a '__'-separated list of the '__name__' of the types
-        # in build_single_method(), so types with the same __name__ or
-        # with '__' in them would obscurely break this logic
-        for typeorder in self.list_of_typeorders:
-            for type in typeorder:
-                assert '__' not in type.__name__, (
-                    "avoid '__' in the name of %r" % (type,))
-            names = dict.fromkeys([type.__name__ for type in typeorder])
-            assert len(names) == len(typeorder), (
-                "duplicate type.__name__ in %r" % (typeorder,))
-
-    def is_empty(self):
-        return not self.non_empty
-
-    def install(self):
-        #f = open('LOGFILE', 'a')
-        #print >> f, '_'*60
-        #import pprint
-        #pprint.pprint(self.list_of_typeorders, f)
-
-        def class_key(cls):
-            "Returns an object such that class_key(subcls) > class_key(cls)."
-            return len(cls.__mro__)
-
-        # Sort 'to_install' so that base classes come first, which is
-        # necessary for the 'parentfunc' logic in the loop below to work.
-        # Moreover, 'to_install' can contain two functions with the same
-        # name for the root class: the default fallback one and the real
-        # one.  So we have to sort the real one just after the default one
-        # so that the default one gets overridden.
-        def key(target, funcname, func, source, fallback):
-            if target is None:
-                return ()
-            return (class_key(target), not fallback)
-        self.to_install.sort(lambda a, b: cmp(key(*a), key(*b)))
-
-        for target, funcname, func, source, fallback in self.to_install:
-            if target is not None:
-                # If the parent class provides a method of the same
-                # name which is actually the same 'func', we don't need
-                # to install it again.  Useful with fallback functions.
-                parentfunc = getattr(target, funcname, None)
-                parentfunc = getattr(parentfunc, 'im_func', None)
-                if parentfunc is func:
-                    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))
-
-        funcname = intern(funcname)
-        self.build_function(next_type, funcname, len(types_so_far),
-                            things_to_call)
-        return bool(things_to_call)
-
-    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, '__name__': __name__}
-        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
-                convert_callargs = (self.multimethod.argnames_before +
-                                    [callargs[to_convert]])
-                callargs[to_convert] = '%s(%s)' % (
-                    invent_name(conversion), ', '.join(convert_callargs))
-            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
-            # NB. make sure that there is only one fallback function object,
-            # i.e. the key used in the mmfunccache below is always the same
-            # for all functions with the same name and an empty bodylines.
-
-        # 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']
-
-        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)
-
-        # XXX find a better place (or way) to avoid duplicate functions
-        l = miniglobals.items()
-        l.sort()
-        l = tuple(l)
-        key = (source, l)
-        try:
-            func = self.mmfunccache[key]
-        except KeyError:
-            exec compile2(source) in miniglobals
-            func = miniglobals[funcname]
-            self.mmfunccache[key] = func
-        #else:
-        #    print "avoided duplicate function", func
-        self.to_install.append((target, funcname, func, source, fallback))
-        return func
-
-# ____________________________________________________________
-# Installer version 2
-
-class MMDispatcher(object):
-    """NOT_RPYTHON
-    Explicit dispatcher class.  The __call__ and dispatch() methods
-    are only present for documentation purposes.  The InstallerVersion2
-    uses the expressions() method to precompute fast RPython-friendly
-    dispatch tables.
-    """
-    _revcache = None
-
-    def __init__(self, multimethod, list_of_typeorders):
-        self.multimethod = multimethod
-        self.list_of_typeorders = list_of_typeorders
-
-    def __call__(self, *args):
-        # for testing only: this is slow
-        i = len(self.multimethod.argnames_before)
-        j = i + self.multimethod.arity
-        k = j + len(self.multimethod.argnames_after)
-        assert len(args) == k
-        prefixargs = args[:i]
-        dispatchargs = args[i:j]
-        suffixargs = args[j:]
-        return self.dispatch([x.__class__ for x in dispatchargs],
-                             prefixargs,
-                             dispatchargs,
-                             suffixargs)
-
-    def dispatch(self, argtypes, prefixargs, args, suffixargs):
-        # for testing only: this is slow
-        def expr(v):
-            if isinstance(v, Call):
-                return v.function(*[expr(w) for w in v.arguments])
-            else:
-                return v
-        # XXX this is incomplete: for each type in argtypes but not
-        # in the typeorder, we should look for the first base class
-        # that is in the typeorder.
-        e = None
-        for v in self.expressions(argtypes, prefixargs, args, suffixargs):
-            try:
-                return expr(v)
-            except FailedToImplement, e:
-                pass
-        else:
-            raise e or FailedToImplement()
-
-    def expressions(self, argtypes, prefixargs, args, suffixargs):
-        """Lists the possible expressions that call the appropriate
-        function for the given argument types.  Each expression is a Call
-        object.  The intent is that at run-time the first Call that doesn't
-        cause FailedToImplement to be raised is the good one.
-        """
-        prefixargs = tuple(prefixargs)
-        suffixargs = tuple(suffixargs)
-
-        def walktree(node, args_so_far):
-            if isinstance(node, list):
-                for func in node:
-                    if func is not None:
-                        result.append(Call(func, prefixargs +
-                                                 args_so_far +
-                                                 suffixargs))
-            else:
-                index = len(args_so_far)
-                typeorder = self.list_of_typeorders[index]
-                next_type = argtypes[index]
-                for target_type, converter in typeorder[next_type]:
-                    if target_type not in node:
-                        continue
-                    next_arg = args[index]
-                    if converter:
-                        next_arg = Call(converter, prefixargs + (next_arg,))
-                    walktree(node[target_type], args_so_far + (next_arg,))
-
-        result = []
-        walktree(self.multimethod.dispatch_tree, ())
-        return result
-
-    def anychance(self, typesprefix):
-        # is there any chance that a list of types starting with typesprefix
-        # could lead to a successful dispatch?
-        # (START-UP TIME OPTIMIZATION ONLY)
-        if self._revcache is None:
-
-            def build_tree(types_so_far, dispatch_node):
-                non_empty = False
-                typeorder = self.list_of_typeorders[len(types_so_far)]
-                for next_type in typeorder:
-                    if build_single_method(typeorder, types_so_far, next_type,
-                                           dispatch_node):
-                        non_empty = True
-                if non_empty:
-                    self._revcache[types_so_far] = True
-                return non_empty
-
-            def build_single_method(typeorder, types_so_far, next_type,
-                                    dispatch_node):
-                order = typeorder[next_type]
-                things_to_call = False
-                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 build_tree(types_so_far+(next_type,), match):
-                            things_to_call = True
-                    elif match:
-                        things_to_call = True
-                return things_to_call
-
-            self._revcache = {}
-            build_tree((), self.multimethod.dispatch_tree)
-        return tuple(typesprefix) in self._revcache
-
-
-class Call(object):
-    """ Represents a call expression.
-    The arguments may themselves be Call objects.
-    """
-    def __init__(self, function, arguments):
-        self.function = function
-        self.arguments = arguments
-
-
-class CompressedArray(object):
-    def __init__(self, null_value):
-        self.null_value = null_value
-        self.items = [null_value]
-
-    def ensure_length(self, newlen):
-        if newlen > len(self.items):
-            self.items.extend([self.null_value] * (newlen - len(self.items)))
-
-    def insert_subarray(self, array):
-        # insert the given array of numbers into the indexlist,
-        # allowing null values to become non-null
-        if array.count(self.null_value) == len(array):
-            return 0
-        test = 1
-        while True:
-            self.ensure_length(test+len(array))
-            for i in xrange(len(array)):
-                if not (array[i] == self.items[test+i] or
-                        array[i] == self.null_value or
-                        self.items[test+i] == self.null_value):
-                    break
-            else:
-                # success
-                for i in range(len(array)):
-                    if array[i] != self.null_value:
-                        self.items[test+i] = array[i]
-                return test
-            test += 1
-
-    def _freeze_(self):
-        return True
-
-
-class MRDTable(object):
-    # Multi-Method Dispatch Using Multiple Row Displacement,
-    # Candy Pang, Wade Holst, Yuri Leontiev, and Duane Szafron
-    # University of Alberta, Edmonton AB T6G 2H1 Canada
-    # can be found on http://web.cs.ualberta.ca/~yuri/publ.htm
-
-    Counter = 0
-
-    def __init__(self, list_of_types):
-        self.id = MRDTable.Counter
-        MRDTable.Counter += 1
-        self.list_of_types = list_of_types
-        self.typenum = dict(zip(list_of_types, range(len(list_of_types))))
-        self.attrname = '__mrd%d_typenum' % self.id
-        for t1, num in self.typenum.items():
-            setattr(t1, self.attrname, num)
-        self.indexarray = CompressedArray(0)
-
-    def get_typenum(self, cls):
-        return self.typenum[cls]
-
-    def is_anti_range(self, typenums):
-        # NB. typenums should be sorted.  Returns (a, b) if typenums contains
-        # at least half of all typenums and its complement is range(a, b).
-        # Returns (None, None) otherwise.  Returns (0, 0) if typenums contains
-        # everything.
-        n = len(self.list_of_types)
-        if len(typenums) <= n // 2:
-            return (None, None)
-        typenums = dict.fromkeys(typenums)
-        complement = [typenum for typenum in range(n)
-                              if typenum not in typenums]
-        if not complement:
-            return (0, 0)
-        a = min(complement)
-        b = max(complement) + 1
-        if complement == range(a, b):
-            return (a, b)
-        else:
-            return (None, None)
-
-    def normalize_length(self, next_array):
-        # make sure that the indexarray is not smaller than any funcarray
-        self.indexarray.ensure_length(len(next_array.items))
-
-
-def invent_name(miniglobals, 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
-
-
-class FuncEntry(object):
-
-    def __init__(self, bodylines, miniglobals, fallback):
-        self.body = '\n    '.join(bodylines)
-        self.miniglobals = miniglobals
-        self.fallback = fallback
-        self.possiblenames = []
-        self.typetree = {}
-        self._function = None
-
-    def key(self):
-        lst = self.miniglobals.items()
-        lst.sort()
-        return self.body, tuple(lst)
-
-    def get_function_name(self):
-        # pick a name consistently based on self.possiblenames
-        length = min([len(parts) for parts in self.possiblenames])
-        result = []
-        for i in range(length):
-            choices = {}
-            for parts in self.possiblenames:
-                choices[parts[i]] = True
-            parts = choices.keys()
-            res = str(len(parts))
-            for part in parts:
-                if type(part) is str:     # there is a string at this pos
-                    if '0_fail' in choices:
-                        res = '0_fail'
-                    elif len(parts) == 1:
-                        res = part
-                    break
-            else:
-                # only types at this location, try to find a common base
-                basecls = parts[0]
-                for cls in parts[1:]:
-                    if issubclass(basecls, cls):
-                        basecls = cls
-                for cls in parts[1:]:
-                    if not issubclass(cls, basecls):
-                        break   # no common base
-                else:
-                    res = basecls.__name__
-            result.append(res)
-        return '_'.join(result)
-
-    def make_function(self, fnargs, nbargs_before, mrdtable):
-        if self._function is not None:
-            return self._function
-        name = self.get_function_name()
-        self.compress_typechecks(mrdtable)
-        checklines = self.generate_typechecks(mrdtable, fnargs[nbargs_before:])
-        if not checklines:
-            body = self.body
-        else:
-            checklines.append(self.body)
-            body = '\n    '.join(checklines)
-        source = 'def %s(%s):\n    %s\n' % (name, ', '.join(fnargs), body)
-        self.debug_dump(source)
-        exec compile2(source) in self.miniglobals
-        self._function = self.miniglobals[name]
-        return self._function
-
-    def debug_dump(self, source):
-        if 0:    # for debugging the generated mm sources
-            name = self.get_function_name()
-            f = open('/tmp/mm-source/%s' % name, 'a')
-            for possiblename in self.possiblenames:
-                print >> f, '#',
-                for part in possiblename:
-                    print >> f, getattr(part, '__name__', part),
-                print >> f
-            print >> f
-            print >> f, source
-            f.close()
-
-    def register_valid_types(self, types):
-        node = self.typetree
-        for t1 in types[:-1]:
-            if node is True:
-                return
-            node = node.setdefault(t1, {})
-        if node is True:
-            return
-        node[types[-1]] = True
-
-    def no_typecheck(self):
-        self.typetree = True
-
-    def compress_typechecks(self, mrdtable):
-        def full(node):
-            if node is True:
-                return 1
-            fulls = 0
-            for key, subnode in node.items():
-                if full(subnode):
-                    node[key] = True
-                    fulls += 1
-            if fulls == types_total:
-                return 1
-            return 0
-
-        types_total = len(mrdtable.list_of_types)
-        if full(self.typetree):
-            self.typetree = True
-
-    def generate_typechecks(self, mrdtable, args):
-        attrname = mrdtable.attrname
-        possibletypes = [{} for _ in args]
-        any_type_is_ok = [False for _ in args]
-
-        def generate(node, level=0):
-            # this generates type-checking code like the following:
-            #
-            #     _argtypenum = arg1.__typenum
-            #     if _argtypenum == 5:
-            #         ...
-            #     elif _argtypenum == 6 or _argtypenum == 8:
-            #         ...
-            #     else:
-            #         _failedtoimplement = True
-            #
-            # or, in the common particular case of an "anti-range", we optimize it to:
-            #
-            #     _argtypenum = arg1.__typenum
-            #     if _argtypenum < 5 or _argtypenum >= 10:
-            #         ...
-            #     else:
-            #         _failedtoimplement = True
-            #
-            result = []
-            indent = '    '*level
-            if node is True:
-                for i in range(level, len(args)):
-                    any_type_is_ok[i] = True
-                result.append('%s_failedtoimplement = False' % (indent,))
-                return result
-            if not node:
-                result.append('%s_failedtoimplement = True' % (indent,))
-                return result
-            result.append('%s_argtypenum = %s.%s' % (indent, args[level],
-                                                     attrname))
-            cases = {}
-            for key, subnode in node.items():
-                possibletypes[level][key] = True
-                casebody = tuple(generate(subnode, level+1))
-                typenum = mrdtable.get_typenum(key)
-                cases.setdefault(casebody, []).append(typenum)
-            for casebody, typenums in cases.items():
-                typenums.sort()
-            cases = [(typenums, casebody)
-                     for (casebody, typenums) in cases.items()]
-            cases.sort()
-            if len(cases) == 1:
-                typenums, casebody = cases[0]
-                a, b = mrdtable.is_anti_range(typenums)
-            else:
-                a, b = None, None
-            keyword = 'if'
-            for typenums, casebody in cases:
-                if a is not None:
-                    if b - a == 1:
-                        condition = '_argtypenum != %d' % a
-                    elif b == a:
-                        condition = 'True'
-                    else:
-                        condition = '_argtypenum < %d or _argtypenum >= %d' % (
-                            a, b)
-                else:
-                    conditions = ['_argtypenum == %d' % typenum
-                                  for typenum in typenums]
-                    condition = ' or '.join(conditions)
-                result.append('%s%s %s:' % (indent, keyword, condition))
-                result.extend(casebody)
-                keyword = 'elif'
-            result.append('%selse:' % (indent,))
-            result.append('%s    _failedtoimplement = True' % (indent,))
-            return result
-
-        result = []
-        if self.typetree is not True:
-            result.extend(generate(self.typetree))
-            result.append('if _failedtoimplement:')
-            result.append('    raise FailedToImplement')
-            for level in range(len(args)):
-                if not any_type_is_ok[level]:
-                    cls = commonbase(possibletypes[level].keys())
-                    clsname = invent_name(self.miniglobals, cls)
-                    result.append('assert isinstance(%s, %s)' % (args[level],
-                                                                 clsname))
-        return result
-
-
-def commonbase(classlist):
-    def baseclasses(cls):
-        result = set([cls])
-        for base in cls.__bases__:
-            if '_mixin_' not in base.__dict__:
-                result |= baseclasses(base)
-        return result
-
-    bag = baseclasses(classlist[0])
-    for cls in classlist[1:]:
-        bag &= baseclasses(cls)
-    _, candidate = max([(len(cls.__mro__), cls) for cls in bag])
-    for cls in bag:
-        assert issubclass(candidate, cls)
-    return candidate
-
-
-class InstallerVersion2(object):
-    """NOT_RPYTHON"""
-
-    instance_counter = 0
-    mrdtables = {}
-
-    def __init__(self, multimethod, prefix, list_of_typeorders,
-                 baked_perform_call=True, base_typeorder=None):
-        #print 'InstallerVersion2:', prefix
-        self.__class__.instance_counter += 1
-        self.multimethod = multimethod
-        self.prefix = prefix
-        self.list_of_typeorders = list_of_typeorders
-        self.baked_perform_call = baked_perform_call
-        self.mmfunccache = {}
-        args = ['arg%d' % i for i in range(multimethod.arity)]
-        self.fnargs = (multimethod.argnames_before + args +
-                       multimethod.argnames_after)
-
-        # compute the complete table
-        base_typeorder = base_typeorder or list_of_typeorders[0]
-        for typeorder in list_of_typeorders:
-            for t1 in typeorder:
-                assert t1 in base_typeorder
-
-        lst = list(base_typeorder)
-        def clskey(cls):
-            return cls.__mro__[::-1]
-        lst.sort(lambda cls1, cls2: cmp(clskey(cls1), clskey(cls2)))
-        key = tuple(lst)
-        try:
-            self.mrdtable = self.mrdtables[key]
-        except KeyError:
-            self.mrdtable = self.mrdtables[key] = MRDTable(key)
-
-        dispatcher = MMDispatcher(multimethod, list_of_typeorders)
-        self.table = {}
-        def buildtable(prefixtypes):
-            if len(prefixtypes) == multimethod.arity:
-                calllist = dispatcher.expressions(prefixtypes,
-                                                  multimethod.argnames_before,
-                                                  args,
-                                                  multimethod.argnames_after)
-                if calllist:
-                    self.table[prefixtypes] = calllist
-            elif dispatcher.anychance(prefixtypes):
-                typeorder = list_of_typeorders[len(prefixtypes)]
-                for t1 in typeorder:
-                    buildtable(prefixtypes + (t1,))
-        buildtable(())
-        self.dispatcher = dispatcher
-
-    def is_empty(self):
-        return len(self.table) == 0
-
-    def install(self):
-        nskip = len(self.multimethod.argnames_before)
-        null_entry = self.build_funcentry([self.prefix, '0_fail'], [])
-        null_entry.no_typecheck()
-        if self.is_empty():
-            return self.answer(null_entry)
-
-        entryarray = CompressedArray(null_entry)
-        indexarray = self.mrdtable.indexarray
-        lst = self.mrdtable.list_of_types
-        indexline = []
-
-        def compress(typesprefix, typesnum):
-            if len(typesprefix) == self.multimethod.arity:
-                calllist = self.table.get(typesprefix, [])
-                funcname = [self.prefix]
-                funcname.extend(typesprefix)
-                entry = self.build_funcentry(funcname, calllist)
-                entry.register_valid_types(typesprefix)
-                return entry
-            elif self.dispatcher.anychance(typesprefix):
-                flatline = []
-                for num1, t1 in enumerate(lst):
-                    item = compress(typesprefix + (t1,), typesnum + (num1,))
-                    flatline.append(item)
-                if len(typesprefix) == self.multimethod.arity - 1:
-                    array = entryarray
-                else:
-                    array = indexarray
-                return array.insert_subarray(flatline)
-            else:
-                return 0
-
-        master_index = compress((), ())
-
-        null_func = null_entry.make_function(self.fnargs, nskip, self.mrdtable)
-        funcarray = CompressedArray(null_func)
-        # round up the length to a power of 2
-        N = 1
-        while N < len(entryarray.items):
-            N *= 2
-        funcarray.ensure_length(N)
-        for i, entry in enumerate(entryarray.items):
-            func = entry.make_function(self.fnargs, nskip, self.mrdtable)
-            funcarray.items[i] = func
-        self.mrdtable.normalize_length(funcarray)
-
-        #print master_index
-        #print indexarray.items
-        #print funcarray.items
-
-        attrname = self.mrdtable.attrname
-        exprfn = "%d" % master_index
-        for n in range(self.multimethod.arity-1):
-            exprfn = "indexarray.items[%s + arg%d.%s]" % (exprfn, n, attrname)
-        n = self.multimethod.arity-1
-        exprfn = "funcarray.items[(%s + arg%d.%s) & mmmask]" % (exprfn, n,
-                                                                attrname)
-        expr = Call(exprfn, self.fnargs)
-        entry = self.build_funcentry([self.prefix, '0_perform_call'],
-                                     [expr],
-                                     indexarray = indexarray,
-                                     funcarray = funcarray,
-                                     mmmask = N-1)
-        entry.no_typecheck()
-        return self.answer(entry)
-
-    def answer(self, entry):
-        if self.baked_perform_call:
-            nskip = len(self.multimethod.argnames_before)
-            return entry.make_function(self.fnargs, nskip, self.mrdtable)
-        else:
-            assert entry.body.startswith('return ')
-            expr = entry.body[len('return '):]
-            entry.debug_dump(entry.body)
-            return self.fnargs, expr, entry.miniglobals, entry.fallback
-
-    def build_funcentry(self, funcnameparts, calllist, **extranames):
-        def expr(v):
-            if isinstance(v, Call):
-                return '%s(%s)' % (invent_name(miniglobals, v.function),
-                                   ', '.join([expr(w) for w in v.arguments]))
-            else:
-                return v
-
-        fallback = len(calllist) == 0
-        if fallback:
-            miniglobals = {'raiseFailedToImplement': raiseFailedToImplement}
-            bodylines = ['return raiseFailedToImplement()']
-        else:
-            miniglobals = {'FailedToImplement': FailedToImplement}
-            miniglobals.update(extranames)
-            bodylines = []
-            for v in calllist[:-1]:
-                bodylines.append('try:')
-                bodylines.append('    return %s' % expr(v))
-                bodylines.append('except FailedToImplement:')
-                bodylines.append('    pass')
-            bodylines.append('return %s' % expr(calllist[-1]))
-
-        miniglobals['__name__'] = __name__
-        entry = FuncEntry(bodylines, miniglobals, fallback)
-        key = entry.key()
-
-        try:
-            entry = self.mmfunccache[key]
-        except KeyError:
-            self.mmfunccache[key] = entry
-        entry.possiblenames.append(funcnameparts)
-        return entry
-
-# ____________________________________________________________
-# Selection of the version to use
-
-Installer = InstallerVersion1   # modified by translate.py targetpypystandalone
diff --git a/pypy/objspace/std/objspace.py b/pypy/objspace/std/objspace.py
--- a/pypy/objspace/std/objspace.py
+++ b/pypy/objspace/std/objspace.py
@@ -52,8 +52,6 @@
 
         self.UnicodeObjectCls = W_UnicodeObject
 
-        self._install_multimethods()
-
         # singletons
         self.w_None = W_NoneObject.w_None
         self.w_False = W_BoolObject.w_False
@@ -87,39 +85,6 @@
     def get_builtin_types(self):
         return self.builtin_types
 
-    def _install_multimethods(self):
-        """Install all the MultiMethods into the space instance."""
-        for name, mm in model.MM.__dict__.items():
-            if not isinstance(mm, model.StdObjSpaceMultiMethod):
-                continue
-            if not hasattr(self, name):
-                # int_w, str_w...: these do not return a wrapped object
-                if name.endswith('_w'):
-                    func = mm.install_not_sliced(self.model.typeorder,
-                                                 baked_perform_call=True)
-                else:
-                    unsliced = mm.install_not_sliced(self.model.typeorder,
-                                                     baked_perform_call=False)
-                    exprargs, expr, miniglobals, fallback = unsliced
-                    func = stdtypedef.make_perform_trampoline('__mm_'+name,
-                                                              exprargs, expr,
-                                                              miniglobals, mm)
-
-                boundmethod = types.MethodType(func, self, self.__class__)
-                setattr(self, name, boundmethod)  # store into 'space' instance
-            elif self.config.objspace.std.builtinshortcut:
-                if name.startswith('inplace_'):
-                    fallback_name = name[len('inplace_'):]
-                    if fallback_name in ('or', 'and'):
-                        fallback_name += '_'
-                    fallback_mm = model.MM.__dict__[fallback_name]
-                else:
-                    fallback_mm = None
-                builtinshortcut.install(self, mm, fallback_mm)
-        if self.config.objspace.std.builtinshortcut:
-            builtinshortcut.install_is_true(self, model.MM.nonzero,
-                                            model.MM.len)
-
     def createexecutioncontext(self):
         # add space specific fields to execution context
         # note that this method must not call space methods that might need an
diff --git a/pypy/objspace/std/stdtypedef.py b/pypy/objspace/std/stdtypedef.py
--- a/pypy/objspace/std/stdtypedef.py
+++ b/pypy/objspace/std/stdtypedef.py
@@ -1,14 +1,9 @@
-from pypy.interpreter import gateway, baseobjspace, argument
-from pypy.interpreter.error import OperationError, oefmt
+from pypy.interpreter import baseobjspace
 from pypy.interpreter.typedef import TypeDef, GetSetProperty, Member
 from pypy.interpreter.typedef import descr_get_dict, descr_set_dict
 from pypy.interpreter.typedef import descr_del_dict
 from pypy.interpreter.baseobjspace import SpaceCache
-from pypy.objspace.std import model
-from pypy.objspace.std.model import StdObjSpaceMultiMethod
-from pypy.objspace.std.multimethod import FailedToImplement
 from rpython.rlib import jit
-from rpython.tool.sourcetools import compile2
 
 __all__ = ['StdTypeDef']
 
@@ -19,11 +14,6 @@
         "NOT_RPYTHON: initialization-time only."
         TypeDef.__init__(self, __name, __base, **rawdict)
         self.any = type("W_Any"+__name.title(), (baseobjspace.W_Root,), {'typedef': self})
-        self.local_multimethods = []
-
-    def registermethods(self, namespace):
-        "NOT_RPYTHON: initialization-time only."
-        self.local_multimethods += hack_out_multimethods(namespace)
 
 @jit.unroll_safe
 def issubtypedef(a, b):
@@ -61,17 +51,6 @@
         rawdict = typedef.rawdict
         lazyloaders = {}
 
-        if isinstance(typedef, StdTypeDef):
-            # get all the sliced multimethods
-            multimethods = slicemultimethods(space, typedef)
-            for name, loader in multimethods.items():
-                if name in rawdict:
-                    # the name specified in the rawdict has priority
-                    continue
-                assert name not in lazyloaders, (
-                    'name clash: %s in %s.lazyloaders' % (name, typedef.name))
-                lazyloaders[name] = loader
-
         # compute the bases
         if typedef is W_ObjectObject.typedef:
             bases_w = []
@@ -97,190 +76,3 @@
 
     def ready(self, w_type):
         w_type.ready()
-
-def hack_out_multimethods(ns):
-    "NOT_RPYTHON: initialization-time only."
-    result = []
-    seen = {}
-    for value in ns.itervalues():
-        if isinstance(value, StdObjSpaceMultiMethod):
-            if value.name in seen:
-                raise Exception("duplicate multimethod name %r" %
-                                (value.name,))
-            seen[value.name] = True
-            result.append(value)
-    return result
-
-def is_relevant_for_slice(target_type, typedef):
-    targettypedef = getattr(target_type, 'typedef', None)
-    if targettypedef == typedef:
-        return True
-    method = getattr(target_type, "is_implementation_for", lambda t: False)
-    return method(typedef)
-
-def sliced_typeorders(typeorder, multimethod, typedef, i, local=False):
-    """NOT_RPYTHON"""
-    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:
-                    if is_relevant_for_slice(target_type, 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 _gettypeerrormsg(nbargs):
-    if nbargs > 1:
-        plural = 's'
-    else:
-        plural = ''
-    return "unsupported operand type%s for %%s: %s" % (
-        plural, ', '.join(["'%T'"] * nbargs))
-_gettypeerrormsg._annspecialcase_ = 'specialize:memo'
-
-def gettypeerror(space, operatorsymbol, *args_w):
-    return oefmt(space.w_TypeError, _gettypeerrormsg(len(args_w)),
-                 operatorsymbol, *args_w)
-
-def make_perform_trampoline(prefix, exprargs, expr, miniglobals,  multimethod, selfindex=0,
-                            allow_NotImplemented_results=False):
-    """NOT_RPYTHON"""    
-    # 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('keywords', False):
-        raise Exception, "no longer supported, use __args__"
-    if multimethod.extras.get('general__args__', False):
-        wrapper_arglist.append('__args__')
-    wrapper_arglist += multimethod.extras.get('extra_args', ())
-
-    miniglobals.update({ 'OperationError': OperationError,
-                         'gettypeerror': gettypeerror})
-    
-    app_defaults = multimethod.extras.get('defaults', ())
-    i = len(argnames) - len(app_defaults)
-    wrapper_signature = wrapper_arglist[:]
-    unwrap_spec_kwds = {}
-    for app_default in app_defaults:
-        name = wrapper_signature[i]
-        unwrap_spec_kwds[name] = gateway.WrappedDefault(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 or
-                                         multimethod.name.startswith('inplace_')):
-        # turn FailedToImplement into NotImplemented
-        code = """def %s_perform_call(space, %s):
-                      %s
-                      try:
-                          return %s
-                      except FailedToImplement, e:
-                          if e.get_w_type(space) is not None:
-                              raise OperationError(e.w_type, e.get_w_value(space))
-                          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.get_w_type(space) is not None:
-                              raise OperationError(e.w_type, e.get_w_value(space))
-                          else:
-                              raise gettypeerror(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 compile2(code, '', 'exec') in miniglobals 
-    func = miniglobals["%s_perform_call" % prefix]
-    if unwrap_spec_kwds:
-        func = gateway.unwrap_spec(**unwrap_spec_kwds)(func)
-    return func
-
-def wrap_trampoline_in_gateway(func, methname, multimethod):
-    """NOT_RPYTHON"""
-    if 'doc' in multimethod.extras:
-        func.__doc__ = multimethod.extras['doc']
-    return gateway.interp2app(func, app_name=methname)
-
-def slicemultimethod(space, multimethod, typedef, result, local=False):
-    """NOT_RPYTHON"""    
-    for i in range(len(multimethod.specialnames)):
-        methname = multimethod.specialnames[i]
-        if methname in result:
-            # conflict between e.g. __lt__ and
-            # __lt__-as-reversed-version-of-__gt__
-            loader = result[methname]
-            if loader.bound_position < i:
-                continue
-
-        def multimethod_loader(i=i, methname=methname):
-            """NOT_RPYTHON"""
-            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,
-                                                                        base_typeorder=space.model.typeorder)
-            if fallback:
-                return None   # 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)
-            return space.wrap(gw)
-
-        multimethod_loader.bound_position = i   # for the check above
-        result[methname] = multimethod_loader
-
-def slicemultimethods(space, typedef):
-    """NOT_RPYTHON"""
-    result = {}
-    # import and slice all multimethods of the MM container
-    for multimethod in hack_out_multimethods(model.MM.__dict__):
-        slicemultimethod(space, multimethod, typedef, result)
-    # import all multimethods defined directly on the type without slicing
-    for multimethod in typedef.local_multimethods:
-        slicemultimethod(space, multimethod, typedef, result, local=True)
-    return result
-
-def multimethods_defined_on(cls):
-    """NOT_RPYTHON: enumerate the (multimethod, local_flag) for all the
-    multimethods that have an implementation whose first typed argument
-    is 'cls'.
-    """
-    typedef = cls.typedef
-    for multimethod in hack_out_multimethods(model.MM.__dict__):
-        if cls in multimethod.dispatch_tree:
-            yield multimethod, False
-    for multimethod in typedef.local_multimethods:
-        yield multimethod, True
diff --git a/pypy/objspace/std/test/test_annmm.py b/pypy/objspace/std/test/test_annmm.py
deleted file mode 100644
--- a/pypy/objspace/std/test/test_annmm.py
+++ /dev/null
@@ -1,56 +0,0 @@
-from pypy.objspace.std.multimethod import *
-from rpython.annotator.annrpython import RPythonAnnotator
-
-class W_Root(object):
-    pass
-
-class W_Int(W_Root):
-    pass
-
-class W_Str(W_Root):
-    pass
-
-
-str_w = MultiMethodTable(1, root_class=W_Root, argnames_before=['space'])
-int_w = MultiMethodTable(1, root_class=W_Root, argnames_before=['space'])
-
-
-def int_w__Int(space, w_x):
-    assert space == 'space'
-    assert isinstance(w_x, W_Int)
-    return 1
-
-def str_w__Str(space, w_x):
-    assert space == 'space'
-    assert isinstance(w_x, W_Str)
-    return "string"
-
-int_w.register(int_w__Int, W_Int)
-str_w.register(str_w__Str, W_Str)
-
-
-def setup_module(mod):
-    typeorder = {
-        W_Int: [(W_Int, None)],
-        W_Str: [(W_Str, None)],
-        }
-    mod.typeorder = typeorder
-    mod.str_w1 = str_w.install('__str_w', [typeorder])
-    mod.int_w1 = int_w.install('__int_w', [typeorder])
-
-
-def test_str_w_ann():
-    a = RPythonAnnotator()
-    s1 = a.build_types(str_w1,[str, W_Str])
-    s2 = a.build_types(str_w1,[str, W_Root])
-    assert s1.knowntype == str
-    assert s2.knowntype == str
-    
-def test_int_w_ann():
-    a = RPythonAnnotator()
-    s1 = a.build_types(int_w1,[str, W_Int])
-    s2 = a.build_types(int_w1,[str, W_Str])
-    assert s1.knowntype == int
-    assert s2.knowntype == int
-    
-    
diff --git a/pypy/objspace/std/test/test_builtinshortcut.py b/pypy/objspace/std/test/test_builtinshortcut.py
--- a/pypy/objspace/std/test/test_builtinshortcut.py
+++ b/pypy/objspace/std/test/test_builtinshortcut.py
@@ -7,9 +7,6 @@
 class AppTestUserObject(test_userobject.AppTestUserObject):
     spaceconfig = WITH_BUILTINSHORTCUT
 
-class AppTestWithMultiMethodVersion2(test_userobject.AppTestWithMultiMethodVersion2):
-    spaceconfig = WITH_BUILTINSHORTCUT
-
 class AppTestBug:
     spaceconfig = WITH_BUILTINSHORTCUT
 
diff --git a/pypy/objspace/std/test/test_complexobject.py b/pypy/objspace/std/test/test_complexobject.py
--- a/pypy/objspace/std/test/test_complexobject.py
+++ b/pypy/objspace/std/test/test_complexobject.py
@@ -1,6 +1,5 @@
 import py
 from pypy.objspace.std.complexobject import W_ComplexObject, _split_complex
-from pypy.objspace.std.multimethod import FailedToImplement
 from pypy.objspace.std import StdObjSpace
 
 EPS = 1e-9
diff --git a/pypy/objspace/std/test/test_intobject.py b/pypy/objspace/std/test/test_intobject.py
--- a/pypy/objspace/std/test/test_intobject.py
+++ b/pypy/objspace/std/test/test_intobject.py
@@ -2,7 +2,6 @@
 import py
 import sys
 from pypy.objspace.std import intobject as iobj
-from pypy.objspace.std.multimethod import FailedToImplement
 from rpython.rlib.rarithmetic import r_uint, is_valid_int
 from rpython.rlib.rbigint import rbigint
 
diff --git a/pypy/objspace/std/test/test_multimethod.py b/pypy/objspace/std/test/test_multimethod.py
deleted file mode 100644
--- a/pypy/objspace/std/test/test_multimethod.py
+++ /dev/null
@@ -1,264 +0,0 @@
-from py.test import raises
-
-from pypy.objspace.std import multimethod
-from pypy.objspace.std.multimethod import FailedToImplement
-from pypy.objspace.std.multimethod import FailedToImplementArgs
-
-
-class W_Root(object):
-    pass
-
-class W_IntObject(W_Root):
-    pass
-
-class W_BoolObject(W_Root):
-    pass
-
-class W_StringObject(W_Root):
-    pass
-
-def delegate_b2i(space, w_x):
-    assert isinstance(w_x, W_BoolObject)
-    return W_IntObject()
-
-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'
-
-
-def test_failedtoimplement():
-    f = FailedToImplement()
-    assert f.get_w_type("space") is None
-    assert f.get_w_value("space") is None
-    f = FailedToImplementArgs("ab", "cd")
-    assert f.get_w_type("space") == "ab"
-    assert f.get_w_value("space") == "cd"
-    # for testing it's good to get the following behavior:
-    raises(AssertionError, FailedToImplement, "ab", "cd")
-    # but the class FailedToImplement should have no __init__ for translation:
-    assert '__init__' not in FailedToImplement.__dict__
-
-
-class TestMultiMethod1:
-    Installer = multimethod.InstallerVersion1
-
-    def setup_class(cls):
-        cls.prev_installer = multimethod.Installer
-        multimethod.Installer = cls.Installer
-        add = multimethod.MultiMethodTable(2, root_class=W_Root,
-                                           argnames_before=['space'])
-        add.register(add__Int_Int, W_IntObject, W_IntObject)
-        typeorder = {
-            W_IntObject: [(W_IntObject, None), (W_Root, None)],
-            W_BoolObject: [(W_BoolObject, None), (W_IntObject, delegate_b2i),
-                           (W_Root, None)],
-            W_StringObject: [(W_StringObject, None), (W_Root, None)],
-            }
-        cls.typeorder = typeorder
-        cls.add = add
-        cls.add1 = staticmethod(add.install('__add', [typeorder, typeorder]))
-
-    def teardown_class(cls):
-        multimethod.Installer = cls.prev_installer
-
-    def test_simple(self):
-        space = 'space'
-        w_x = W_IntObject()
-        w_y = W_IntObject()
-        assert self.add1(space, w_x, w_y) == 'fine'
-
-    def test_failtoimplement(self):
-        space = 'space'
-        w_x = W_IntObject()
-        w_s = W_StringObject()
-        raises(FailedToImplement, "self.add1(space, w_x, w_s)")
-        raises(FailedToImplement, "self.add1(space, w_s, w_x)")
-
-    def test_delegate(self):
-        space = 'space'
-        w_x = W_IntObject()
-        w_s = W_StringObject()
-        w_b = W_BoolObject()
-        assert self.add1(space, w_x, w_b) == 'fine'
-        assert self.add1(space, w_b, w_x) == 'fine'
-        assert self.add1(space, w_b, w_b) == 'fine'
-        raises(FailedToImplement, "self.add1(space, w_b, w_s)")
-        raises(FailedToImplement, "self.add1(space, w_s, w_b)")
-
-    def test_not_baked(self):
-        typeorder = self.typeorder
-        add2 = self.add.install('__add2', [typeorder, typeorder],
-                                baked_perform_call=False)
-        assert add2[0] == ['space', 'arg0', 'arg1']
-        if multimethod.Installer is multimethod.InstallerVersion1:
-            assert add2[1] == 'arg0.__add2(space, arg1)'
-        assert isinstance(add2[2], dict)
-        assert not add2[3]
-
-    def test_empty(self):
-        add3_installer = multimethod.Installer(self.add, '__add3', [{},{}])
-        assert add3_installer.is_empty()
-        if multimethod.Installer is multimethod.InstallerVersion1:
-            assert len(add3_installer.to_install) == 1
-            assert add3_installer.to_install[0][0] is None
-
-    def test_empty_direct(self):
-        assert not self.add.install_if_not_empty('__add4', [{},{}])
-
-    def test_empty_not_baked(self):
-        add5_installer = multimethod.Installer(self.add, '__add5', [{},{}],
-                                               baked_perform_call=False)
-        assert add5_installer.is_empty()
-        if multimethod.Installer is multimethod.InstallerVersion1:
-            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 test_mmdispatcher(self):
-        typeorder = self.typeorder
-        add2 = multimethod.MMDispatcher(self.add, [typeorder, typeorder])
-        space = 'space'
-        w_x = W_IntObject()
-        w_s = W_StringObject()
-        w_b1 = W_BoolObject()
-        w_b2 = W_BoolObject()
-        assert add2(space, w_x, w_b1) == 'fine'
-        assert add2(space, w_b2, w_x) == 'fine'
-        assert add2(space, w_b1, w_b2) == 'fine'
-        raises(FailedToImplement, "add2(space, w_b2, w_s)")
-        raises(FailedToImplement, "add2(space, w_s, w_b1)")
-
-    def test_forbidden_subclasses(self):
-        mul = multimethod.MultiMethodTable(2, root_class=W_Root,
-                                           argnames_before=['space'])
-        class UserW_StringObject(W_StringObject):
-            pass
-        def mul__Int_String(space, w_x, w_y):
-            assert space == 'space'
-            assert isinstance(w_x, W_IntObject)
-            assert isinstance(w_y, W_StringObject)
-            return 'fine'
-        mul.register(mul__Int_String, W_IntObject, W_StringObject)
-
-        mul1 = mul.install('__mul1', [self.typeorder, self.typeorder])
-        assert mul1('space', W_IntObject(), W_StringObject()) == 'fine'
-        assert mul1('space', W_IntObject(), UserW_StringObject()) == 'fine'
-
-        ext_typeorder = self.typeorder.copy()
-        ext_typeorder[UserW_StringObject] = []
-        mul2 = mul.install('__mul2', [ext_typeorder, ext_typeorder])
-        assert mul2('space', W_IntObject(), W_StringObject()) == 'fine'
-        raises(FailedToImplement,
-               mul2, 'baz', W_IntObject(), UserW_StringObject())
-
-    def test_more_forbidden_subclasses(self):
-        mul = multimethod.MultiMethodTable(2, root_class=W_Root,
-                                           argnames_before=['space'])
-        class UserW_StringObject(W_StringObject):
-            pass
-        def mul__String_String(space, w_x, w_y):
-            assert space == 'space'
-            assert isinstance(w_x, W_StringObject)
-            assert isinstance(w_y, W_StringObject)
-            return 'fine'
-        mul.register(mul__String_String, W_StringObject, W_StringObject)
-
-        ext_typeorder = {W_StringObject: [(W_StringObject, None)],
-                         UserW_StringObject: []}
-        mul2 = mul.install('__mul2', [ext_typeorder, ext_typeorder])
-        assert mul2('space', W_StringObject(), W_StringObject()) == 'fine'
-        raises(FailedToImplement,
-               mul2, 'baz', W_StringObject(), UserW_StringObject())
-        raises(FailedToImplement,
-               mul2, 'baz', UserW_StringObject(), W_StringObject())
-        raises(FailedToImplement,
-               mul2, 'baz', UserW_StringObject(), UserW_StringObject())
-
-    def test_ANY(self):
-        setattr = multimethod.MultiMethodTable(3, root_class=W_Root,
-                                           argnames_before=['space'])
-        def setattr__Int_ANY_ANY(space, w_x, w_y, w_z):
-            assert space == 'space'
-            assert isinstance(w_x, W_IntObject)
-            assert isinstance(w_y, W_Root)
-            assert isinstance(w_z, W_Root)
-            return w_y.__class__.__name__ + w_z.__class__.__name__
-        setattr.register(setattr__Int_ANY_ANY, W_IntObject, W_Root, W_Root)
-        setattr1 = setattr.install('__setattr1', [self.typeorder]*3)
-        for cls1 in self.typeorder:
-            for cls2 in self.typeorder:
-                assert setattr1('space', W_IntObject(), cls1(), cls2()) == (
-                    cls1.__name__ + cls2.__name__)
-
-    def test_all_cases(self):
-        import random
-        space = 'space'
-        w_x = W_IntObject()
-        w_x.expected = [W_IntObject, W_Root]
-        w_s = W_StringObject()
-        w_s.expected = [W_StringObject, W_Root]
-        w_b = W_BoolObject()
-        w_b.expected = [W_BoolObject, W_IntObject, W_Root]
-
-        def test(indices):
-            sub = multimethod.MultiMethodTable(2, root_class=W_Root,
-                                               argnames_before=['space'])
-            def addimpl(cls1, cls2):
-                token = random.random()
-                def sub__cls1_cls2(space, w_x, w_y):
-                    assert space == 'space'
-                    assert isinstance(w_x, cls1)
-                    assert isinstance(w_y, cls2)
-                    return token
-                sub.register(sub__cls1_cls2, cls1, cls2)
-                return token
-
-            def check(w1, w2):
-                try:
-                    res = sub1(space, w1, w2)
-                except FailedToImplement:
-                    res = FailedToImplement
-                for cls1 in w1.expected:
-                    for cls2 in w2.expected:
-                        if (cls1, cls2) in expected:
-                            assert res == expected[cls1, cls2]
-                            return
-                else:
-                    assert res is FailedToImplement
-
-            random.shuffle(indices)
-            expected = {}
-            for index in indices:
-                cls1, cls2 = choices[index]
-                token = addimpl(cls1, cls2)
-                expected[cls1, cls2] = token
-
-            typeorder = self.typeorder
-            sub1 = sub.install('__sub', [typeorder, typeorder])
-            for w1 in [w_x, w_s, w_b]:
-                for w2 in [w_x, w_s, w_b]:
-                    check(w1, w2)
-
-        classes = [W_Root, W_StringObject, W_IntObject, W_BoolObject]
-        choices = [(cls1, cls2) for cls1 in classes
-                                for cls2 in classes]
-        # each choice is a pair of classes which can be implemented or
-        # not by the multimethod 'sub'.  Test all combinations that
-        # involve at most three implemented choices.
-        for i in range(len(choices)):
-            test([i])
-            for j in range(i+1, len(choices)):
-                test([i, j])
-                for k in range(j+1, len(choices)):
-                    test([i, j, k])
-                    #for l in range(k+1, len(choices)):  -- for a 4th choice
-                    #    test([i, j, k, l])              -- (takes a while)
-
-
-class TestMultiMethod2(TestMultiMethod1):
-    Installer = multimethod.InstallerVersion2
diff --git a/pypy/objspace/std/test/test_userobject.py b/pypy/objspace/std/test/test_userobject.py
--- a/pypy/objspace/std/test/test_userobject.py
+++ b/pypy/objspace/std/test/test_userobject.py
@@ -273,22 +273,6 @@
             i += 1
 
 
-class AppTestWithMultiMethodVersion2(AppTestUserObject):
-    spaceconfig = {}
-
-    def setup_class(cls):
-        from pypy.objspace.std import multimethod
-
-        cls.prev_installer = multimethod.Installer
-        multimethod.Installer = multimethod.InstallerVersion2
-        if cls.runappdirect:
-            py.test.skip("Cannot run different installers when runappdirect")
-
-    def teardown_class(cls):
-        from pypy.objspace.std import multimethod
-        multimethod.Installer = cls.prev_installer
-
-
 class AppTestWithGetAttributeShortcut(AppTestUserObject):
     spaceconfig = {"objspace.std.getattributeshortcut": True}
 


More information about the pypy-commit mailing list