[pypy-commit] pypy online-transforms: hg merge default

rlamy noreply at buildbot.pypy.org
Sun Nov 2 23:41:06 CET 2014


Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: online-transforms
Changeset: r74327:d935b9812077
Date: 2014-11-01 05:16 +0000
http://bitbucket.org/pypy/pypy/changeset/d935b9812077/

Log:	hg merge default

diff too long, truncating to 2000 out of 4803 lines

diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py
--- a/pypy/config/pypyoption.py
+++ b/pypy/config/pypyoption.py
@@ -255,10 +255,6 @@
         BoolOption("optimized_list_getitem",
                    "special case the 'list[integer]' expressions",
                    default=False),
-        BoolOption("builtinshortcut",
-                   "a shortcut for operations between built-in types. XXX: "
-                   "deprecated, not really a shortcut any more.",
-                   default=False),
         BoolOption("getattributeshortcut",
                    "track types that override __getattribute__",
                    default=False,
@@ -270,9 +266,6 @@
                    # weakrefs needed, because of get_subclasses()
                    requires=[("translation.rweakref", True)]),
 
-        ChoiceOption("multimethods", "the multimethod implementation to use",
-                     ["doubledispatch", "mrd"],
-                     default="mrd"),
         BoolOption("withidentitydict",
                    "track types that override __hash__, __eq__ or __cmp__ and use a special dict strategy for those which do not",
                    default=False,
diff --git a/pypy/doc/config/objspace.std.builtinshortcut.txt b/pypy/doc/config/objspace.std.builtinshortcut.txt
deleted file mode 100644
--- a/pypy/doc/config/objspace.std.builtinshortcut.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-A shortcut speeding up primitive operations between built-in types.
-
-This is a space-time trade-off: at the moment, this option makes a
-translated pypy-c executable bigger by about 1.7 MB.  (This can probably
-be improved with careful analysis.)
diff --git a/pypy/doc/config/objspace.std.multimethods.txt b/pypy/doc/config/objspace.std.multimethods.txt
deleted file mode 100644
--- a/pypy/doc/config/objspace.std.multimethods.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-Choose the multimethod implementation.
-
-* ``doubledispatch`` turns
-  a multimethod call into a sequence of normal method calls.
-
-* ``mrd`` uses a technique known as Multiple Row Displacement
-  which precomputes a few compact tables of numbers and
-  function pointers.
diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst
--- a/pypy/doc/whatsnew-head.rst
+++ b/pypy/doc/whatsnew-head.rst
@@ -35,3 +35,7 @@
 Split RPython documentation from PyPy documentation and clean up.  There now is
 a clearer separation between documentation for users, developers and people
 interested in background information.
+
+.. branch: kill-multimethod
+
+Kill multimethod machinery, all multimethods were removed earlier.
diff --git a/pypy/goal/targetpypystandalone.py b/pypy/goal/targetpypystandalone.py
--- a/pypy/goal/targetpypystandalone.py
+++ b/pypy/goal/targetpypystandalone.py
@@ -208,23 +208,6 @@
         from pypy.config.pypyoption import set_pypy_opt_level
         set_pypy_opt_level(config, translateconfig.opt)
 
-        # as of revision 27081, multimethod.py uses the InstallerVersion1 by default
-        # because it is much faster both to initialize and run on top of CPython.
-        # The InstallerVersion2 is optimized for making a translator-friendly
-        # structure for low level backends. However, InstallerVersion1 is still
-        # preferable for high level backends, so we patch here.
-
-        from pypy.objspace.std import multimethod
-        if config.objspace.std.multimethods == 'mrd':
-            assert multimethod.InstallerVersion1.instance_counter == 0,\
-                   'The wrong Installer version has already been instatiated'
-            multimethod.Installer = multimethod.InstallerVersion2
-        elif config.objspace.std.multimethods == 'doubledispatch':
-            # don't rely on the default, set again here
-            assert multimethod.InstallerVersion2.instance_counter == 0,\
-                   'The wrong Installer version has already been instatiated'
-            multimethod.Installer = multimethod.InstallerVersion1
-
     def print_help(self, config):
         self.opt_parser(config).print_help()
 
diff --git a/pypy/interpreter/typedef.py b/pypy/interpreter/typedef.py
--- a/pypy/interpreter/typedef.py
+++ b/pypy/interpreter/typedef.py
@@ -618,6 +618,7 @@
 from pypy.interpreter.nestedscope import Cell
 from pypy.interpreter.special import NotImplemented, Ellipsis
 
+
 def descr_get_dict(space, w_obj):
     w_dict = w_obj.getdict(space)
     if w_dict is None:
@@ -638,6 +639,11 @@
         return space.w_None
     return lifeline.get_any_weakref(space)
 
+dict_descr = GetSetProperty(descr_get_dict, descr_set_dict, descr_del_dict,
+                            doc="dictionary for instance variables (if defined)")
+dict_descr.name = '__dict__'
+
+
 def generic_ne(space, w_obj1, w_obj2):
     if space.eq_w(w_obj1, w_obj2):
         return space.w_False
diff --git a/pypy/module/_file/test/test_file.py b/pypy/module/_file/test/test_file.py
--- a/pypy/module/_file/test/test_file.py
+++ b/pypy/module/_file/test/test_file.py
@@ -275,6 +275,24 @@
         finally:
             f.close()
 
+    def test_ignore_ioerror_in_readall_if_nonempty_result(self):
+        # this is the behavior of regular files in CPython 2.7, as
+        # well as of _io.FileIO at least in CPython 3.3.  This is
+        # *not* the behavior of _io.FileIO in CPython 3.4 or 3.5;
+        # see CPython's issue #21090.
+        try:
+            from posix import openpty, fdopen, write, close
+        except ImportError:
+            skip('no openpty on this platform')
+        read_fd, write_fd = openpty()
+        write(write_fd, 'Abc\n')
+        close(write_fd)
+        f = fdopen(read_fd)
+        s = f.read()
+        assert s == 'Abc\r\n'
+        raises(IOError, f.read)
+        f.close()
+
 
 class AppTestNonblocking(object):
     def setup_class(cls):
diff --git a/pypy/module/_io/interp_bufferedio.py b/pypy/module/_io/interp_bufferedio.py
--- a/pypy/module/_io/interp_bufferedio.py
+++ b/pypy/module/_io/interp_bufferedio.py
@@ -812,11 +812,6 @@
         self._check_closed(space, "flush of closed file")
         with self.lock:
             self._flush_and_rewind_unlocked(space)
-            if self.readable:
-                # Rewind the raw stream so that its position corresponds to
-                # the current logical position.
-                self._raw_seek(space, -self._raw_offset(), 1)
-                self._reader_reset_buf()
 
     def _flush_and_rewind_unlocked(self, space):
         self._writer_flush_unlocked(space)
diff --git a/pypy/module/_io/interp_iobase.py b/pypy/module/_io/interp_iobase.py
--- a/pypy/module/_io/interp_iobase.py
+++ b/pypy/module/_io/interp_iobase.py
@@ -24,8 +24,7 @@
     try:
         w_value = error.get_w_value(space)
         w_errno = space.getattr(w_value, space.wrap("errno"))
-        return space.is_true(
-            space.eq(w_errno, space.wrap(EINTR)))
+        return space.eq_w(w_errno, space.wrap(EINTR))
     except OperationError:
         return False
 
diff --git a/pypy/module/_io/test/test_io.py b/pypy/module/_io/test/test_io.py
--- a/pypy/module/_io/test/test_io.py
+++ b/pypy/module/_io/test/test_io.py
@@ -352,3 +352,13 @@
                 assert mod == 'io'
             else:
                 assert mod == '_io'
+
+    def test_issue1902(self):
+        import _io
+        with _io.open(self.tmpfile, 'w+b', 4096) as f:
+            f.write(b'\xff' * 13569)
+            f.flush()
+            f.seek(0, 0)
+            f.read(1)
+            f.seek(-1, 1)
+            f.write(b'')
diff --git a/pypy/module/array/interp_array.py b/pypy/module/array/interp_array.py
--- a/pypy/module/array/interp_array.py
+++ b/pypy/module/array/interp_array.py
@@ -1,5 +1,3 @@
-from __future__ import with_statement
-
 from rpython.rlib import jit
 from rpython.rlib.buffer import Buffer
 from rpython.rlib.objectmodel import keepalive_until_here
@@ -15,9 +13,7 @@
     interp2app, interpindirect2app, unwrap_spec)
 from pypy.interpreter.typedef import (
     GetSetProperty, TypeDef, make_weakref_descr)
-from pypy.interpreter.generator import GeneratorIterator
 from pypy.module._file.interp_file import W_File
-from pypy.objspace.std.floatobject import W_FloatObject
 
 
 @unwrap_spec(typecode=str)
@@ -654,7 +650,7 @@
             try:
                 item = unwrap(w_item)
             except OperationError, e:
-                if isinstance(w_item, W_FloatObject):
+                if space.isinstance_w(w_item, space.w_float):
                     # Odd special case from cpython
                     raise
                 if mytype.method != '' and e.match(space, space.w_TypeError):
diff --git a/pypy/module/array/test/test_array.py b/pypy/module/array/test/test_array.py
--- a/pypy/module/array/test/test_array.py
+++ b/pypy/module/array/test/test_array.py
@@ -1035,8 +1035,3 @@
 
     def test_fresh_array_buffer_str(self):
         assert str(buffer(self.array('i'))) == ''
-
-
-class AppTestArrayBuiltinShortcut(AppTestArray):
-    spaceconfig = AppTestArray.spaceconfig.copy()
-    spaceconfig['objspace.std.builtinshortcut'] = True
diff --git a/pypy/module/cpyext/typeobject.py b/pypy/module/cpyext/typeobject.py
--- a/pypy/module/cpyext/typeobject.py
+++ b/pypy/module/cpyext/typeobject.py
@@ -303,11 +303,6 @@
 
 @bootstrap_function
 def init_typeobject(space):
-    # Probably a hack
-    space.model.typeorder[W_PyCTypeObject] = [(W_PyCTypeObject, None),
-                                              (W_TypeObject, None),
-                                              (W_Root, None)]
-
     make_typedescr(space.w_type.instancetypedef,
                    basestruct=PyTypeObject,
                    alloc=type_alloc,
diff --git a/pypy/objspace/fake/objspace.py b/pypy/objspace/fake/objspace.py
--- a/pypy/objspace/fake/objspace.py
+++ b/pypy/objspace/fake/objspace.py
@@ -2,7 +2,6 @@
 from pypy.interpreter import argument, gateway
 from pypy.interpreter.baseobjspace import W_Root, ObjSpace, SpaceCache
 from pypy.interpreter.typedef import TypeDef, GetSetProperty
-from pypy.objspace.std.stdtypedef import StdTypeDef
 from pypy.objspace.std.sliceobject import W_SliceObject
 from rpython.rlib.buffer import StringBuffer
 from rpython.rlib.objectmodel import instantiate, we_are_translated, specialize
@@ -112,6 +111,10 @@
 # ____________________________________________________________
 
 
+BUILTIN_TYPES = ['int', 'str', 'float', 'long', 'tuple', 'list', 'dict',
+                 'unicode', 'complex', 'slice', 'bool', 'basestring', 'object',
+                 'bytearray', 'buffer']
+
 class FakeObjSpace(ObjSpace):
     def __init__(self, config=None):
         self._seen_extras = []
@@ -342,9 +345,7 @@
     def setup(space):
         for name in (ObjSpace.ConstantTable +
                      ObjSpace.ExceptionTable +
-                     ['int', 'str', 'float', 'long', 'tuple', 'list',
-                      'dict', 'unicode', 'complex', 'slice', 'bool',
-                      'basestring', 'object', 'bytearray', 'buffer']):
+                     BUILTIN_TYPES):
             setattr(space, 'w_' + name, w_some_obj())
         space.w_type = w_some_type()
         #
@@ -375,7 +376,7 @@
 @specialize.memo()
 def see_typedef(space, typedef):
     assert isinstance(typedef, TypeDef)
-    if not isinstance(typedef, StdTypeDef):
+    if typedef.name not in BUILTIN_TYPES:
         for name, value in typedef.rawdict.items():
             space.wrap(value)
 
diff --git a/pypy/objspace/std/basestringtype.py b/pypy/objspace/std/basestringtype.py
--- a/pypy/objspace/std/basestringtype.py
+++ b/pypy/objspace/std/basestringtype.py
@@ -1,7 +1,7 @@
-from pypy.objspace.std.stdtypedef import StdTypeDef
+from pypy.interpreter.typedef import TypeDef
 
 
-basestring_typedef = StdTypeDef("basestring",
+basestring_typedef = TypeDef("basestring",
     __doc__ =  ("basestring cannot be instantiated; "
                 "it is the base for str and unicode.")
     )
diff --git a/pypy/objspace/std/boolobject.py b/pypy/objspace/std/boolobject.py
--- a/pypy/objspace/std/boolobject.py
+++ b/pypy/objspace/std/boolobject.py
@@ -6,8 +6,8 @@
 from rpython.tool.sourcetools import func_renamer, func_with_new_name
 
 from pypy.interpreter.gateway import WrappedDefault, interp2app, unwrap_spec
+from pypy.interpreter.typedef import TypeDef
 from pypy.objspace.std.intobject import W_AbstractIntObject, W_IntObject
-from pypy.objspace.std.stdtypedef import StdTypeDef
 
 
 class W_BoolObject(W_IntObject):
@@ -80,7 +80,7 @@
 W_BoolObject.w_True = W_BoolObject(True)
 
 
-W_BoolObject.typedef = StdTypeDef("bool", W_IntObject.typedef,
+W_BoolObject.typedef = TypeDef("bool", W_IntObject.typedef,
     __doc__ = """bool(x) -> bool
 
 Returns True when the argument x is true, False otherwise.
diff --git a/pypy/objspace/std/builtinshortcut.py b/pypy/objspace/std/builtinshortcut.py
deleted file mode 100644
--- a/pypy/objspace/std/builtinshortcut.py
+++ /dev/null
@@ -1,137 +0,0 @@
-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
-
-# ____________________________________________________________
-#
-#  The sole purpose of this file is performance.
-#  It speeds up the dispatch of operations between
-#  built-in objects.
-#
-
-# this is a selection... a few operations are missing because they are
-# thought to be very rare or most commonly used with non-builtin types
-METHODS_WITH_SHORTCUT = dict.fromkeys(
-    ['add', 'sub', 'mul', 'truediv', 'floordiv', 'div',
-     'mod', 'lshift', 'rshift', 'and_', 'or_', 'xor', 'pow',
-     'lt', 'le', 'eq', 'ne', 'gt', 'ge', 'contains',
-     # unary
-     'len', 'nonzero', 'repr', 'str', 'hash',
-     'neg', 'invert', 'index', 'iter', 'next', 'buffer',
-     'getitem', 'setitem', 'int',
-     # in-place
-     'inplace_add', 'inplace_sub', 'inplace_mul', 'inplace_truediv',
-     'inplace_floordiv', 'inplace_div', 'inplace_mod', 'inplace_pow',
-     'inplace_lshift', 'inplace_rshift', 'inplace_and', 'inplace_or',
-     'inplace_xor',
-     # other
-     'format',
- ])
-
-KNOWN_MISSING = ['getattr',   # mostly non-builtins or optimized by CALL_METHOD
-                 'setattr', 'delattr', 'userdel',  # mostly for non-builtins
-                 'get', 'set', 'delete',   # uncommon (except on functions)
-                 'getslice', 'setslice', 'delslice',  # see below
-                 'delitem', 'trunc',              # rare stuff?
-                 'abs', 'hex', 'oct',             # rare stuff?
-                 'pos', 'divmod', 'cmp',          # rare stuff?
-                 'float', 'long', 'coerce',       # rare stuff?
-                 'isinstance', 'issubtype',
-                 ]
-# We cannot support {get,set,del}slice right now because
-# DescrOperation.{get,set,del}slice do a bit more work than just call
-# the special methods: they call old_slice_range().  See e.g.
-# test_builtinshortcut.AppTestString.
-
-for _name, _, _, _specialmethods in ObjSpace.MethodTable:
-    if _specialmethods:
-        assert _name in METHODS_WITH_SHORTCUT or _name in KNOWN_MISSING, (
-            "operation %r should be in METHODS_WITH_SHORTCUT or KNOWN_MISSING"
-            % (_name,))
-
-
-def filter_out_conversions(typeorder):
-    res = {}
-    for cls, order in typeorder.iteritems():        
-        res[cls] = [(target_type, converter) for (target_type, converter) in
-                                                 order if converter is None]
-    return res
-
-
-def install(space, mm, fallback_mm=None):
-    """Install a function <name>() on the space instance which invokes
-    a shortcut for built-in types.  Returns the shortcutting multimethod
-    object or None.
-    """
-    name = mm.name
-    if name not in METHODS_WITH_SHORTCUT:
-        return None
-
-    # can be called multiple times without re-installing
-    if name in space.__dict__:
-        mm1, shortcut_method = space.__dict__[name].builtinshortcut
-        assert mm1 is mm
-        return shortcut_method
-
-    #print 'installing shortcut for:', name
-    assert hasattr(DescrOperation, name)
-
-    base_method = getattr(space.__class__, name)
-
-    # Basic idea: we first try to dispatch the operation using purely
-    # the multimethod.  If this is done naively, subclassing a built-in
-    # type like 'int' and overriding a special method like '__add__'
-    # doesn't work any more, because the multimethod will accept the int
-    # subclass and compute the result in the built-in way.  To avoid
-    # this issue, we tweak the shortcut multimethods so that these ones
-    # (and only these ones) never match the interp-level subclasses
-    # built in pypy.interpreter.typedef.get_unique_interplevel_subclass.
-    expanded_order = space.model.get_typeorder_with_empty_usersubcls()
-    if fallback_mm:
-        mm = mm.merge_with(fallback_mm)
-    shortcut_method = mm.install_not_sliced(filter_out_conversions(expanded_order))
-
-    def operate(*args_w):
-        try:
-            return shortcut_method(space, *args_w)
-        except FailedToImplement:
-            pass
-        return base_method(space, *args_w)
-
-    operate = func_with_new_name(operate, name)
-    operate.builtinshortcut = (mm, shortcut_method)
-    setattr(space, name, operate)
-    return shortcut_method
-
-
-def install_is_true(space, mm_nonzero, mm_len):
-    shortcut = install(space, mm_nonzero, fallback_mm = mm_len)
-    assert 'is_true' not in space.__dict__
-
-    def is_true(w_obj):
-        # a bit of duplication of the logic from DescrOperation.is_true...
-        try:
-            w_res = shortcut(space, w_obj)
-        except FailedToImplement:
-            pass
-        else:
-            # the __nonzero__ method of built-in objects should
-            # always directly return a Bool; however, the __len__ method
-            # of built-in objects typically returns an unwrappable integer
-            if isinstance(w_res, W_BoolObject):
-                return bool(w_res.intval)
-            try:
-                return space.int_w(w_res) != 0
-            except OperationError:
-                # I think no OperationError other than w_OverflowError
-                # could occur here
-                w_obj = w_res
-
-        # general case fallback
-        return _DescrOperation_is_true(space, w_obj)
-
-    _DescrOperation_is_true = DescrOperation.is_true.im_func
-    space.is_true = is_true
diff --git a/pypy/objspace/std/bytearrayobject.py b/pypy/objspace/std/bytearrayobject.py
--- a/pypy/objspace/std/bytearrayobject.py
+++ b/pypy/objspace/std/bytearrayobject.py
@@ -10,8 +10,8 @@
 from pypy.interpreter.error import OperationError, oefmt
 from pypy.interpreter.gateway import WrappedDefault, interp2app, unwrap_spec
 from pypy.interpreter.signature import Signature
+from pypy.interpreter.typedef import TypeDef
 from pypy.objspace.std.sliceobject import W_SliceObject
-from pypy.objspace.std.stdtypedef import StdTypeDef
 from pypy.objspace.std.stringmethods import StringMethods, _get_buffer
 from pypy.objspace.std.bytesobject import W_BytesObject
 from pypy.objspace.std.util import get_positive_index
@@ -990,7 +990,7 @@
         """
 
 
-W_BytearrayObject.typedef = StdTypeDef(
+W_BytearrayObject.typedef = TypeDef(
     "bytearray",
     __doc__ = BytearrayDocstrings.__doc__,
     __new__ = interp2app(W_BytearrayObject.descr_new),
diff --git a/pypy/objspace/std/bytesobject.py b/pypy/objspace/std/bytesobject.py
--- a/pypy/objspace/std/bytesobject.py
+++ b/pypy/objspace/std/bytesobject.py
@@ -10,10 +10,10 @@
 from pypy.interpreter.error import OperationError, oefmt
 from pypy.interpreter.gateway import (
     WrappedDefault, interp2app, interpindirect2app, unwrap_spec)
+from pypy.interpreter.typedef import TypeDef
 from pypy.objspace.std import newformat
 from pypy.objspace.std.basestringtype import basestring_typedef
 from pypy.objspace.std.formatting import mod_format
-from pypy.objspace.std.stdtypedef import StdTypeDef
 from pypy.objspace.std.stringmethods import StringMethods
 from pypy.objspace.std.unicodeobject import (
     _get_encoding_and_errors, decode_object, unicode_from_encoded_object,
@@ -874,7 +874,7 @@
         return W_BytesObject(c)
 
 
-W_BytesObject.typedef = StdTypeDef(
+W_BytesObject.typedef = TypeDef(
     "str", basestring_typedef,
     __new__ = interp2app(W_BytesObject.descr_new),
     __doc__ = """str(object='') -> string
diff --git a/pypy/objspace/std/complexobject.py b/pypy/objspace/std/complexobject.py
--- a/pypy/objspace/std/complexobject.py
+++ b/pypy/objspace/std/complexobject.py
@@ -1,18 +1,19 @@
 import math
 
-from pypy.interpreter.baseobjspace import W_Root
-from pypy.interpreter.error import OperationError, oefmt
-from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault
-from pypy.objspace.std import newformat
-from pypy.objspace.std.floatobject import _hash_float
-from pypy.objspace.std.stdtypedef import GetSetProperty, StdTypeDef
 from rpython.rlib import jit, rcomplex
 from rpython.rlib.rarithmetic import intmask, r_ulonglong
 from rpython.rlib.rbigint import rbigint
 from rpython.rlib.rfloat import (
-    formatd, DTSF_STR_PRECISION, isinf, isnan, copysign, string_to_float)
+    DTSF_STR_PRECISION, copysign, formatd, isinf, isnan, string_to_float)
 from rpython.rlib.rstring import ParseStringError
 
+from pypy.interpreter.baseobjspace import W_Root
+from pypy.interpreter.error import OperationError, oefmt
+from pypy.interpreter.gateway import WrappedDefault, interp2app, unwrap_spec
+from pypy.interpreter.typedef import GetSetProperty, TypeDef
+from pypy.objspace.std import newformat
+from pypy.objspace.std.floatobject import _hash_float
+
 
 def _split_complex(s):
     slen = len(s)
@@ -264,7 +265,7 @@
         if self.user_overridden_class:
             return None
         from rpython.rlib.longlong2float import float2longlong
-        from pypy.objspace.std.model import IDTAG_COMPLEX as tag
+        from pypy.objspace.std.util import IDTAG_COMPLEX as tag
         real = space.float_w(space.getattr(self, space.wrap("real")))
         imag = space.float_w(space.getattr(self, space.wrap("imag")))
         real_b = rbigint.fromrarith_int(float2longlong(real))
@@ -587,7 +588,7 @@
         return space.newfloat(getattr(w_obj, name))
     return GetSetProperty(fget)
 
-W_ComplexObject.typedef = StdTypeDef("complex",
+W_ComplexObject.typedef = TypeDef("complex",
     __doc__ = """complex(real[, imag]) -> complex number
 
 Create a complex number from a real part and an optional imaginary part.
diff --git a/pypy/objspace/std/dictmultiobject.py b/pypy/objspace/std/dictmultiobject.py
--- a/pypy/objspace/std/dictmultiobject.py
+++ b/pypy/objspace/std/dictmultiobject.py
@@ -11,7 +11,7 @@
     WrappedDefault, applevel, interp2app, unwrap_spec)
 from pypy.interpreter.mixedmodule import MixedModule
 from pypy.interpreter.signature import Signature
-from pypy.objspace.std.stdtypedef import StdTypeDef
+from pypy.interpreter.typedef import TypeDef
 from pypy.objspace.std.util import negate
 
 
@@ -372,7 +372,7 @@
 dictrepr = app.interphook("dictrepr")
 
 
-W_DictMultiObject.typedef = StdTypeDef("dict",
+W_DictMultiObject.typedef = TypeDef("dict",
     __doc__ = '''dict() -> new empty dictionary.
 dict(mapping) -> new dictionary initialized from a mapping object\'s
     (key, value) pairs.
@@ -1217,8 +1217,6 @@
 class W_BaseDictMultiIterObject(W_Root):
     _immutable_fields_ = ["iteratorimplementation"]
 
-    ignore_for_isinstance_cache = True
-
     def __init__(self, space, iteratorimplementation):
         self.space = space
         self.iteratorimplementation = iteratorimplementation
@@ -1309,7 +1307,7 @@
             return space.newtuple([w_key, w_value])
         raise OperationError(space.w_StopIteration, space.w_None)
 
-W_DictMultiIterItemsObject.typedef = StdTypeDef(
+W_DictMultiIterItemsObject.typedef = TypeDef(
     "dict_iteritems",
     __iter__ = interp2app(W_DictMultiIterItemsObject.descr_iter),
     next = interp2app(W_DictMultiIterItemsObject.descr_next),
@@ -1317,7 +1315,7 @@
     __reduce__ = interp2app(W_BaseDictMultiIterObject.descr_reduce),
     )
 
-W_DictMultiIterKeysObject.typedef = StdTypeDef(
+W_DictMultiIterKeysObject.typedef = TypeDef(
     "dict_iterkeys",
     __iter__ = interp2app(W_DictMultiIterKeysObject.descr_iter),
     next = interp2app(W_DictMultiIterKeysObject.descr_next),
@@ -1325,7 +1323,7 @@
     __reduce__ = interp2app(W_BaseDictMultiIterObject.descr_reduce),
     )
 
-W_DictMultiIterValuesObject.typedef = StdTypeDef(
+W_DictMultiIterValuesObject.typedef = TypeDef(
     "dict_itervalues",
     __iter__ = interp2app(W_DictMultiIterValuesObject.descr_iter),
     next = interp2app(W_DictMultiIterValuesObject.descr_next),
@@ -1433,7 +1431,7 @@
     def descr_iter(self, space):
         return W_DictMultiIterValuesObject(space, self.w_dict.itervalues())
 
-W_DictViewItemsObject.typedef = StdTypeDef(
+W_DictViewItemsObject.typedef = TypeDef(
     "dict_items",
     __repr__ = interp2app(W_DictViewItemsObject.descr_repr),
     __len__ = interp2app(W_DictViewItemsObject.descr_len),
@@ -1456,7 +1454,7 @@
     __rxor__ = interp2app(W_DictViewItemsObject.descr_rxor),
     )
 
-W_DictViewKeysObject.typedef = StdTypeDef(
+W_DictViewKeysObject.typedef = TypeDef(
     "dict_keys",
     __repr__ = interp2app(W_DictViewKeysObject.descr_repr),
     __len__ = interp2app(W_DictViewKeysObject.descr_len),
@@ -1479,7 +1477,7 @@
     __rxor__ = interp2app(W_DictViewKeysObject.descr_rxor),
     )
 
-W_DictViewValuesObject.typedef = StdTypeDef(
+W_DictViewValuesObject.typedef = TypeDef(
     "dict_values",
     __repr__ = interp2app(W_DictViewValuesObject.descr_repr),
     __len__ = interp2app(W_DictViewValuesObject.descr_len),
diff --git a/pypy/objspace/std/dictproxyobject.py b/pypy/objspace/std/dictproxyobject.py
--- a/pypy/objspace/std/dictproxyobject.py
+++ b/pypy/objspace/std/dictproxyobject.py
@@ -1,8 +1,9 @@
-from pypy.objspace.std.dictmultiobject import DictStrategy, create_iterator_classes
+from rpython.rlib import rerased
+
+from pypy.interpreter.error import OperationError, oefmt
+from pypy.objspace.std.dictmultiobject import (
+    DictStrategy, create_iterator_classes)
 from pypy.objspace.std.typeobject import unwrap_cell
-from pypy.interpreter.error import OperationError, oefmt
-
-from rpython.rlib import rerased
 
 
 class DictProxyStrategy(DictStrategy):
diff --git a/pypy/objspace/std/floatobject.py b/pypy/objspace/std/floatobject.py
--- a/pypy/objspace/std/floatobject.py
+++ b/pypy/objspace/std/floatobject.py
@@ -2,24 +2,24 @@
 import operator
 import sys
 
+from rpython.rlib import rarithmetic, rfloat
+from rpython.rlib.rarithmetic import LONG_BIT, intmask, ovfcheck_float_to_int
+from rpython.rlib.rbigint import rbigint
+from rpython.rlib.rfloat import (
+    DTSF_ADD_DOT_0, DTSF_STR_PRECISION, INFINITY, NAN, copysign,
+    float_as_rbigint_ratio, formatd, isfinite, isinf, isnan)
+from rpython.rlib.rstring import ParseStringError
+from rpython.rlib.unroll import unrolling_iterable
+from rpython.rtyper.lltypesystem.module.ll_math import math_fmod
+from rpython.tool.sourcetools import func_with_new_name
+
 from pypy.interpreter.baseobjspace import W_Root
 from pypy.interpreter.error import OperationError, oefmt
-from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault
-from pypy.interpreter.typedef import GetSetProperty
+from pypy.interpreter.gateway import WrappedDefault, interp2app, unwrap_spec
+from pypy.interpreter.typedef import GetSetProperty, TypeDef
 from pypy.objspace.std import newformat
 from pypy.objspace.std.longobject import W_LongObject
-from pypy.objspace.std.stdtypedef import StdTypeDef
 from pypy.objspace.std.util import wrap_parsestringerror
-from rpython.rlib import rarithmetic, rfloat
-from rpython.rlib.rarithmetic import ovfcheck_float_to_int, intmask, LONG_BIT
-from rpython.rlib.rbigint import rbigint
-from rpython.rlib.rfloat import (
-    isinf, isnan, isfinite, INFINITY, NAN, copysign, formatd,
-    DTSF_ADD_DOT_0, DTSF_STR_PRECISION, float_as_rbigint_ratio)
-from rpython.rlib.rstring import ParseStringError
-from rpython.tool.sourcetools import func_with_new_name
-from rpython.rlib.unroll import unrolling_iterable
-from rpython.rtyper.lltypesystem.module.ll_math import math_fmod
 
 
 def float2string(x, code, precision):
@@ -182,7 +182,7 @@
         if self.user_overridden_class:
             return None
         from rpython.rlib.longlong2float import float2longlong
-        from pypy.objspace.std.model import IDTAG_FLOAT as tag
+        from pypy.objspace.std.util import IDTAG_FLOAT as tag
         val = float2longlong(space.float_w(self))
         b = rbigint.fromrarith_int(val)
         b = b.lshift(3).or_(rbigint.fromint(tag))
@@ -646,7 +646,7 @@
             return space.wrap("0x%sp%s%d" % (s, sign, exp))
 
 
-W_FloatObject.typedef = StdTypeDef("float",
+W_FloatObject.typedef = TypeDef("float",
     __doc__ = '''float(x) -> floating point number
 
 Convert a string or number to a floating point number, if possible.''',
diff --git a/pypy/objspace/std/formatting.py b/pypy/objspace/std/formatting.py
--- a/pypy/objspace/std/formatting.py
+++ b/pypy/objspace/std/formatting.py
@@ -1,15 +1,15 @@
-"""
-String formatting routines.
-"""
+"""String formatting routines"""
 import sys
-from pypy.interpreter.error import OperationError, oefmt
+
 from rpython.rlib import jit
-from rpython.rlib.rfloat import formatd, DTSF_ALT, isnan, isinf
+from rpython.rlib.rarithmetic import INT_MAX
+from rpython.rlib.rfloat import DTSF_ALT, formatd, isnan, isinf
 from rpython.rlib.rstring import StringBuilder, UnicodeBuilder
 from rpython.rlib.unroll import unrolling_iterable
-from rpython.rlib.rarithmetic import INT_MAX
 from rpython.tool.sourcetools import func_with_new_name
 
+from pypy.interpreter.error import OperationError, oefmt
+
 
 class BaseStringFormatter(object):
     def __init__(self, space, values_w, w_valuedict):
diff --git a/pypy/objspace/std/intobject.py b/pypy/objspace/std/intobject.py
--- a/pypy/objspace/std/intobject.py
+++ b/pypy/objspace/std/intobject.py
@@ -21,11 +21,10 @@
 from pypy.interpreter.baseobjspace import W_Root
 from pypy.interpreter.error import OperationError, oefmt
 from pypy.interpreter.gateway import WrappedDefault, interp2app, unwrap_spec
+from pypy.interpreter.typedef import TypeDef
 from pypy.objspace.std import newformat
-from pypy.objspace.std.model import (
-    BINARY_OPS, CMP_OPS, COMMUTATIVE_OPS, IDTAG_INT)
-from pypy.objspace.std.stdtypedef import StdTypeDef
-from pypy.objspace.std.util import wrap_parsestringerror
+from pypy.objspace.std.util import (
+    BINARY_OPS, CMP_OPS, COMMUTATIVE_OPS, IDTAG_INT, wrap_parsestringerror)
 
 SENTINEL = object()
 
@@ -601,6 +600,16 @@
         _divmod, ovf2small=_divmod_ovf2small)
 
 
+def setup_prebuilt(space):
+    if space.config.objspace.std.withprebuiltint:
+        W_IntObject.PREBUILT = []
+        for i in range(space.config.objspace.std.prebuiltintfrom,
+                       space.config.objspace.std.prebuiltintto):
+            W_IntObject.PREBUILT.append(W_IntObject(i))
+    else:
+        W_IntObject.PREBUILT = None
+
+
 def wrapint(space, x):
     if not space.config.objspace.std.withprebuiltint:
         return W_IntObject(x)
@@ -723,7 +732,7 @@
         return w_obj
 
 
-W_IntObject.typedef = StdTypeDef("int",
+W_IntObject.typedef = TypeDef("int",
     __doc__ = """int(x=0) -> int or long
 int(x, base=10) -> int or long
 
diff --git a/pypy/objspace/std/iterobject.py b/pypy/objspace/std/iterobject.py
--- a/pypy/objspace/std/iterobject.py
+++ b/pypy/objspace/std/iterobject.py
@@ -3,7 +3,7 @@
 from pypy.interpreter.baseobjspace import W_Root
 from pypy.interpreter.gateway import interp2app, interpindirect2app
 from pypy.interpreter.error import OperationError
-from pypy.objspace.std.stdtypedef import StdTypeDef
+from pypy.interpreter.typedef import TypeDef
 
 
 class W_AbstractSeqIterObject(W_Root):
@@ -40,7 +40,7 @@
     def descr_length_hint(self, space):
         return self.getlength(space)
 
-W_AbstractSeqIterObject.typedef = StdTypeDef(
+W_AbstractSeqIterObject.typedef = TypeDef(
     "sequenceiterator",
     __doc__ = '''iter(collection) -> iterator
 iter(callable, sentinel) -> iterator
@@ -159,7 +159,7 @@
             raise OperationError(space.w_StopIteration, space.w_None)
         return w_item
 
-W_ReverseSeqIterObject.typedef = StdTypeDef(
+W_ReverseSeqIterObject.typedef = TypeDef(
     "reversesequenceiterator",
     __iter__ = interp2app(W_ReverseSeqIterObject.descr_iter),
     next = interp2app(W_ReverseSeqIterObject.descr_next),
diff --git a/pypy/objspace/std/listobject.py b/pypy/objspace/std/listobject.py
--- a/pypy/objspace/std/listobject.py
+++ b/pypy/objspace/std/listobject.py
@@ -10,28 +10,29 @@
 import operator
 import sys
 
+from rpython.rlib import debug, jit, rerased
+from rpython.rlib.listsort import make_timsort_class
+from rpython.rlib.objectmodel import (
+    import_from_mixin, instantiate, newlist_hint, resizelist_hint, specialize)
+from rpython.tool.sourcetools import func_with_new_name
+
 from pypy.interpreter.baseobjspace import W_Root
 from pypy.interpreter.error import OperationError, oefmt
-from pypy.interpreter.gateway import (WrappedDefault, unwrap_spec, applevel,
-    interp2app)
+from pypy.interpreter.gateway import (
+    WrappedDefault, applevel, interp2app, unwrap_spec)
 from pypy.interpreter.generator import GeneratorIterator
 from pypy.interpreter.signature import Signature
+from pypy.interpreter.typedef import TypeDef
 from pypy.objspace.std.bytesobject import W_BytesObject
 from pypy.objspace.std.floatobject import W_FloatObject
 from pypy.objspace.std.intobject import W_IntObject
-from pypy.objspace.std.iterobject import (W_FastListIterObject,
-    W_ReverseSeqIterObject)
-from pypy.objspace.std.sliceobject import (W_SliceObject, unwrap_start_stop,
-    normalize_simple_slice)
-from pypy.objspace.std.stdtypedef import StdTypeDef
+from pypy.objspace.std.iterobject import (
+    W_FastListIterObject, W_ReverseSeqIterObject)
+from pypy.objspace.std.sliceobject import (
+    W_SliceObject, normalize_simple_slice, unwrap_start_stop)
 from pypy.objspace.std.tupleobject import W_AbstractTupleObject
 from pypy.objspace.std.unicodeobject import W_UnicodeObject
 from pypy.objspace.std.util import get_positive_index, negate
-from rpython.rlib import debug, jit, rerased
-from rpython.rlib.listsort import make_timsort_class
-from rpython.rlib.objectmodel import (
-    instantiate, newlist_hint, resizelist_hint, specialize, import_from_mixin)
-from rpython.tool.sourcetools import func_with_new_name
 
 __all__ = ['W_ListObject', 'make_range_list', 'make_empty_list_with_size']
 
@@ -1830,7 +1831,7 @@
         return CustomCompareSort.lt(self, a.w_key, b.w_key)
 
 
-W_ListObject.typedef = StdTypeDef("list",
+W_ListObject.typedef = TypeDef("list",
     __doc__ = """list() -> new empty list
 list(iterable) -> new list initialized from iterable's items""",
     __new__ = interp2app(W_ListObject.descr_new),
diff --git a/pypy/objspace/std/longobject.py b/pypy/objspace/std/longobject.py
--- a/pypy/objspace/std/longobject.py
+++ b/pypy/objspace/std/longobject.py
@@ -12,12 +12,11 @@
 from pypy.interpreter.error import OperationError, oefmt
 from pypy.interpreter.gateway import (
     WrappedDefault, interp2app, interpindirect2app, unwrap_spec)
+from pypy.interpreter.typedef import TypeDef
 from pypy.objspace.std import newformat
 from pypy.objspace.std.intobject import W_AbstractIntObject
-from pypy.objspace.std.model import (
-    BINARY_OPS, CMP_OPS, COMMUTATIVE_OPS, IDTAG_LONG)
-from pypy.objspace.std.stdtypedef import StdTypeDef
-from pypy.objspace.std.util import wrap_parsestringerror
+from pypy.objspace.std.util import (
+    BINARY_OPS, CMP_OPS, COMMUTATIVE_OPS, IDTAG_LONG, wrap_parsestringerror)
 
 
 def delegate_other(func):
@@ -567,7 +566,7 @@
     return w_obj
 
 
-W_AbstractLongObject.typedef = StdTypeDef("long",
+W_AbstractLongObject.typedef = TypeDef("long",
     __doc__ = """long(x=0) -> long
 long(x, base=10) -> long
 
diff --git a/pypy/objspace/std/model.py b/pypy/objspace/std/model.py
deleted file mode 100644
--- a/pypy/objspace/std/model.py
+++ /dev/null
@@ -1,357 +0,0 @@
-"""
-The full list of which Python types and which implementation we want
-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
-
-_registered_implementations = set()
-def registerimplementation(implcls):
-    """Hint to objspace.std.model to register the implementation class."""
-    assert issubclass(implcls, W_Object)
-    _registered_implementations.add(implcls)
-
-option_to_typename = {
-    "withsmalllong"  : ["smalllongobject.W_SmallLongObject"],
-    "withstrbuf"     : ["strbufobject.W_StringBufferObject"],
-}
-
-IDTAG_INT     = 1
-IDTAG_LONG    = 3
-IDTAG_FLOAT   = 5
-IDTAG_COMPLEX = 7
-
-class StdTypeModel:
-
-    def __init__(self, config):
-        """NOT_RPYTHON: inititialization only"""
-        self.config = config
-        # All the Python types that we want to provide in this StdObjSpace
-
-        # 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 complexobject
-        from pypy.objspace.std import tupleobject
-        from pypy.objspace.std import listobject
-        from pypy.objspace.std import dictmultiobject
-        from pypy.objspace.std import setobject
-        from pypy.objspace.std import basestringtype
-        from pypy.objspace.std import bytesobject
-        from pypy.objspace.std import bytearrayobject
-        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 dictproxyobject
-        from pypy.objspace.std import proxyobject
-        from pypy.objspace.std import bufferobject
-        from pypy.objspace.std import memoryobject
-
-
-        self.pythontypes = []
-        self.pythontypes.append(objectobject.W_ObjectObject.typedef)
-        self.pythontypes.append(typeobject.W_TypeObject.typedef)
-        self.pythontypes.append(noneobject.W_NoneObject.typedef)
-        self.pythontypes.append(tupleobject.W_TupleObject.typedef)
-        self.pythontypes.append(listobject.W_ListObject.typedef)
-        self.pythontypes.append(dictmultiobject.W_DictMultiObject.typedef)
-        self.pythontypes.append(setobject.W_SetObject.typedef)
-        self.pythontypes.append(setobject.W_FrozensetObject.typedef)
-        self.pythontypes.append(iterobject.W_AbstractSeqIterObject.typedef)
-        self.pythontypes.append(basestringtype.basestring_typedef)
-        self.pythontypes.append(bytesobject.W_BytesObject.typedef)
-        self.pythontypes.append(bytearrayobject.W_BytearrayObject.typedef)
-        self.pythontypes.append(unicodeobject.W_UnicodeObject.typedef)
-        self.pythontypes.append(intobject.W_IntObject.typedef)
-        self.pythontypes.append(boolobject.W_BoolObject.typedef)
-        self.pythontypes.append(longobject.W_LongObject.typedef)
-        self.pythontypes.append(floatobject.W_FloatObject.typedef)
-        self.pythontypes.append(complexobject.W_ComplexObject.typedef)
-        self.pythontypes.append(sliceobject.W_SliceObject.typedef)
-        self.pythontypes.append(bufferobject.W_Buffer.typedef)
-        self.pythontypes.append(memoryobject.W_MemoryView.typedef)
-
-        # the set of implementation types
-        self.typeorder = {
-            objectobject.W_ObjectObject: [],
-            # XXX: Bool/Int/Long are pythontypes but still included here
-            # for delegation to Float/Complex
-            boolobject.W_BoolObject: [],
-            intobject.W_IntObject: [],
-            floatobject.W_FloatObject: [],
-            typeobject.W_TypeObject: [],
-            sliceobject.W_SliceObject: [],
-            longobject.W_LongObject: [],
-            noneobject.W_NoneObject: [],
-            complexobject.W_ComplexObject: [],
-            pypy.interpreter.pycode.PyCode: [],
-            pypy.interpreter.special.Ellipsis: [],
-            }
-
-        self.imported_but_not_registered = {
-            bytesobject.W_BytesObject: True,
-        }
-        for option, value in config.objspace.std:
-            if option.startswith("with") and option in option_to_typename:
-                for classname in option_to_typename[option]:
-                    modname = classname[:classname.index('.')]
-                    classname = classname[classname.index('.')+1:]
-                    d = {}
-                    exec "from pypy.objspace.std.%s import %s" % (
-                        modname, classname) in d
-                    implcls = d[classname]
-                    if value:
-                        self.typeorder[implcls] = []
-                    else:
-                        self.imported_but_not_registered[implcls] = True
-
-        # check if we missed implementations
-        for implcls in _registered_implementations:
-            if hasattr(implcls, 'register'):
-                implcls.register(self.typeorder)
-            assert (implcls in self.typeorder or
-                    implcls in self.imported_but_not_registered), (
-                "please add %r in StdTypeModel.typeorder" % (implcls,))
-
-
-        for type in self.typeorder:
-            self.typeorder[type].append((type, None))
-
-        # register the order in which types are converted into each others
-        # when trying to dispatch multimethods.
-        # XXX build these lists a bit more automatically later
-
-        if config.objspace.std.withsmalllong:
-            from pypy.objspace.std import smalllongobject
-            self.typeorder[smalllongobject.W_SmallLongObject] += [
-                (floatobject.W_FloatObject, smalllongobject.delegate_SmallLong2Float),
-                (complexobject.W_ComplexObject, smalllongobject.delegate_SmallLong2Complex),
-                ]
-
-        if config.objspace.std.withstrbuf:
-            from pypy.objspace.std import strbufobject
-
-        # put W_Root everywhere
-        self.typeorder[W_Root] = []
-        for type in self.typeorder:
-            from pypy.objspace.std import stdtypedef
-            if type is not W_Root and isinstance(type.typedef, stdtypedef.StdTypeDef):
-                self.typeorder[type].append((type.typedef.any, None))
-            self.typeorder[type].append((W_Root, None))
-
-        self._typeorder_with_empty_usersubcls = None
-
-        # ____________________________________________________________
-        # Prebuilt common integer values
-
-        if config.objspace.std.withprebuiltint:
-            intobject.W_IntObject.PREBUILT = []
-            for i in range(config.objspace.std.prebuiltintfrom,
-                           config.objspace.std.prebuiltintto):
-                intobject.W_IntObject.PREBUILT.append(intobject.W_IntObject(i))
-            del i
-        else:
-            intobject.W_IntObject.PREBUILT = None
-
-        # ____________________________________________________________
-
-    def get_typeorder_with_empty_usersubcls(self):
-        if self._typeorder_with_empty_usersubcls is None:
-            from pypy.interpreter.typedef import enum_interplevel_subclasses
-            from pypy.objspace.std import stdtypedef
-            result = self.typeorder.copy()
-            for cls in self.typeorder:
-                if (hasattr(cls, 'typedef') and cls.typedef is not None and
-                    cls.typedef.acceptable_as_base_class):
-                    subclslist = enum_interplevel_subclasses(self.config, cls)
-                    for subcls in subclslist:
-                        if cls in subcls.__bases__:   # only direct subclasses
-                            # for user subclasses we only accept "generic"
-                            # matches: "typedef.any" is the applevel-type-based
-                            # matching, and "W_Root" is ANY.
-                            matches = []
-                            if isinstance(cls.typedef, stdtypedef.StdTypeDef):
-                                matches.append((cls.typedef.any, None))
-                            matches.append((W_Root, None))
-                            result[subcls] = matches
-            self._typeorder_with_empty_usersubcls = result
-        return self._typeorder_with_empty_usersubcls
-
-def _op_negated(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):
-        return function(space, w_2, w_1)
-    return op
-
-def _op_swapped_negated(function):
-    def op(space, w_1, w_2):
-        return space.not_(function(space, w_2, w_1))
-    return op
-
-
-CMP_OPS = dict(lt='<', le='<=', eq='==', ne='!=', gt='>', ge='>=')
-CMP_CORRESPONDANCES = [
-    ('eq', 'ne', _op_negated),
-    ('lt', 'gt', _op_swapped),
-    ('le', 'ge', _op_swapped),
-    ('lt', 'ge', _op_negated),
-    ('le', 'gt', _op_negated),
-    ('lt', 'le', _op_swapped_negated),
-    ('gt', 'ge', _op_swapped_negated),
-    ]
-for op1, op2, value in CMP_CORRESPONDANCES[:]:
-    i = CMP_CORRESPONDANCES.index((op1, op2, value))
-    CMP_CORRESPONDANCES.insert(i+1, (op2, op1, value))
-BINARY_BITWISE_OPS = {'and': '&', 'lshift': '<<', 'or': '|', 'rshift': '>>',
-                      'xor': '^'}
-BINARY_OPS = dict(add='+', div='/', floordiv='//', mod='%', mul='*', sub='-',
-                  truediv='/', **BINARY_BITWISE_OPS)
-COMMUTATIVE_OPS = ('add', 'mul', 'and', 'or', 'xor')
-
-def add_extra_comparisons():
-    """
-    Add the missing comparison operators if they were not explicitly
-    defined:  eq <-> ne  and  lt <-> le <-> gt <-> ge.
-    We try to add them in the order defined by the CMP_CORRESPONDANCES
-    table, thus favouring swapping the arguments over negating the result.
-    """
-    originalentries = {}
-    for op in CMP_OPS.iterkeys():
-        originalentries[op] = getattr(MM, op).signatures()
-
-    for op1, op2, correspondance in CMP_CORRESPONDANCES:
-        mirrorfunc = getattr(MM, op2)
-        for types in originalentries[op1]:
-            t1, t2 = types
-            if t1 is t2:
-                if not mirrorfunc.has_signature(types):
-                    functions = getattr(MM, op1).getfunctions(types)
-                    assert len(functions) == 1, ('Automatic'
-                            ' registration of comparison functions'
-                            ' only work when there is a single method for'
-                            ' the operation.')
-                    mirrorfunc.register(correspondance(functions[0]), *types)
-
-
-# ____________________________________________________________
-
-W_ANY = W_Root
-
-class W_Object(W_Root):
-    "Parent base class for wrapped objects provided by the StdObjSpace."
-    # Note that not all wrapped objects in the interpreter inherit from
-    # W_Object.  (They inherit from W_Root.)
-    __slots__ = ()
-
-    def __repr__(self):
-        name = getattr(self, 'name', '')
-        if not isinstance(name, str):
-            name = ''
-        s = '%s(%s)' % (self.__class__.__name__, name)
-        w_cls = getattr(self, 'w__class__', None)
-        if w_cls is not None and w_cls is not self:
-            s += ' instance of %s' % self.w__class__
-        return '<%s>' % s
-
-
-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,972 +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()


More information about the pypy-commit mailing list