[pypy-commit] pypy dynamic-specialized-tuple: Merged default.

alex_gaynor noreply at buildbot.pypy.org
Tue Mar 27 23:31:09 CEST 2012


Author: Alex Gaynor <alex.gaynor at gmail.com>
Branch: dynamic-specialized-tuple
Changeset: r54038:c5b11dfcf240
Date: 2012-03-27 17:30 -0400
http://bitbucket.org/pypy/pypy/changeset/c5b11dfcf240/

Log:	Merged default.

diff --git a/lib-python/modified-2.7/site.py b/lib-python/modified-2.7/site.py
--- a/lib-python/modified-2.7/site.py
+++ b/lib-python/modified-2.7/site.py
@@ -550,9 +550,18 @@
                 "'import usercustomize' failed; use -v for traceback"
 
 
+def import_builtin_stuff():
+    """PyPy specific: pre-import a few built-in modules, because
+    some programs actually rely on them to be in sys.modules :-("""
+    import exceptions
+    if 'zipimport' in sys.builtin_module_names:
+        import zipimport
+
+
 def main():
     global ENABLE_USER_SITE
 
+    import_builtin_stuff()
     abs__file__()
     known_paths = removeduppaths()
     if (os.name == "posix" and sys.path and
diff --git a/lib-python/modified-2.7/test/test_set.py b/lib-python/modified-2.7/test/test_set.py
--- a/lib-python/modified-2.7/test/test_set.py
+++ b/lib-python/modified-2.7/test/test_set.py
@@ -1568,7 +1568,7 @@
             for meth in (s.union, s.intersection, s.difference, s.symmetric_difference, s.isdisjoint):
                 for g in (G, I, Ig, L, R):
                     expected = meth(data)
-                    actual = meth(G(data))
+                    actual = meth(g(data))
                     if isinstance(expected, bool):
                         self.assertEqual(actual, expected)
                     else:
diff --git a/lib_pypy/_locale.py b/lib_pypy/_locale.py
deleted file mode 100644
--- a/lib_pypy/_locale.py
+++ /dev/null
@@ -1,337 +0,0 @@
-# ctypes implementation of _locale module by Victor Stinner, 2008-03-27
-
-# ------------------------------------------------------------
-#  Note that we also have our own interp-level implementation
-# ------------------------------------------------------------
-
-"""
-Support for POSIX locales.
-"""
-
-from ctypes import (Structure, POINTER, create_string_buffer,
-    c_ubyte, c_int, c_char_p, c_wchar_p, c_size_t)
-from ctypes_support import standard_c_lib as libc
-from ctypes_support import get_errno
-
-# load the platform-specific cache made by running locale.ctc.py
-from ctypes_config_cache._locale_cache import *
-
-try: from __pypy__ import builtinify
-except ImportError: builtinify = lambda f: f
-
-
-# Ubuntu Gusty i386 structure
-class lconv(Structure):
-    _fields_ = (
-        # Numeric (non-monetary) information.
-        ("decimal_point", c_char_p),    # Decimal point character.
-        ("thousands_sep", c_char_p),    # Thousands separator.
-
-        # Each element is the number of digits in each group;
-        # elements with higher indices are farther left.
-        # An element with value CHAR_MAX means that no further grouping is done.
-        # An element with value 0 means that the previous element is used
-        # for all groups farther left.  */
-        ("grouping", c_char_p),
-
-        # Monetary information.
-
-        # First three chars are a currency symbol from ISO 4217.
-        # Fourth char is the separator.  Fifth char is '\0'.
-        ("int_curr_symbol", c_char_p),
-        ("currency_symbol", c_char_p),   # Local currency symbol.
-        ("mon_decimal_point", c_char_p), # Decimal point character.
-        ("mon_thousands_sep", c_char_p), # Thousands separator.
-        ("mon_grouping", c_char_p),      # Like `grouping' element (above).
-        ("positive_sign", c_char_p),     # Sign for positive values.
-        ("negative_sign", c_char_p),     # Sign for negative values.
-        ("int_frac_digits", c_ubyte),    # Int'l fractional digits.
-        ("frac_digits", c_ubyte),        # Local fractional digits.
-        # 1 if currency_symbol precedes a positive value, 0 if succeeds.
-        ("p_cs_precedes", c_ubyte),
-        # 1 iff a space separates currency_symbol from a positive value.
-        ("p_sep_by_space", c_ubyte),
-        # 1 if currency_symbol precedes a negative value, 0 if succeeds.
-        ("n_cs_precedes", c_ubyte),
-        # 1 iff a space separates currency_symbol from a negative value.
-        ("n_sep_by_space", c_ubyte),
-
-        # Positive and negative sign positions:
-        # 0 Parentheses surround the quantity and currency_symbol.
-        # 1 The sign string precedes the quantity and currency_symbol.
-        # 2 The sign string follows the quantity and currency_symbol.
-        # 3 The sign string immediately precedes the currency_symbol.
-        # 4 The sign string immediately follows the currency_symbol.
-        ("p_sign_posn", c_ubyte),
-        ("n_sign_posn", c_ubyte),
-        # 1 if int_curr_symbol precedes a positive value, 0 if succeeds.
-        ("int_p_cs_precedes", c_ubyte),
-        # 1 iff a space separates int_curr_symbol from a positive value.
-        ("int_p_sep_by_space", c_ubyte),
-        # 1 if int_curr_symbol precedes a negative value, 0 if succeeds.
-        ("int_n_cs_precedes", c_ubyte),
-        # 1 iff a space separates int_curr_symbol from a negative value.
-        ("int_n_sep_by_space", c_ubyte),
-         # Positive and negative sign positions:
-         # 0 Parentheses surround the quantity and int_curr_symbol.
-         # 1 The sign string precedes the quantity and int_curr_symbol.
-         # 2 The sign string follows the quantity and int_curr_symbol.
-         # 3 The sign string immediately precedes the int_curr_symbol.
-         # 4 The sign string immediately follows the int_curr_symbol.
-        ("int_p_sign_posn", c_ubyte),
-        ("int_n_sign_posn", c_ubyte),
-    )
-
-_setlocale = libc.setlocale
-_setlocale.argtypes = (c_int, c_char_p)
-_setlocale.restype = c_char_p
-
-_localeconv = libc.localeconv
-_localeconv.argtypes = None
-_localeconv.restype = POINTER(lconv)
-
-_strcoll = libc.strcoll
-_strcoll.argtypes = (c_char_p, c_char_p)
-_strcoll.restype = c_int
-
-_wcscoll = libc.wcscoll
-_wcscoll.argtypes = (c_wchar_p, c_wchar_p)
-_wcscoll.restype = c_int
-
-_strxfrm = libc.strxfrm
-_strxfrm.argtypes = (c_char_p, c_char_p, c_size_t)
-_strxfrm.restype = c_size_t
-
-HAS_LIBINTL = hasattr(libc, 'gettext')
-if HAS_LIBINTL:
-    _gettext = libc.gettext
-    _gettext.argtypes = (c_char_p,)
-    _gettext.restype = c_char_p
-
-    _dgettext = libc.dgettext
-    _dgettext.argtypes = (c_char_p, c_char_p)
-    _dgettext.restype = c_char_p
-
-    _dcgettext = libc.dcgettext
-    _dcgettext.argtypes = (c_char_p, c_char_p, c_int)
-    _dcgettext.restype = c_char_p
-
-    _textdomain = libc.textdomain
-    _textdomain.argtypes = (c_char_p,)
-    _textdomain.restype = c_char_p
-
-    _bindtextdomain = libc.bindtextdomain
-    _bindtextdomain.argtypes = (c_char_p, c_char_p)
-    _bindtextdomain.restype = c_char_p
-
-    HAS_BIND_TEXTDOMAIN_CODESET = hasattr(libc, 'bindtextdomain_codeset')
-    if HAS_BIND_TEXTDOMAIN_CODESET:
-        _bind_textdomain_codeset = libc.bindtextdomain_codeset
-        _bind_textdomain_codeset.argtypes = (c_char_p, c_char_p)
-        _bind_textdomain_codeset.restype = c_char_p
-
-class Error(Exception):
-    pass
-
-def fixup_ulcase():
-    import string
-    #import strop
-
-    # create uppercase map string
-    ul = []
-    for c in xrange(256):
-        c = chr(c)
-        if c.isupper():
-            ul.append(c)
-    ul = ''.join(ul)
-    string.uppercase = ul
-    #strop.uppercase = ul
-
-    # create lowercase string
-    ul = []
-    for c in xrange(256):
-        c = chr(c)
-        if c.islower():
-            ul.append(c)
-    ul = ''.join(ul)
-    string.lowercase = ul
-    #strop.lowercase = ul
-
-    # create letters string
-    ul = []
-    for c in xrange(256):
-        c = chr(c)
-        if c.isalpha():
-            ul.append(c)
-    ul = ''.join(ul)
-    string.letters = ul
-
- at builtinify
-def setlocale(category, locale=None):
-    "(integer,string=None) -> string. Activates/queries locale processing."
-    if locale:
-        # set locale
-        result = _setlocale(category, locale)
-        if not result:
-            raise Error("unsupported locale setting")
-
-        # record changes to LC_CTYPE
-        if category in (LC_CTYPE, LC_ALL):
-            fixup_ulcase()
-    else:
-        # get locale
-        result = _setlocale(category, None)
-        if not result:
-            raise Error("locale query failed")
-    return result
-
-def _copy_grouping(text):
-    groups = [ ord(group) for group in text ]
-    if groups:
-        groups.append(0)
-    return groups
-
- at builtinify
-def localeconv():
-    "() -> dict. Returns numeric and monetary locale-specific parameters."
-
-    # if LC_NUMERIC is different in the C library, use saved value
-    lp = _localeconv()
-    l = lp.contents
-
-    # hopefully, the localeconv result survives the C library calls
-    # involved herein
-
-    # Numeric information
-    result = {
-        "decimal_point": l.decimal_point,
-        "thousands_sep": l.thousands_sep,
-        "grouping": _copy_grouping(l.grouping),
-        "int_curr_symbol": l.int_curr_symbol,
-        "currency_symbol": l.currency_symbol,
-        "mon_decimal_point": l.mon_decimal_point,
-        "mon_thousands_sep": l.mon_thousands_sep,
-        "mon_grouping": _copy_grouping(l.mon_grouping),
-        "positive_sign": l.positive_sign,
-        "negative_sign": l.negative_sign,
-        "int_frac_digits": l.int_frac_digits,
-        "frac_digits": l.frac_digits,
-        "p_cs_precedes": l.p_cs_precedes,
-        "p_sep_by_space": l.p_sep_by_space,
-        "n_cs_precedes": l.n_cs_precedes,
-        "n_sep_by_space": l.n_sep_by_space,
-        "p_sign_posn": l.p_sign_posn,
-        "n_sign_posn": l.n_sign_posn,
-    }
-    return result
-
- at builtinify
-def strcoll(s1, s2):
-    "string,string -> int. Compares two strings according to the locale."
-
-    # If both arguments are byte strings, use strcoll.
-    if isinstance(s1, str) and isinstance(s2, str):
-        return _strcoll(s1, s2)
-
-    # If neither argument is unicode, it's an error.
-    if not isinstance(s1, unicode) and not isinstance(s2, unicode):
-        raise ValueError("strcoll arguments must be strings")
-
-    # Convert the non-unicode argument to unicode.
-    s1 = unicode(s1)
-    s2 = unicode(s2)
-
-    # Collate the strings.
-    return _wcscoll(s1, s2)
-
- at builtinify
-def strxfrm(s):
-    "string -> string. Returns a string that behaves for cmp locale-aware."
-
-    # assume no change in size, first
-    n1 = len(s) + 1
-    buf = create_string_buffer(n1)
-    n2 = _strxfrm(buf, s, n1) + 1
-    if n2 > n1:
-        # more space needed
-        buf = create_string_buffer(n2)
-        _strxfrm(buf, s, n2)
-    return buf.value
-
- at builtinify
-def getdefaultlocale():
-    # TODO: Port code from CPython for Windows and Mac OS
-    raise NotImplementedError()
-
-if HAS_LANGINFO:
-    _nl_langinfo = libc.nl_langinfo
-    _nl_langinfo.argtypes = (nl_item,)
-    _nl_langinfo.restype = c_char_p
-
-    def nl_langinfo(key):
-        """nl_langinfo(key) -> string
-        Return the value for the locale information associated with key."""
-        # Check whether this is a supported constant. GNU libc sometimes
-        # returns numeric values in the char* return value, which would
-        # crash PyString_FromString.
-        result = _nl_langinfo(key)
-        if result is not None:
-            return result
-        raise ValueError("unsupported langinfo constant")
-
-if HAS_LIBINTL:
-    @builtinify
-    def gettext(msg):
-        """gettext(msg) -> string
-        Return translation of msg."""
-        return _gettext(msg)
-
-    @builtinify
-    def dgettext(domain, msg):
-        """dgettext(domain, msg) -> string
-        Return translation of msg in domain."""
-        return _dgettext(domain, msg)
-
-    @builtinify
-    def dcgettext(domain, msg, category):
-        """dcgettext(domain, msg, category) -> string
-        Return translation of msg in domain and category."""
-        return _dcgettext(domain, msg, category)
-
-    @builtinify
-    def textdomain(domain):
-        """textdomain(domain) -> string
-        Set the C library's textdomain to domain, returning the new domain."""
-        return _textdomain(domain)
-
-    @builtinify
-    def bindtextdomain(domain, dir):
-        """bindtextdomain(domain, dir) -> string
-        Bind the C library's domain to dir."""
-        dirname = _bindtextdomain(domain, dir)
-        if not dirname:
-            errno = get_errno()
-            raise OSError(errno)
-        return dirname
-
-    if HAS_BIND_TEXTDOMAIN_CODESET:
-        @builtinify
-        def bind_textdomain_codeset(domain, codeset):
-            """bind_textdomain_codeset(domain, codeset) -> string
-            Bind the C library's domain to codeset."""
-            codeset = _bind_textdomain_codeset(domain, codeset)
-            if codeset:
-                return codeset
-            return None
-
-__all__ = (
-    'Error',
-    'setlocale', 'localeconv', 'strxfrm', 'strcoll',
-) + ALL_CONSTANTS
-if HAS_LIBINTL:
-    __all__ += ('gettext', 'dgettext', 'dcgettext', 'textdomain',
-                'bindtextdomain')
-    if HAS_BIND_TEXTDOMAIN_CODESET:
-        __all__ += ('bind_textdomain_codeset',)
-if HAS_LANGINFO:
-    __all__ += ('nl_langinfo',)
diff --git a/lib_pypy/array.py b/lib_pypy/array.py
deleted file mode 100644
--- a/lib_pypy/array.py
+++ /dev/null
@@ -1,531 +0,0 @@
-"""This module defines an object type which can efficiently represent
-an array of basic values: characters, integers, floating point
-numbers.  Arrays are sequence types and behave very much like lists,
-except that the type of objects stored in them is constrained.  The
-type is specified at object creation time by using a type code, which
-is a single character.  The following type codes are defined:
-
-    Type code   C Type             Minimum size in bytes 
-    'c'         character          1 
-    'b'         signed integer     1 
-    'B'         unsigned integer   1 
-    'u'         Unicode character  2 
-    'h'         signed integer     2 
-    'H'         unsigned integer   2 
-    'i'         signed integer     2 
-    'I'         unsigned integer   2 
-    'l'         signed integer     4 
-    'L'         unsigned integer   4 
-    'f'         floating point     4 
-    'd'         floating point     8 
-
-The constructor is:
-
-array(typecode [, initializer]) -- create a new array
-"""
-
-from struct import calcsize, pack, pack_into, unpack_from
-import operator
-
-# the buffer-like object to use internally: trying from
-# various places in order...
-try:
-    import _rawffi                    # a reasonable implementation based
-    _RAWARRAY = _rawffi.Array('c')    # on raw_malloc, and providing a
-    def bytebuffer(size):             # real address
-        return _RAWARRAY(size, autofree=True)
-    def getbufaddress(buf):
-        return buf.buffer
-except ImportError:
-    try:
-        from __pypy__ import bytebuffer     # a reasonable implementation
-        def getbufaddress(buf):             # compatible with oo backends,
-            return 0                        # but no address
-    except ImportError:
-        # not running on PyPy.  Fall back to ctypes...
-        import ctypes
-        bytebuffer = ctypes.create_string_buffer
-        def getbufaddress(buf):
-            voidp = ctypes.cast(ctypes.pointer(buf), ctypes.c_void_p)
-            return voidp.value
-
-# ____________________________________________________________
-
-TYPECODES = "cbBuhHiIlLfd"
-
-class array(object):
-    """array(typecode [, initializer]) -> array
-    
-    Return a new array whose items are restricted by typecode, and
-    initialized from the optional initializer value, which must be a list,
-    string. or iterable over elements of the appropriate type.
-    
-    Arrays represent basic values and behave very much like lists, except
-    the type of objects stored in them is constrained.
-    
-    Methods:
-    
-    append() -- append a new item to the end of the array
-    buffer_info() -- return information giving the current memory info
-    byteswap() -- byteswap all the items of the array
-    count() -- return number of occurences of an object
-    extend() -- extend array by appending multiple elements from an iterable
-    fromfile() -- read items from a file object
-    fromlist() -- append items from the list
-    fromstring() -- append items from the string
-    index() -- return index of first occurence of an object
-    insert() -- insert a new item into the array at a provided position
-    pop() -- remove and return item (default last)
-    read() -- DEPRECATED, use fromfile()
-    remove() -- remove first occurence of an object
-    reverse() -- reverse the order of the items in the array
-    tofile() -- write all items to a file object
-    tolist() -- return the array converted to an ordinary list
-    tostring() -- return the array converted to a string
-    write() -- DEPRECATED, use tofile()
-    
-    Attributes:
-    
-    typecode -- the typecode character used to create the array
-    itemsize -- the length in bytes of one array item
-    """
-    __slots__ = ["typecode", "itemsize", "_data", "_descriptor", "__weakref__"]
-
-    def __new__(cls, typecode, initializer=[], **extrakwds):
-        self = object.__new__(cls)
-        if cls is array and extrakwds:
-            raise TypeError("array() does not take keyword arguments")
-        if not isinstance(typecode, str) or len(typecode) != 1:
-            raise TypeError(
-                     "array() argument 1 must be char, not %s" % type(typecode))
-        if typecode not in TYPECODES:
-            raise ValueError(
-                  "bad typecode (must be one of %s)" % ', '.join(TYPECODES))
-        self._data = bytebuffer(0)
-        self.typecode = typecode
-        self.itemsize = calcsize(typecode)
-        if isinstance(initializer, list):
-            self.fromlist(initializer)
-        elif isinstance(initializer, str):
-            self.fromstring(initializer)
-        elif isinstance(initializer, unicode) and self.typecode == "u":
-            self.fromunicode(initializer)
-        else:
-            self.extend(initializer)
-        return self
-
-    def _clear(self):
-        self._data = bytebuffer(0)
-
-    ##### array-specific operations
-
-    def fromfile(self, f, n):
-        """Read n objects from the file object f and append them to the end of
-        the array. Also called as read."""
-        if not isinstance(f, file):
-            raise TypeError("arg1 must be open file")
-        size = self.itemsize * n
-        item = f.read(size)
-        if len(item) < size:
-            raise EOFError("not enough items in file")
-        self.fromstring(item)
-
-    def fromlist(self, l):
-        """Append items to array from list."""
-        if not isinstance(l, list):
-            raise TypeError("arg must be list")
-        self._fromiterable(l)
-        
-    def fromstring(self, s):
-        """Appends items from the string, interpreting it as an array of machine
-        values, as if it had been read from a file using the fromfile()
-        method."""
-        if isinstance(s, unicode):
-            s = str(s)
-        self._frombuffer(s)
-
-    def _frombuffer(self, s):
-        length = len(s)
-        if length % self.itemsize != 0:
-            raise ValueError("string length not a multiple of item size")
-        boundary = len(self._data)
-        newdata = bytebuffer(boundary + length)
-        newdata[:boundary] = self._data
-        newdata[boundary:] = s
-        self._data = newdata
-
-    def fromunicode(self, ustr):
-        """Extends this array with data from the unicode string ustr. The array
-        must be a type 'u' array; otherwise a ValueError is raised. Use
-        array.fromstring(ustr.encode(...)) to append Unicode data to an array of
-        some other type."""
-        if not self.typecode == "u":
-            raise ValueError(
-                          "fromunicode() may only be called on type 'u' arrays")
-        # XXX the following probable bug is not emulated:
-        # CPython accepts a non-unicode string or a buffer, and then
-        # behaves just like fromstring(), except that it strangely truncates
-        # string arguments at multiples of the unicode byte size.
-        # Let's only accept unicode arguments for now.
-        if not isinstance(ustr, unicode):
-            raise TypeError("fromunicode() argument should probably be "
-                            "a unicode string")
-        # _frombuffer() does the currect thing using
-        # the buffer behavior of unicode objects
-        self._frombuffer(buffer(ustr))
-
-    def tofile(self, f):
-        """Write all items (as machine values) to the file object f.  Also
-        called as write."""
-        if not isinstance(f, file):
-            raise TypeError("arg must be open file")
-        f.write(self.tostring())
-        
-    def tolist(self):
-        """Convert array to an ordinary list with the same items."""
-        count = len(self._data) // self.itemsize
-        return list(unpack_from('%d%s' % (count, self.typecode), self._data))
-
-    def tostring(self):
-        return self._data[:]
-
-    def __buffer__(self):
-        return buffer(self._data)
-
-    def tounicode(self):
-        """Convert the array to a unicode string. The array must be a type 'u'
-        array; otherwise a ValueError is raised. Use array.tostring().decode()
-        to obtain a unicode string from an array of some other type."""
-        if self.typecode != "u":
-            raise ValueError("tounicode() may only be called on type 'u' arrays")
-        # XXX performance is not too good
-        return u"".join(self.tolist())
-
-    def byteswap(self):
-        """Byteswap all items of the array.  If the items in the array are not
-        1, 2, 4, or 8 bytes in size, RuntimeError is raised."""
-        if self.itemsize not in [1, 2, 4, 8]:
-            raise RuntimeError("byteswap not supported for this array")
-        # XXX slowish
-        itemsize = self.itemsize
-        bytes = self._data
-        for start in range(0, len(bytes), itemsize):
-            stop = start + itemsize
-            bytes[start:stop] = bytes[start:stop][::-1]
-
-    def buffer_info(self):
-        """Return a tuple (address, length) giving the current memory address
-        and the length in items of the buffer used to hold array's contents. The
-        length should be multiplied by the itemsize attribute to calculate the
-        buffer length in bytes. On PyPy the address might be meaningless
-        (returned as 0), depending on the available modules."""
-        return (getbufaddress(self._data), len(self))
-    
-    read = fromfile
-
-    write = tofile
-
-    ##### general object protocol
-    
-    def __repr__(self):
-        if len(self._data) == 0:
-            return "array('%s')" % self.typecode
-        elif self.typecode == "c":
-            return "array('%s', %s)" % (self.typecode, repr(self.tostring()))
-        elif self.typecode == "u":
-            return "array('%s', %s)" % (self.typecode, repr(self.tounicode()))
-        else:
-            return "array('%s', %s)" % (self.typecode, repr(self.tolist()))
-
-    def __copy__(self):
-        a = array(self.typecode)
-        a._data = bytebuffer(len(self._data))
-        a._data[:] = self._data
-        return a
-
-    def __eq__(self, other):
-        if not isinstance(other, array):
-            return NotImplemented
-        if self.typecode == 'c':
-            return buffer(self._data) == buffer(other._data)
-        else:
-            return self.tolist() == other.tolist()
-
-    def __ne__(self, other):
-        if not isinstance(other, array):
-            return NotImplemented
-        if self.typecode == 'c':
-            return buffer(self._data) != buffer(other._data)
-        else:
-            return self.tolist() != other.tolist()
-
-    def __lt__(self, other):
-        if not isinstance(other, array):
-            return NotImplemented
-        if self.typecode == 'c':
-            return buffer(self._data) < buffer(other._data)
-        else:
-            return self.tolist() < other.tolist()
-
-    def __gt__(self, other):
-        if not isinstance(other, array):
-            return NotImplemented
-        if self.typecode == 'c':
-            return buffer(self._data) > buffer(other._data)
-        else:
-            return self.tolist() > other.tolist()
-
-    def __le__(self, other):
-        if not isinstance(other, array):
-            return NotImplemented
-        if self.typecode == 'c':
-            return buffer(self._data) <= buffer(other._data)
-        else:
-            return self.tolist() <= other.tolist()
-
-    def __ge__(self, other):
-        if not isinstance(other, array):
-            return NotImplemented
-        if self.typecode == 'c':
-            return buffer(self._data) >= buffer(other._data)
-        else:
-            return self.tolist() >= other.tolist()
-
-    def __reduce__(self):
-        dict = getattr(self, '__dict__', None)
-        data = self.tostring()
-        if data:
-            initargs = (self.typecode, data)
-        else:
-            initargs = (self.typecode,)
-        return (type(self), initargs, dict)
-
-    ##### list methods
-    
-    def append(self, x):
-        """Append new value x to the end of the array."""
-        self._frombuffer(pack(self.typecode, x))
-
-    def count(self, x):
-        """Return number of occurences of x in the array."""
-        return operator.countOf(self, x)
-
-    def extend(self, iterable):
-        """Append items to the end of the array."""
-        if isinstance(iterable, array) \
-                                    and not self.typecode == iterable.typecode:
-            raise TypeError("can only extend with array of same kind")
-        self._fromiterable(iterable)
-
-    def index(self, x):
-        """Return index of first occurence of x in the array."""
-        return operator.indexOf(self, x)
-    
-    def insert(self, i, x):
-        """Insert a new item x into the array before position i."""
-        seqlength = len(self)
-        if i < 0:
-            i += seqlength
-            if i < 0:
-                i = 0
-        elif i > seqlength:
-            i = seqlength
-        boundary = i * self.itemsize
-        data = pack(self.typecode, x)
-        newdata = bytebuffer(len(self._data) + len(data))
-        newdata[:boundary] = self._data[:boundary]
-        newdata[boundary:boundary+self.itemsize] = data
-        newdata[boundary+self.itemsize:] = self._data[boundary:]
-        self._data = newdata
-        
-    def pop(self, i=-1):
-        """Return the i-th element and delete it from the array. i defaults to
-        -1."""
-        seqlength = len(self)
-        if i < 0:
-            i += seqlength
-        if not (0 <= i < seqlength):
-            raise IndexError(i)
-        boundary = i * self.itemsize
-        result = unpack_from(self.typecode, self._data, boundary)[0]
-        newdata = bytebuffer(len(self._data) - self.itemsize)
-        newdata[:boundary] = self._data[:boundary]
-        newdata[boundary:] = self._data[boundary+self.itemsize:]
-        self._data = newdata
-        return result
-        
-    def remove(self, x):
-        """Remove the first occurence of x in the array."""
-        self.pop(self.index(x))
-        
-    def reverse(self):
-        """Reverse the order of the items in the array."""
-        lst = self.tolist()
-        lst.reverse()
-        self._clear()
-        self.fromlist(lst)
-
-    ##### list protocol
-    
-    def __len__(self):
-        return len(self._data) // self.itemsize
-    
-    def __add__(self, other):
-        if not isinstance(other, array):
-            raise TypeError("can only append array to array")
-        if self.typecode != other.typecode:
-            raise TypeError("bad argument type for built-in operation")
-        return array(self.typecode, buffer(self._data) + buffer(other._data))
-
-    def __mul__(self, repeat):
-        return array(self.typecode, buffer(self._data) * repeat)
-
-    __rmul__ = __mul__
-
-    def __getitem__(self, i):
-        seqlength = len(self)
-        if isinstance(i, slice):
-            start, stop, step = i.indices(seqlength)
-            if step != 1:
-                sublist = self.tolist()[i]    # fall-back
-                return array(self.typecode, sublist)
-            if start < 0:
-                start = 0
-            if stop < start:
-                stop = start
-            assert stop <= seqlength
-            return array(self.typecode, self._data[start * self.itemsize :
-                                                   stop * self.itemsize])
-        else:
-            if i < 0:
-                i += seqlength
-            if self.typecode == 'c':  # speed trick
-                return self._data[i]
-            if not (0 <= i < seqlength):
-                raise IndexError(i)
-            boundary = i * self.itemsize
-            return unpack_from(self.typecode, self._data, boundary)[0]
-
-    def __getslice__(self, i, j):
-        return self.__getitem__(slice(i, j))
-
-    def __setitem__(self, i, x):
-        if isinstance(i, slice):
-            if (not isinstance(x, array)
-                or self.typecode != x.typecode):
-                raise TypeError("can only assign array of same kind"
-                                " to array slice")
-            seqlength = len(self)
-            start, stop, step = i.indices(seqlength)
-            if step != 1:
-                sublist = self.tolist()    # fall-back
-                sublist[i] = x.tolist()
-                self._clear()
-                self.fromlist(sublist)
-                return
-            if start < 0:
-                start = 0
-            if stop < start:
-                stop = start
-            assert stop <= seqlength
-            boundary1 = start * self.itemsize
-            boundary2 = stop * self.itemsize
-            boundary2new = boundary1 + len(x._data)
-            if boundary2 == boundary2new:
-                self._data[boundary1:boundary2] = x._data
-            else:
-                newdata = bytebuffer(len(self._data) + boundary2new-boundary2)
-                newdata[:boundary1] = self._data[:boundary1]
-                newdata[boundary1:boundary2new] = x._data
-                newdata[boundary2new:] = self._data[boundary2:]
-                self._data = newdata
-        else:
-            seqlength = len(self)
-            if i < 0:
-                i += seqlength
-            if self.typecode == 'c':  # speed trick
-                self._data[i] = x
-                return
-            if not (0 <= i < seqlength):
-                raise IndexError(i)
-            boundary = i * self.itemsize
-            pack_into(self.typecode, self._data, boundary, x)
-
-    def __setslice__(self, i, j, x):
-        self.__setitem__(slice(i, j), x)
-
-    def __delitem__(self, i):
-        if isinstance(i, slice):
-            seqlength = len(self)
-            start, stop, step = i.indices(seqlength)
-            if start < 0:
-                start = 0
-            if stop < start:
-                stop = start
-            assert stop <= seqlength
-            if step != 1:
-                sublist = self.tolist()    # fall-back
-                del sublist[i]
-                self._clear()
-                self.fromlist(sublist)
-                return
-            dellength = stop - start
-            boundary1 = start * self.itemsize
-            boundary2 = stop * self.itemsize
-            newdata = bytebuffer(len(self._data) - (boundary2-boundary1))
-            newdata[:boundary1] = self._data[:boundary1]
-            newdata[boundary1:] = self._data[boundary2:]
-            self._data = newdata
-        else:            
-            seqlength = len(self)
-            if i < 0:
-                i += seqlength
-            if not (0 <= i < seqlength):
-                raise IndexError(i)
-            boundary = i * self.itemsize
-            newdata = bytebuffer(len(self._data) - self.itemsize)
-            newdata[:boundary] = self._data[:boundary]
-            newdata[boundary:] = self._data[boundary+self.itemsize:]
-            self._data = newdata
-
-    def __delslice__(self, i, j):
-        self.__delitem__(slice(i, j))
-
-    def __contains__(self, item):
-        for x in self:
-            if x == item:
-                return True
-        return False
-
-    def __iadd__(self, other):
-        if not isinstance(other, array):
-            raise TypeError("can only extend array with array")
-        self.extend(other)
-        return self
-
-    def __imul__(self, repeat):
-        newdata = buffer(self._data) * repeat
-        self._data = bytebuffer(len(newdata))
-        self._data[:] = newdata
-        return self
-
-    def __iter__(self):
-        p = 0
-        typecode = self.typecode
-        itemsize = self.itemsize
-        while p < len(self._data):
-            yield unpack_from(typecode, self._data, p)[0]
-            p += itemsize
-
-    ##### internal methods
-
-    def _fromiterable(self, iterable):
-        iterable = tuple(iterable)
-        n = len(iterable)
-        boundary = len(self._data)
-        newdata = bytebuffer(boundary + n * self.itemsize)
-        newdata[:boundary] = self._data
-        pack_into('%d%s' % (n, self.typecode), newdata, boundary, *iterable)
-        self._data = newdata
-
-ArrayType = array
diff --git a/lib_pypy/binascii.py b/lib_pypy/binascii.py
deleted file mode 100644
--- a/lib_pypy/binascii.py
+++ /dev/null
@@ -1,720 +0,0 @@
-"""A pure Python implementation of binascii.
-
-Rather slow and buggy in corner cases.
-PyPy provides an RPython version too.
-"""
-
-class Error(Exception):
-    pass
-
-class Done(Exception):
-    pass
-
-class Incomplete(Exception):
-    pass
-
-def a2b_uu(s):
-    if not s:
-        return ''
-    
-    length = (ord(s[0]) - 0x20) % 64
-
-    def quadruplets_gen(s):
-        while s:
-            try:
-                yield ord(s[0]), ord(s[1]), ord(s[2]), ord(s[3])
-            except IndexError:
-                s += '   '
-                yield ord(s[0]), ord(s[1]), ord(s[2]), ord(s[3])
-                return
-            s = s[4:]
-
-    try:
-        result = [''.join(
-            [chr((A - 0x20) << 2 | (((B - 0x20) >> 4) & 0x3)),
-            chr(((B - 0x20) & 0xf) << 4 | (((C - 0x20) >> 2) & 0xf)),
-            chr(((C - 0x20) & 0x3) << 6 | ((D - 0x20) & 0x3f))
-            ]) for A, B, C, D in quadruplets_gen(s[1:].rstrip())]
-    except ValueError:
-        raise Error('Illegal char')
-    result = ''.join(result)
-    trailingdata = result[length:]
-    if trailingdata.strip('\x00'):
-        raise Error('Trailing garbage')
-    result = result[:length]
-    if len(result) < length:
-        result += ((length - len(result)) * '\x00')
-    return result
-
-                               
-def b2a_uu(s):
-    length = len(s)
-    if length > 45:
-        raise Error('At most 45 bytes at once')
-
-    def triples_gen(s):
-        while s:
-            try:
-                yield ord(s[0]), ord(s[1]), ord(s[2])
-            except IndexError:
-                s += '\0\0'
-                yield ord(s[0]), ord(s[1]), ord(s[2])
-                return
-            s = s[3:]
-
-    result = [''.join(
-        [chr(0x20 + (( A >> 2                    ) & 0x3F)),
-         chr(0x20 + (((A << 4) | ((B >> 4) & 0xF)) & 0x3F)),
-         chr(0x20 + (((B << 2) | ((C >> 6) & 0x3)) & 0x3F)),
-         chr(0x20 + (( C                         ) & 0x3F))])
-              for A, B, C in triples_gen(s)]
-    return chr(ord(' ') + (length & 077)) + ''.join(result) + '\n'
-
-
-table_a2b_base64 = {
-    'A': 0,
-    'B': 1,
-    'C': 2,
-    'D': 3,
-    'E': 4,
-    'F': 5,
-    'G': 6,
-    'H': 7,
-    'I': 8,
-    'J': 9,
-    'K': 10,
-    'L': 11,
-    'M': 12,
-    'N': 13,
-    'O': 14,
-    'P': 15,
-    'Q': 16,
-    'R': 17,
-    'S': 18,
-    'T': 19,
-    'U': 20,
-    'V': 21,
-    'W': 22,
-    'X': 23,
-    'Y': 24,
-    'Z': 25,
-    'a': 26,
-    'b': 27,
-    'c': 28,
-    'd': 29,
-    'e': 30,
-    'f': 31,
-    'g': 32,
-    'h': 33,
-    'i': 34,
-    'j': 35,
-    'k': 36,
-    'l': 37,
-    'm': 38,
-    'n': 39,
-    'o': 40,
-    'p': 41,
-    'q': 42,
-    'r': 43,
-    's': 44,
-    't': 45,
-    'u': 46,
-    'v': 47,
-    'w': 48,
-    'x': 49,
-    'y': 50,
-    'z': 51,
-    '0': 52,
-    '1': 53,
-    '2': 54,
-    '3': 55,
-    '4': 56,
-    '5': 57,
-    '6': 58,
-    '7': 59,
-    '8': 60,
-    '9': 61,
-    '+': 62,
-    '/': 63,
-    '=': 0,
-}
-
-
-def a2b_base64(s):
-    if not isinstance(s, (str, unicode)):
-        raise TypeError("expected string or unicode, got %r" % (s,))
-    s = s.rstrip()
-    # clean out all invalid characters, this also strips the final '=' padding
-    # check for correct padding
-
-    def next_valid_char(s, pos):
-        for i in range(pos + 1, len(s)):
-            c = s[i]
-            if c < '\x7f':
-                try:
-                    table_a2b_base64[c]
-                    return c
-                except KeyError:
-                    pass
-        return None
-    
-    quad_pos = 0
-    leftbits = 0
-    leftchar = 0
-    res = []
-    for i, c in enumerate(s):
-        if c > '\x7f' or c == '\n' or c == '\r' or c == ' ':
-            continue
-        if c == '=':
-            if quad_pos < 2 or (quad_pos == 2 and next_valid_char(s, i) != '='):
-                continue
-            else:
-                leftbits = 0
-                break
-        try:
-            next_c = table_a2b_base64[c]
-        except KeyError:
-            continue
-        quad_pos = (quad_pos + 1) & 0x03
-        leftchar = (leftchar << 6) | next_c
-        leftbits += 6
-        if leftbits >= 8:
-            leftbits -= 8
-            res.append((leftchar >> leftbits & 0xff))
-            leftchar &= ((1 << leftbits) - 1)
-    if leftbits != 0:
-        raise Error('Incorrect padding')
-    
-    return ''.join([chr(i) for i in res])
-    
-table_b2a_base64 = \
-"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
-
-def b2a_base64(s):
-    length = len(s)
-    final_length = length % 3
-
-    def triples_gen(s):
-        while s:
-            try:
-                yield ord(s[0]), ord(s[1]), ord(s[2])
-            except IndexError:
-                s += '\0\0'
-                yield ord(s[0]), ord(s[1]), ord(s[2])
-                return
-            s = s[3:]
-
-    
-    a = triples_gen(s[ :length - final_length])
-
-    result = [''.join(
-        [table_b2a_base64[( A >> 2                    ) & 0x3F],
-         table_b2a_base64[((A << 4) | ((B >> 4) & 0xF)) & 0x3F],
-         table_b2a_base64[((B << 2) | ((C >> 6) & 0x3)) & 0x3F],
-         table_b2a_base64[( C                         ) & 0x3F]])
-              for A, B, C in a]
-
-    final = s[length - final_length:]
-    if final_length == 0:
-        snippet = ''
-    elif final_length == 1:
-        a = ord(final[0])
-        snippet = table_b2a_base64[(a >> 2 ) & 0x3F] + \
-                  table_b2a_base64[(a << 4 ) & 0x3F] + '=='
-    else:
-        a = ord(final[0])
-        b = ord(final[1])
-        snippet = table_b2a_base64[(a >> 2) & 0x3F] + \
-                  table_b2a_base64[((a << 4) | (b >> 4) & 0xF) & 0x3F] + \
-                  table_b2a_base64[(b << 2) & 0x3F] + '='
-    return ''.join(result) + snippet + '\n'
-
-def a2b_qp(s, header=False):
-    inp = 0
-    odata = []
-    while inp < len(s):
-        if s[inp] == '=':
-            inp += 1
-            if inp >= len(s):
-                break
-            # Soft line breaks
-            if (s[inp] == '\n') or (s[inp] == '\r'):
-                if s[inp] != '\n':
-                    while inp < len(s) and s[inp] != '\n':
-                        inp += 1
-                if inp < len(s):
-                    inp += 1
-            elif s[inp] == '=':
-                # broken case from broken python qp
-                odata.append('=')
-                inp += 1
-            elif s[inp] in hex_numbers and s[inp + 1] in hex_numbers:
-                ch = chr(int(s[inp:inp+2], 16))
-                inp += 2
-                odata.append(ch)
-            else:
-                odata.append('=')
-        elif header and s[inp] == '_':
-            odata.append(' ')
-            inp += 1
-        else:
-            odata.append(s[inp])
-            inp += 1
-    return ''.join(odata)
-
-def b2a_qp(data, quotetabs=False, istext=True, header=False):
-    """quotetabs=True means that tab and space characters are always
-       quoted.
-       istext=False means that \r and \n are treated as regular characters
-       header=True encodes space characters with '_' and requires
-       real '_' characters to be quoted.
-    """
-    MAXLINESIZE = 76
-
-    # See if this string is using CRLF line ends
-    lf = data.find('\n')
-    crlf = lf > 0 and data[lf-1] == '\r'
-
-    inp = 0
-    linelen = 0
-    odata = []
-    while inp < len(data):
-        c = data[inp]
-        if (c > '~' or
-            c == '=' or
-            (header and c == '_') or
-            (c == '.' and linelen == 0 and (inp+1 == len(data) or
-                                            data[inp+1] == '\n' or
-                                            data[inp+1] == '\r')) or
-            (not istext and (c == '\r' or c == '\n')) or
-            ((c == '\t' or c == ' ') and (inp + 1 == len(data))) or
-            (c <= ' ' and c != '\r' and c != '\n' and
-             (quotetabs or (not quotetabs and (c != '\t' and c != ' '))))):
-            linelen += 3
-            if linelen >= MAXLINESIZE:
-                odata.append('=')
-                if crlf: odata.append('\r')
-                odata.append('\n')
-                linelen = 3
-            odata.append('=' + two_hex_digits(ord(c)))
-            inp += 1
-        else:
-            if (istext and
-                (c == '\n' or (inp+1 < len(data) and c == '\r' and
-                               data[inp+1] == '\n'))):
-                linelen = 0
-                # Protect against whitespace on end of line
-                if (len(odata) > 0 and
-                    (odata[-1] == ' ' or odata[-1] == '\t')):
-                    ch = ord(odata[-1])
-                    odata[-1] = '='
-                    odata.append(two_hex_digits(ch))
-
-                if crlf: odata.append('\r')
-                odata.append('\n')
-                if c == '\r':
-                    inp += 2
-                else:
-                    inp += 1
-            else:
-                if (inp + 1 < len(data) and
-                    data[inp+1] != '\n' and
-                    (linelen + 1) >= MAXLINESIZE):
-                    odata.append('=')
-                    if crlf: odata.append('\r')
-                    odata.append('\n')
-                    linelen = 0
-
-                linelen += 1
-                if header and c == ' ':
-                    c = '_'
-                odata.append(c)
-                inp += 1
-    return ''.join(odata)
-
-hex_numbers = '0123456789ABCDEF'
-def hex(n):
-    if n == 0:
-        return '0'
-    
-    if n < 0:
-        n = -n
-        sign = '-'
-    else:
-        sign = ''
-    arr = []
-
-    def hex_gen(n):
-        """ Yield a nibble at a time. """
-        while n:
-            yield n % 0x10
-            n = n / 0x10
-
-    for nibble in hex_gen(n):
-        arr = [hex_numbers[nibble]] + arr
-    return sign + ''.join(arr)
-
-def two_hex_digits(n):
-    return hex_numbers[n / 0x10] + hex_numbers[n % 0x10]
-    
-
-def strhex_to_int(s):
-    i = 0
-    for c in s:
-        i = i * 0x10 + hex_numbers.index(c)
-    return i
-
-hqx_encoding = '!"#$%&\'()*+,-012345689 at ABCDEFGHIJKLMNPQRSTUVXYZ[`abcdefhijklmpqr'
-
-DONE = 0x7f
-SKIP = 0x7e
-FAIL = 0x7d
-    
-table_a2b_hqx = [
-    #^@    ^A    ^B    ^C    ^D    ^E    ^F    ^G   
-    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
-    #\b    \t    \n    ^K    ^L    \r    ^N    ^O   
-    FAIL, FAIL, SKIP, FAIL, FAIL, SKIP, FAIL, FAIL,
-    #^P    ^Q    ^R    ^S    ^T    ^U    ^V    ^W   
-    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
-    #^X    ^Y    ^Z    ^[    ^\    ^]    ^^    ^_   
-    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
-    #      !     "     #     $     %     &     '   
-    FAIL, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
-    #(     )     *     +     ,     -     .     /   
-    0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, FAIL, FAIL,
-    #0     1     2     3     4     5     6     7   
-    0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, FAIL,
-    #8     9     :     ;     <     =     >     ?   
-    0x14, 0x15, DONE, FAIL, FAIL, FAIL, FAIL, FAIL,
-    #@     A     B     C     D     E     F     G   
-    0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D,
-    #H     I     J     K     L     M     N     O   
-    0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, FAIL,
-    #P     Q     R     S     T     U     V     W   
-    0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, FAIL,
-    #X     Y     Z     [     \     ]     ^     _   
-    0x2C, 0x2D, 0x2E, 0x2F, FAIL, FAIL, FAIL, FAIL,
-    #`     a     b     c     d     e     f     g   
-    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, FAIL,
-    #h     i     j     k     l     m     n     o   
-    0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, FAIL, FAIL,
-    #p     q     r     s     t     u     v     w   
-    0x3D, 0x3E, 0x3F, FAIL, FAIL, FAIL, FAIL, FAIL,
-    #x     y     z     {     |     }     ~    ^?   
-    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
-    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
-    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
-    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
-    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
-    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
-    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
-    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
-    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
-    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
-    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
-    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
-    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
-    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
-    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
-    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
-    FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL, FAIL,
-]
-
-def a2b_hqx(s):
-    result = []
-
-    def quadruples_gen(s):
-        t = []
-        for c in s:
-            res = table_a2b_hqx[ord(c)]
-            if res == SKIP:
-                continue
-            elif res == FAIL:
-                raise Error('Illegal character')
-            elif res == DONE:
-                yield t
-                raise Done
-            else:
-                t.append(res)
-            if len(t) == 4:
-                yield t
-                t = []
-        yield t
-        
-    done = 0
-    try:
-        for snippet in quadruples_gen(s):
-            length = len(snippet)
-            if length == 4:
-                result.append(chr(((snippet[0] & 0x3f) << 2) | (snippet[1] >> 4))) 
-                result.append(chr(((snippet[1] & 0x0f) << 4) | (snippet[2] >> 2))) 
-                result.append(chr(((snippet[2] & 0x03) << 6) | (snippet[3]))) 
-            elif length == 3:
-                result.append(chr(((snippet[0] & 0x3f) << 2) | (snippet[1] >> 4))) 
-                result.append(chr(((snippet[1] & 0x0f) << 4) | (snippet[2] >> 2))) 
-            elif length == 2:
-                result.append(chr(((snippet[0] & 0x3f) << 2) | (snippet[1] >> 4))) 
-    except Done:
-        done = 1
-    except Error:
-        raise
-    return (''.join(result), done)
-
-def b2a_hqx(s):
-    result =[]
-
-    def triples_gen(s):
-        while s:
-            try:
-                yield ord(s[0]), ord(s[1]), ord(s[2])
-            except IndexError:
-                yield tuple([ord(c) for c in s])
-            s = s[3:]
-
-    for snippet in triples_gen(s):
-        length = len(snippet)
-        if length == 3:
-            result.append(
-                hqx_encoding[(snippet[0] & 0xfc) >> 2])
-            result.append(hqx_encoding[
-                ((snippet[0] & 0x03) << 4) | ((snippet[1] & 0xf0) >> 4)])
-            result.append(hqx_encoding[
-                (snippet[1] & 0x0f) << 2 | ((snippet[2] & 0xc0) >> 6)])
-            result.append(hqx_encoding[snippet[2] & 0x3f])
-        elif length == 2:
-            result.append(
-                hqx_encoding[(snippet[0] & 0xfc) >> 2])
-            result.append(hqx_encoding[
-                ((snippet[0] & 0x03) << 4) | ((snippet[1] & 0xf0) >> 4)])
-            result.append(hqx_encoding[
-                (snippet[1] & 0x0f) << 2])
-        elif length == 1:
-            result.append(
-                hqx_encoding[(snippet[0] & 0xfc) >> 2])
-            result.append(hqx_encoding[
-                ((snippet[0] & 0x03) << 4)])
-    return ''.join(result)
-
-crctab_hqx = [
-        0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
-        0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
-        0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
-        0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
-        0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
-        0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
-        0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
-        0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
-        0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
-        0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
-        0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
-        0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
-        0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
-        0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
-        0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
-        0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
-        0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
-        0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
-        0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
-        0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
-        0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
-        0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
-        0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
-        0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
-        0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
-        0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
-        0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
-        0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
-        0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
-        0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
-        0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
-        0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0,
-]
-
-def crc_hqx(s, crc):
-    for c in s:
-        crc = ((crc << 8) & 0xff00) ^ crctab_hqx[((crc >> 8) & 0xff) ^ ord(c)]
-
-    return crc
-
-def rlecode_hqx(s):
-    """
-    Run length encoding for binhex4.
-    The CPython implementation does not do run length encoding
-    of \x90 characters. This implementation does.
-    """
-    if not s:
-        return ''
-    result = []
-    prev = s[0]
-    count = 1
-    # Add a dummy character to get the loop to go one extra round.
-    # The dummy must be different from the last character of s.
-    # In the same step we remove the first character, which has
-    # already been stored in prev.
-    if s[-1] == '!':
-        s = s[1:] + '?'
-    else:
-        s = s[1:] + '!'
-        
-    for c in s:
-        if c == prev and count < 255:
-            count += 1
-        else:
-            if count == 1:
-                if prev != '\x90':
-                    result.append(prev)
-                else:
-                    result.extend(['\x90', '\x00'])
-            elif count < 4:
-                if prev != '\x90':
-                    result.extend([prev] * count)
-                else:
-                    result.extend(['\x90', '\x00'] * count)
-            else:
-                if prev != '\x90':
-                    result.extend([prev, '\x90', chr(count)])
-                else:
-                    result.extend(['\x90', '\x00', '\x90', chr(count)]) 
-            count = 1
-            prev = c
-        
-    return ''.join(result)
-
-def rledecode_hqx(s):
-    s = s.split('\x90')
-    result = [s[0]]
-    prev = s[0]
-    for snippet in s[1:]:
-        count = ord(snippet[0])
-        if count > 0:
-            result.append(prev[-1] * (count-1))
-            prev = snippet
-        else:
-            result. append('\x90')
-            prev = '\x90'
-        result.append(snippet[1:])
-
-    return ''.join(result)
-
-crc_32_tab = [
-    0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
-    0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
-    0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
-    0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
-    0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
-    0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
-    0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
-    0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
-    0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
-    0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
-    0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
-    0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
-    0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
-    0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
-    0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
-    0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
-    0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
-    0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
-    0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
-    0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
-    0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
-    0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
-    0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
-    0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
-    0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
-    0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
-    0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
-    0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
-    0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
-    0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
-    0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
-    0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
-    0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
-    0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
-    0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
-    0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
-    0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
-    0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
-    0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
-    0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
-    0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
-    0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
-    0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
-    0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
-    0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
-    0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
-    0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
-    0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
-    0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
-    0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
-    0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
-    0x2d02ef8dL
-]
-
-def crc32(s, crc=0):
-    result = 0
-    crc = ~long(crc) & 0xffffffffL
-    for c in s:
-        crc = crc_32_tab[(crc ^ long(ord(c))) & 0xffL] ^ (crc >> 8)
-        #/* Note:  (crc >> 8) MUST zero fill on left
-
-    result = crc ^ 0xffffffffL
-    
-    if result > 2**31:
-        result = ((result + 2**31) % 2**32) - 2**31
-
-    return result
-
-def b2a_hex(s):
-    result = []
-    for char in s:
-        c = (ord(char) >> 4) & 0xf
-        if c > 9:
-            c = c + ord('a') - 10
-        else:
-            c = c + ord('0')
-        result.append(chr(c))
-        c = ord(char) & 0xf
-        if c > 9:
-            c = c + ord('a') - 10
-        else:
-            c = c + ord('0')
-        result.append(chr(c))
-    return ''.join(result)
-
-hexlify = b2a_hex
-
-table_hex = [
-    -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
-    -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
-    -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
-    0, 1, 2, 3,  4, 5, 6, 7,  8, 9,-1,-1, -1,-1,-1,-1,
-    -1,10,11,12, 13,14,15,-1, -1,-1,-1,-1, -1,-1,-1,-1,
-    -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
-    -1,10,11,12, 13,14,15,-1, -1,-1,-1,-1, -1,-1,-1,-1,
-    -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1
-]
-
-
-def a2b_hex(t):
-    result = []
-
-    def pairs_gen(s):
-        while s:
-            try:
-                yield table_hex[ord(s[0])], table_hex[ord(s[1])]
-            except IndexError:
-                if len(s):
-                    raise TypeError('Odd-length string')
-                return
-            s = s[2:]
-
-    for a, b in pairs_gen(t):
-        if a < 0 or b < 0:
-            raise TypeError('Non-hexadecimal digit found')
-        result.append(chr((a << 4) + b))
-    return ''.join(result)
-    
-
-unhexlify = a2b_hex
diff --git a/lib_pypy/numpypy/core/numeric.py b/lib_pypy/numpypy/core/numeric.py
--- a/lib_pypy/numpypy/core/numeric.py
+++ b/lib_pypy/numpypy/core/numeric.py
@@ -306,6 +306,125 @@
     else:
         return multiarray.set_string_function(f, repr)
 
+def array_equal(a1, a2):
+    """
+    True if two arrays have the same shape and elements, False otherwise.
+
+    Parameters
+    ----------
+    a1, a2 : array_like
+        Input arrays.
+
+    Returns
+    -------
+    b : bool
+        Returns True if the arrays are equal.
+
+    See Also
+    --------
+    allclose: Returns True if two arrays are element-wise equal within a
+              tolerance.
+    array_equiv: Returns True if input arrays are shape consistent and all
+                 elements equal.
+
+    Examples
+    --------
+    >>> np.array_equal([1, 2], [1, 2])
+    True
+    >>> np.array_equal(np.array([1, 2]), np.array([1, 2]))
+    True
+    >>> np.array_equal([1, 2], [1, 2, 3])
+    False
+    >>> np.array_equal([1, 2], [1, 4])
+    False
+
+    """
+    try:
+        a1, a2 = asarray(a1), asarray(a2)
+    except:
+        return False
+    if a1.shape != a2.shape:
+        return False
+    return bool((a1 == a2).all())
+
+def asarray(a, dtype=None, order=None, maskna=None, ownmaskna=False):
+    """
+    Convert the input to an array.
+
+    Parameters
+    ----------
+    a : array_like
+        Input data, in any form that can be converted to an array.  This
+        includes lists, lists of tuples, tuples, tuples of tuples, tuples
+        of lists and ndarrays.
+    dtype : data-type, optional
+        By default, the data-type is inferred from the input data.
+    order : {'C', 'F'}, optional
+        Whether to use row-major ('C') or column-major ('F' for FORTRAN)
+        memory representation.  Defaults to 'C'.
+   maskna : bool or None, optional
+        If this is set to True, it forces the array to have an NA mask.
+        If this is set to False, it forces the array to not have an NA
+        mask.
+    ownmaskna : bool, optional
+        If this is set to True, forces the array to have a mask which
+        it owns.
+
+    Returns
+    -------
+    out : ndarray
+        Array interpretation of `a`.  No copy is performed if the input
+        is already an ndarray.  If `a` is a subclass of ndarray, a base
+        class ndarray is returned.
+
+    See Also
+    --------
+    asanyarray : Similar function which passes through subclasses.
+    ascontiguousarray : Convert input to a contiguous array.
+    asfarray : Convert input to a floating point ndarray.
+    asfortranarray : Convert input to an ndarray with column-major
+                     memory order.
+    asarray_chkfinite : Similar function which checks input for NaNs and Infs.
+    fromiter : Create an array from an iterator.
+    fromfunction : Construct an array by executing a function on grid
+                   positions.
+
+    Examples
+    --------
+    Convert a list into an array:
+
+    >>> a = [1, 2]
+    >>> np.asarray(a)
+    array([1, 2])
+
+    Existing arrays are not copied:
+
+    >>> a = np.array([1, 2])
+    >>> np.asarray(a) is a
+    True
+
+    If `dtype` is set, array is copied only if dtype does not match:
+
+    >>> a = np.array([1, 2], dtype=np.float32)
+    >>> np.asarray(a, dtype=np.float32) is a
+    True
+    >>> np.asarray(a, dtype=np.float64) is a
+    False
+
+    Contrary to `asanyarray`, ndarray subclasses are not passed through:
+
+    >>> issubclass(np.matrix, np.ndarray)
+    True
+    >>> a = np.matrix([[1, 2]])
+    >>> np.asarray(a) is a
+    False
+    >>> np.asanyarray(a) is a
+    True
+
+    """
+    return array(a, dtype, copy=False, order=order,
+                            maskna=maskna, ownmaskna=ownmaskna)
+
 set_string_function(array_str, 0)
 set_string_function(array_repr, 1)
 
diff --git a/lib_pypy/pypy_test/test_binascii.py b/lib_pypy/pypy_test/test_binascii.py
deleted file mode 100644
--- a/lib_pypy/pypy_test/test_binascii.py
+++ /dev/null
@@ -1,168 +0,0 @@
-from __future__ import absolute_import
-import py
-from lib_pypy import binascii
-
-# Create binary test data
-data = "The quick brown fox jumps over the lazy dog.\r\n"
-# Be slow so we don't depend on other modules
-data += "".join(map(chr, xrange(256)))
-data += "\r\nHello world.\n"
-
-def test_exceptions():
-    # Check module exceptions
-    assert issubclass(binascii.Error, Exception)
-    assert issubclass(binascii.Incomplete, Exception)
-
-def test_functions():
-    # Check presence of all functions
-    funcs = []
-    for suffix in "base64", "hqx", "uu", "hex":
-        prefixes = ["a2b_", "b2a_"]
-        if suffix == "hqx":
-            prefixes.extend(["crc_", "rlecode_", "rledecode_"])
-        for prefix in prefixes:
-            name = prefix + suffix
-            assert callable(getattr(binascii, name))
-            py.test.raises(TypeError, getattr(binascii, name))
-    for name in ("hexlify", "unhexlify"):
-        assert callable(getattr(binascii, name))
-        py.test.raises(TypeError, getattr(binascii, name))
-
-def test_base64valid():
-    # Test base64 with valid data
-    MAX_BASE64 = 57
-    lines = []
-    for i in range(0, len(data), MAX_BASE64):
-        b = data[i:i+MAX_BASE64]
-        a = binascii.b2a_base64(b)
-        lines.append(a)
-    res = ""
-    for line in lines:
-        b = binascii.a2b_base64(line)
-        res = res + b
-    assert res == data
-
-def test_base64invalid():
-    # Test base64 with random invalid characters sprinkled throughout
-    # (This requires a new version of binascii.)
-    MAX_BASE64 = 57
-    lines = []
-    for i in range(0, len(data), MAX_BASE64):
-        b = data[i:i+MAX_BASE64]
-        a = binascii.b2a_base64(b)
-        lines.append(a)
-
-    fillers = ""
-    valid = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/"
-    for i in xrange(256):
-        c = chr(i)
-        if c not in valid:
-            fillers += c
-    def addnoise(line):
-        noise = fillers
-        ratio = len(line) // len(noise)
-        res = ""
-        while line and noise:
-            if len(line) // len(noise) > ratio:
-                c, line = line[0], line[1:]
-            else:
-                c, noise = noise[0], noise[1:]
-            res += c
-        return res + noise + line
-    res = ""
-    for line in map(addnoise, lines):
-        b = binascii.a2b_base64(line)
-        res += b
-    assert res == data
-
-    # Test base64 with just invalid characters, which should return
-    # empty strings. TBD: shouldn't it raise an exception instead ?
-    assert binascii.a2b_base64(fillers) == ''
-
-def test_uu():
-    MAX_UU = 45
-    lines = []
-    for i in range(0, len(data), MAX_UU):
-        b = data[i:i+MAX_UU]
-        a = binascii.b2a_uu(b)
-        lines.append(a)
-    res = ""
-    for line in lines:
-        b = binascii.a2b_uu(line)
-        res += b
-    assert res == data
-
-    assert binascii.a2b_uu("\x7f") == "\x00"*31
-    assert binascii.a2b_uu("\x80") == "\x00"*32
-    assert binascii.a2b_uu("\xff") == "\x00"*31
-    py.test.raises(binascii.Error, binascii.a2b_uu, "\xff\x00")
-    py.test.raises(binascii.Error, binascii.a2b_uu, "!!!!")
-
-    py.test.raises(binascii.Error, binascii.b2a_uu, 46*"!")
-
-def test_crc32():
-    crc = binascii.crc32("Test the CRC-32 of")
-    crc = binascii.crc32(" this string.", crc)
-    assert crc == 1571220330
-    
-    crc = binascii.crc32('frotz\n', 0)
-    assert crc == -372923920
-
-    py.test.raises(TypeError, binascii.crc32)
-
-def test_hex():
-    # test hexlification
-    s = '{s\005\000\000\000worldi\002\000\000\000s\005\000\000\000helloi\001\000\000\0000'
-    t = binascii.b2a_hex(s)
-    u = binascii.a2b_hex(t)
-    assert s == u
-    py.test.raises(TypeError, binascii.a2b_hex, t[:-1])
-    py.test.raises(TypeError, binascii.a2b_hex, t[:-1] + 'q')
-
-    # Verify the treatment of Unicode strings
-    assert binascii.hexlify(unicode('a', 'ascii')) == '61'
-
-def test_qp():
-    # A test for SF bug 534347 (segfaults without the proper fix)
-    try:
-        binascii.a2b_qp("", **{1:1})
-    except TypeError:
-        pass
-    else:
-        fail("binascii.a2b_qp(**{1:1}) didn't raise TypeError")
-    assert binascii.a2b_qp("= ") == "= "
-    assert binascii.a2b_qp("==") == "="
-    assert binascii.a2b_qp("=AX") == "=AX"
-    py.test.raises(TypeError, binascii.b2a_qp, foo="bar")
-    assert binascii.a2b_qp("=00\r\n=00") == "\x00\r\n\x00"
-    assert binascii.b2a_qp("\xff\r\n\xff\n\xff") == "=FF\r\n=FF\r\n=FF"
-    target = "0"*75+"=\r\n=FF\r\n=FF\r\n=FF"
-    assert binascii.b2a_qp("0"*75+"\xff\r\n\xff\r\n\xff") == target
-
-def test_empty_string():
-    # A test for SF bug #1022953.  Make sure SystemError is not raised.
-    for n in ['b2a_qp', 'a2b_hex', 'b2a_base64', 'a2b_uu', 'a2b_qp',
-              'b2a_hex', 'unhexlify', 'hexlify', 'crc32', 'b2a_hqx',
-              'a2b_hqx', 'a2b_base64', 'rlecode_hqx', 'b2a_uu',
-              'rledecode_hqx']:
-        f = getattr(binascii, n)
-        f('')
-    binascii.crc_hqx('', 0)
-
-def test_qp_bug_case():
-    assert binascii.b2a_qp('y'*77, False, False) == 'y'*75 + '=\nyy'
-    assert binascii.b2a_qp(' '*77, False, False) == ' '*75 + '=\n =20'
-    assert binascii.b2a_qp('y'*76, False, False) == 'y'*76
-    assert binascii.b2a_qp(' '*76, False, False) == ' '*75 + '=\n=20'
-
-def test_wrong_padding():
-    s = 'CSixpLDtKSC/7Liuvsax4iC6uLmwMcijIKHaILzSwd/H0SC8+LCjwLsgv7W/+Mj3IQ'
-    py.test.raises(binascii.Error, binascii.a2b_base64, s)
-
-def test_crap_after_padding():
-    s = 'xxx=axxxx'
-    assert binascii.a2b_base64(s) == '\xc7\x1c'
-
-def test_wrong_args():
-    # this should grow as a way longer list
-    py.test.raises(TypeError, binascii.a2b_base64, 42)
diff --git a/lib_pypy/pypy_test/test_locale.py b/lib_pypy/pypy_test/test_locale.py
deleted file mode 100644
--- a/lib_pypy/pypy_test/test_locale.py
+++ /dev/null
@@ -1,79 +0,0 @@
-from __future__ import absolute_import
-import py
-import sys
-
-from lib_pypy.ctypes_config_cache import rebuild
-rebuild.rebuild_one('locale.ctc.py')
-
-from lib_pypy import _locale
-
-
-def setup_module(mod):
-    if sys.platform == 'darwin':
-        py.test.skip("Locale support on MacOSX is minimal and cannot be tested")
-
-class TestLocale:
-    def setup_class(cls):
-        cls.oldlocale = _locale.setlocale(_locale.LC_NUMERIC)
-        if sys.platform.startswith("win"):
-            cls.tloc = "en"
-        elif sys.platform.startswith("freebsd"):
-            cls.tloc = "en_US.US-ASCII"
-        else:
-            cls.tloc = "en_US.UTF8"
-        try:
-            _locale.setlocale(_locale.LC_NUMERIC, cls.tloc)
-        except _locale.Error:
-            py.test.skip("test locale %s not supported" % cls.tloc)
-            
-    def teardown_class(cls):
-        _locale.setlocale(_locale.LC_NUMERIC, cls.oldlocale)
-
-    def test_format(self):
-        py.test.skip("XXX fix or kill me")
-
-        def testformat(formatstr, value, grouping = 0, output=None):
-            if output:
-                print "%s %% %s =? %s ..." %\
-                      (repr(formatstr), repr(value), repr(output)),
-            else:
-                print "%s %% %s works? ..." % (repr(formatstr), repr(value)),
-            result = locale.format(formatstr, value, grouping = grouping)
-            assert result == output
-
-        testformat("%f", 1024, grouping=1, output='1,024.000000')
-        testformat("%f", 102, grouping=1, output='102.000000')
-        testformat("%f", -42, grouping=1, output='-42.000000')
-        testformat("%+f", -42, grouping=1, output='-42.000000')
-        testformat("%20.f", -42, grouping=1, output='                 -42')
-        testformat("%+10.f", -4200, grouping=1, output='    -4,200')
-        testformat("%-10.f", 4200, grouping=1, output='4,200     ')
-
-    def test_getpreferredencoding(self):
-        py.test.skip("XXX fix or kill me")
-        # Invoke getpreferredencoding to make sure it does not cause exceptions
-        _locale.getpreferredencoding()
-
-    # Test BSD Rune locale's bug for isctype functions.
-    def test_bsd_bug(self):
-        def teststrop(s, method, output):
-            print "%s.%s() =? %s ..." % (repr(s), method, repr(output)),
-            result = getattr(s, method)()
-            assert result == output
-
-        oldlocale = _locale.setlocale(_locale.LC_CTYPE)
-        _locale.setlocale(_locale.LC_CTYPE, self.tloc)
-        try:
-            teststrop('\x20', 'isspace', True)
-            teststrop('\xa0', 'isspace', False)
-            teststrop('\xa1', 'isspace', False)
-            teststrop('\xc0', 'isalpha', False)
-            teststrop('\xc0', 'isalnum', False)
-            teststrop('\xc0', 'isupper', False)
-            teststrop('\xc0', 'islower', False)
-            teststrop('\xec\xa0\xbc', 'split', ['\xec\xa0\xbc'])
-            teststrop('\xed\x95\xa0', 'strip', '\xed\x95\xa0')
-            teststrop('\xcc\x85', 'lower', '\xcc\x85')
-            teststrop('\xed\x95\xa0', 'upper', '\xed\x95\xa0')
-        finally:
-            _locale.setlocale(_locale.LC_CTYPE, oldlocale)
diff --git a/lib_pypy/pypy_test/test_site_extra.py b/lib_pypy/pypy_test/test_site_extra.py
new file mode 100644
--- /dev/null
+++ b/lib_pypy/pypy_test/test_site_extra.py
@@ -0,0 +1,13 @@
+import sys, os
+
+
+def test_preimported_modules():
+    lst = ['__builtin__', '_codecs', '_warnings', 'codecs', 'encodings',
+           'exceptions', 'signal', 'sys', 'zipimport']
+    g = os.popen("'%s' -c 'import sys; print sorted(sys.modules)'" %
+                 (sys.executable,))
+    real_data = g.read()
+    g.close()
+    for name in lst:
+        quoted_name = repr(name)
+        assert quoted_name in real_data
diff --git a/lib_pypy/pypy_test/test_struct_extra.py b/lib_pypy/pypy_test/test_struct_extra.py
deleted file mode 100644
--- a/lib_pypy/pypy_test/test_struct_extra.py
+++ /dev/null
@@ -1,25 +0,0 @@
-from __future__ import absolute_import
-from lib_pypy import struct 
-
-def test_simple():
-    morezeros = '\x00' * (struct.calcsize('l')-4)
-    assert struct.pack('<l', 16) == '\x10\x00\x00\x00' + morezeros
-    assert struct.pack('4s', 'WAVE') == 'WAVE'
-    assert struct.pack('<4sl', 'WAVE', 16) == 'WAVE\x10\x00\x00\x00' + morezeros
-    s = 'ABCD01234567\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00'
-    assert struct.unpack('<4s4H2lH', s) == ('ABCD', 0x3130, 0x3332, 0x3534,
-                                            0x3736, 1, 2, 3)
-
-def test_infinity():
-    INFINITY = 1e200 * 1e200
-    assert str(struct.unpack("!d", struct.pack("!d", INFINITY))[0]) \
-           == str(INFINITY)
-    assert str(struct.unpack("!d", struct.pack("!d", -INFINITY))[0]) \
-           == str(-INFINITY)
-
-def test_nan():
-    INFINITY = 1e200 * 1e200
-    NAN = INFINITY / INFINITY
-    assert str(struct.unpack("!d", '\xff\xf8\x00\x00\x00\x00\x00\x00')[0]) \
-           == str(NAN)
-    assert str(struct.unpack("!d", struct.pack("!d", NAN))[0]) == str(NAN)
diff --git a/lib_pypy/struct.py b/lib_pypy/struct.py
deleted file mode 100644
--- a/lib_pypy/struct.py
+++ /dev/null
@@ -1,417 +0,0 @@
-#
-# This module is a pure Python version of pypy.module.struct.
-# It is only imported if the vastly faster pypy.module.struct is not
-# compiled in.  For now we keep this version for reference and
-# because pypy.module.struct is not ootype-backend-friendly yet.
-#
-
-"""Functions to convert between Python values and C structs.
-Python strings are used to hold the data representing the C struct
-and also as format strings to describe the layout of data in the C struct.
-
-The optional first format char indicates byte order, size and alignment:
- @: native order, size & alignment (default)
- =: native order, std. size & alignment
- <: little-endian, std. size & alignment
- >: big-endian, std. size & alignment
- !: same as >
-
-The remaining chars indicate types of args and must match exactly;
-these can be preceded by a decimal repeat count:
-   x: pad byte (no data);
-   c:char;
-   b:signed byte;
-   B:unsigned byte;
-   h:short;
-   H:unsigned short;
-   i:int;
-   I:unsigned int;
-   l:long;
-   L:unsigned long;
-   f:float;
-   d:double.
-Special cases (preceding decimal count indicates length):
-   s:string (array of char); p: pascal string (with count byte).
-Special case (only available in native format):
-   P:an integer type that is wide enough to hold a pointer.
-Special case (not in native mode unless 'long long' in platform C):
-   q:long long;
-   Q:unsigned long long
-Whitespace between formats is ignored.
-
-The variable struct.error is an exception raised on errors."""
-
-import math, sys
-
-# TODO: XXX Find a way to get information on native sizes and alignments
-class StructError(Exception):
-    pass
-error = StructError
-def unpack_int(data,index,size,le):
-    bytes = [ord(b) for b in data[index:index+size]]
-    if le == 'little':
-        bytes.reverse()
-    number = 0L
-    for b in bytes:
-        number = number << 8 | b
-    return int(number)
-
-def unpack_signed_int(data,index,size,le):
-    number = unpack_int(data,index,size,le)
-    max = 2**(size*8)
-    if number > 2**(size*8 - 1) - 1:
-        number = int(-1*(max - number))
-    return number
-
-INFINITY = 1e200 * 1e200
-NAN = INFINITY / INFINITY
-
-def unpack_char(data,index,size,le):
-    return data[index:index+size]
-
-def pack_int(number,size,le):
-    x=number
-    res=[]
-    for i in range(size):
-        res.append(chr(x&0xff))
-        x >>= 8
-    if le == 'big':
-        res.reverse()
-    return ''.join(res)
-
-def pack_signed_int(number,size,le):
-    if not isinstance(number, (int,long)):
-        raise StructError,"argument for i,I,l,L,q,Q,h,H must be integer"
-    if  number > 2**(8*size-1)-1 or number < -1*2**(8*size-1):
-        raise OverflowError,"Number:%i too large to convert" % number
-    return pack_int(number,size,le)
-
-def pack_unsigned_int(number,size,le):
-    if not isinstance(number, (int,long)):
-        raise StructError,"argument for i,I,l,L,q,Q,h,H must be integer"
-    if number < 0:
-        raise TypeError,"can't convert negative long to unsigned"
-    if number > 2**(8*size)-1:
-        raise OverflowError,"Number:%i too large to convert" % number
-    return pack_int(number,size,le)
-
-def pack_char(char,size,le):
-    return str(char)
-
-def isinf(x):
-    return x != 0.0 and x / 2 == x
-def isnan(v):
-    return v != v*1.0 or (v == 1.0 and v == 2.0)
-
-def pack_float(x, size, le):
-    unsigned = float_pack(x, size)
-    result = []
-    for i in range(8):
-        result.append(chr((unsigned >> (i * 8)) & 0xFF))
-    if le == "big":
-        result.reverse()
-    return ''.join(result)
-
-def unpack_float(data, index, size, le):
-    binary = [data[i] for i in range(index, index + 8)]
-    if le == "big":
-        binary.reverse()
-    unsigned = 0
-    for i in range(8):
-        unsigned |= ord(binary[i]) << (i * 8)
-    return float_unpack(unsigned, size, le)
-
-def round_to_nearest(x):
-    """Python 3 style round:  round a float x to the nearest int, but
-    unlike the builtin Python 2.x round function:
-
-      - return an int, not a float
-      - do round-half-to-even, not round-half-away-from-zero.
-
-    We assume that x is finite and nonnegative; except wrong results
-    if you use this for negative x.
-
-    """
-    int_part = int(x)
-    frac_part = x - int_part
-    if frac_part > 0.5 or frac_part == 0.5 and int_part & 1 == 1:
-        int_part += 1
-    return int_part
-
-def float_unpack(Q, size, le):
-    """Convert a 32-bit or 64-bit integer created
-    by float_pack into a Python float."""
-
-    if size == 8:
-        MIN_EXP = -1021  # = sys.float_info.min_exp
-        MAX_EXP = 1024   # = sys.float_info.max_exp
-        MANT_DIG = 53    # = sys.float_info.mant_dig
-        BITS = 64
-    elif size == 4:
-        MIN_EXP = -125   # C's FLT_MIN_EXP
-        MAX_EXP = 128    # FLT_MAX_EXP
-        MANT_DIG = 24    # FLT_MANT_DIG
-        BITS = 32
-    else:
-        raise ValueError("invalid size value")
-
-    if Q >> BITS:
-         raise ValueError("input out of range")
-
-    # extract pieces
-    sign = Q >> BITS - 1
-    exp = (Q & ((1 << BITS - 1) - (1 << MANT_DIG - 1))) >> MANT_DIG - 1
-    mant = Q & ((1 << MANT_DIG - 1) - 1)
-
-    if exp == MAX_EXP - MIN_EXP + 2:
-        # nan or infinity
-        result = float('nan') if mant else float('inf')
-    elif exp == 0:
-        # subnormal or zero
-        result = math.ldexp(float(mant), MIN_EXP - MANT_DIG)
-    else:
-        # normal
-        mant += 1 << MANT_DIG - 1
-        result = math.ldexp(float(mant), exp + MIN_EXP - MANT_DIG - 1)
-    return -result if sign else result
-
-
-def float_pack(x, size):
-    """Convert a Python float x into a 64-bit unsigned integer
-    with the same byte representation."""
-
-    if size == 8:
-        MIN_EXP = -1021  # = sys.float_info.min_exp
-        MAX_EXP = 1024   # = sys.float_info.max_exp
-        MANT_DIG = 53    # = sys.float_info.mant_dig
-        BITS = 64
-    elif size == 4:
-        MIN_EXP = -125   # C's FLT_MIN_EXP
-        MAX_EXP = 128    # FLT_MAX_EXP
-        MANT_DIG = 24    # FLT_MANT_DIG
-        BITS = 32
-    else:
-        raise ValueError("invalid size value")
-
-    sign = math.copysign(1.0, x) < 0.0
-    if math.isinf(x):
-        mant = 0
-        exp = MAX_EXP - MIN_EXP + 2
-    elif math.isnan(x):
-        mant = 1 << (MANT_DIG-2) # other values possible
-        exp = MAX_EXP - MIN_EXP + 2
-    elif x == 0.0:
-        mant = 0
-        exp = 0
-    else:
-        m, e = math.frexp(abs(x))  # abs(x) == m * 2**e
-        exp = e - (MIN_EXP - 1)
-        if exp > 0:
-            # Normal case.
-            mant = round_to_nearest(m * (1 << MANT_DIG))
-            mant -= 1 << MANT_DIG - 1
-        else:
-            # Subnormal case.
-            if exp + MANT_DIG - 1 >= 0:
-                mant = round_to_nearest(m * (1 << exp + MANT_DIG - 1))
-            else:
-                mant = 0
-            exp = 0
-
-        # Special case: rounding produced a MANT_DIG-bit mantissa.
-        assert 0 <= mant <= 1 << MANT_DIG - 1
-        if mant == 1 << MANT_DIG - 1:
-            mant = 0
-            exp += 1
-
-        # Raise on overflow (in some circumstances, may want to return
-        # infinity instead).
-        if exp >= MAX_EXP - MIN_EXP + 2:
-             raise OverflowError("float too large to pack in this format")
-
-    # check constraints
-    assert 0 <= mant < 1 << MANT_DIG - 1
-    assert 0 <= exp <= MAX_EXP - MIN_EXP + 2
-    assert 0 <= sign <= 1
-    return ((sign << BITS - 1) | (exp << MANT_DIG - 1)) | mant
-
-
-big_endian_format = {
-    'x':{ 'size' : 1, 'alignment' : 0, 'pack' : None, 'unpack' : None},
-    'b':{ 'size' : 1, 'alignment' : 0, 'pack' : pack_signed_int, 'unpack' : unpack_signed_int},
-    'B':{ 'size' : 1, 'alignment' : 0, 'pack' : pack_unsigned_int, 'unpack' : unpack_int},
-    'c':{ 'size' : 1, 'alignment' : 0, 'pack' : pack_char, 'unpack' : unpack_char},
-    's':{ 'size' : 1, 'alignment' : 0, 'pack' : None, 'unpack' : None},
-    'p':{ 'size' : 1, 'alignment' : 0, 'pack' : None, 'unpack' : None},
-    'h':{ 'size' : 2, 'alignment' : 0, 'pack' : pack_signed_int, 'unpack' : unpack_signed_int},
-    'H':{ 'size' : 2, 'alignment' : 0, 'pack' : pack_unsigned_int, 'unpack' : unpack_int},
-    'i':{ 'size' : 4, 'alignment' : 0, 'pack' : pack_signed_int, 'unpack' : unpack_signed_int},
-    'I':{ 'size' : 4, 'alignment' : 0, 'pack' : pack_unsigned_int, 'unpack' : unpack_int},
-    'l':{ 'size' : 4, 'alignment' : 0, 'pack' : pack_signed_int, 'unpack' : unpack_signed_int},
-    'L':{ 'size' : 4, 'alignment' : 0, 'pack' : pack_unsigned_int, 'unpack' : unpack_int},
-    'q':{ 'size' : 8, 'alignment' : 0, 'pack' : pack_signed_int, 'unpack' : unpack_signed_int},
-    'Q':{ 'size' : 8, 'alignment' : 0, 'pack' : pack_unsigned_int, 'unpack' : unpack_int},
-    'f':{ 'size' : 4, 'alignment' : 0, 'pack' : pack_float, 'unpack' : unpack_float},
-    'd':{ 'size' : 8, 'alignment' : 0, 'pack' : pack_float, 'unpack' : unpack_float},
-    }
-default = big_endian_format
-formatmode={ '<' : (default, 'little'),
-             '>' : (default, 'big'),
-             '!' : (default, 'big'),
-             '=' : (default, sys.byteorder),
-             '@' : (default, sys.byteorder)
-            }
-
-def getmode(fmt):
-    try:
-        formatdef,endianness = formatmode[fmt[0]]
-        index = 1
-    except KeyError:
-        formatdef,endianness = formatmode['@']
-        index = 0
-    return formatdef,endianness,index
-def getNum(fmt,i):
-    num=None
-    cur = fmt[i]
-    while ('0'<= cur ) and ( cur <= '9'):
-        if num == None:
-            num = int(cur)
-        else:
-            num = 10*num + int(cur)
-        i += 1
-        cur = fmt[i]
-    return num,i
-
-def calcsize(fmt):
-    """calcsize(fmt) -> int
-    Return size of C struct described by format string fmt.
-    See struct.__doc__ for more on format strings."""
-
-    formatdef,endianness,i = getmode(fmt)
-    num = 0
-    result = 0
-    while i<len(fmt):
-        num,i = getNum(fmt,i)
-        cur = fmt[i]
-        try:
-            format = formatdef[cur]
-        except KeyError:
-            raise StructError,"%s is not a valid format"%cur
-        if num != None :
-            result += num*format['size']
-        else:
-            result += format['size']
-        num = 0
-        i += 1
-    return result
-
-def pack(fmt,*args):
-    """pack(fmt, v1, v2, ...) -> string
-       Return string containing values v1, v2, ... packed according to fmt.
-       See struct.__doc__ for more on format strings."""
-    formatdef,endianness,i = getmode(fmt)
-    args = list(args)
-    n_args = len(args)
-    result = []
-    while i<len(fmt):
-        num,i = getNum(fmt,i)
-        cur = fmt[i]
-        try:
-            format = formatdef[cur]
-        except KeyError:
-            raise StructError,"%s is not a valid format"%cur
-        if num == None :
-            num_s = 0
-            num = 1
-        else:
-            num_s = num
-
-        if cur == 'x':
-            result += ['\0'*num]
-        elif cur == 's':
-            if isinstance(args[0], str):
-                padding = num - len(args[0])
-                result += [args[0][:num] + '\0'*padding]
-                args.pop(0)
-            else:
-                raise StructError,"arg for string format not a string"
-        elif cur == 'p':
-            if isinstance(args[0], str):
-                padding = num - len(args[0]) - 1
-
-                if padding > 0:
-                    result += [chr(len(args[0])) + args[0][:num-1] + '\0'*padding]
-                else:
-                    if num<255:
-                        result += [chr(num-1) + args[0][:num-1]]
-                    else:
-                        result += [chr(255) + args[0][:num-1]]
-                args.pop(0)
-            else:
-                raise StructError,"arg for string format not a string"
-
-        else:
-            if len(args) < num:
-                raise StructError,"insufficient arguments to pack"
-            for var in args[:num]:
-                result += [format['pack'](var,format['size'],endianness)]
-            args=args[num:]
-        num = None
-        i += 1
-    if len(args) != 0:
-        raise StructError,"too many arguments for pack format"
-    return ''.join(result)
-
-def unpack(fmt,data):
-    """unpack(fmt, string) -> (v1, v2, ...)
-       Unpack the string, containing packed C structure data, according
-       to fmt.  Requires len(string)==calcsize(fmt).
-       See struct.__doc__ for more on format strings."""
-    formatdef,endianness,i = getmode(fmt)
-    j = 0
-    num = 0
-    result = []
-    length= calcsize(fmt)
-    if length != len (data):
-        raise StructError,"unpack str size does not match format"
-    while i<len(fmt):
-        num,i=getNum(fmt,i)
-        cur = fmt[i]
-        i += 1
-        try:
-            format = formatdef[cur]
-        except KeyError:
-            raise StructError,"%s is not a valid format"%cur
-
-        if not num :
-            num = 1
-
-        if cur == 'x':
-            j += num
-        elif cur == 's':
-            result.append(data[j:j+num])
-            j += num
-        elif cur == 'p':
-            n=ord(data[j])
-            if n >= num:
-                n = num-1
-            result.append(data[j+1:j+n+1])
-            j += num
-        else:
-            for n in range(num):
-                result += [format['unpack'](data,j,format['size'],endianness)]
-                j += format['size']
-
-    return tuple(result)
-
-def pack_into(fmt, buf, offset, *args):
-    data = pack(fmt, *args)
-    buffer(buf)[offset:offset+len(data)] = data
-
-def unpack_from(fmt, buf, offset=0):
-    size = calcsize(fmt)
-    data = buffer(buf)[offset:offset+size]
-    if len(data) != size:
-        raise error("unpack_from requires a buffer of at least %d bytes"
-                    % (size,))
-    return unpack(fmt, data)
diff --git a/pypy/doc/discussion/win64_todo.txt b/pypy/doc/discussion/win64_todo.txt
new file mode 100644
--- /dev/null
+++ b/pypy/doc/discussion/win64_todo.txt
@@ -0,0 +1,9 @@
+2011-11-04
+ll_os.py has a problem with the file rwin32.py.
+Temporarily disabled for the win64_gborg branch. This needs to be
+investigated and re-enabled.
+Resolved, enabled.
+
+2011-11-05
+test_typed.py needs explicit tests to ensure that we
+handle word sizes right.
\ No newline at end of file
diff --git a/pypy/doc/project-ideas.rst b/pypy/doc/project-ideas.rst
--- a/pypy/doc/project-ideas.rst
+++ b/pypy/doc/project-ideas.rst
@@ -103,21 +103,13 @@
 
 * A concurrent garbage collector (a lot of work)
 
-Remove the GIL
---------------
+STM, a.k.a. "remove the GIL"
+----------------------------
 
-This is a major task that requires lots of thinking. However, few subprojects
-can be potentially specified, unless a better plan can be thought out:
+Removing the GIL --- or more precisely, a GIL-less thread-less solution ---
+is `now work in progress.`__  Contributions welcome.
 
-* A thread-aware garbage collector
-
-* Better RPython primitives for dealing with concurrency
-
-* JIT passes to remove locks on objects
-
-* (maybe) implement locking in Python interpreter
-
-* alternatively, look at Software Transactional Memory
+.. __: http://pypy.org/tmdonate.html
 
 Introduce new benchmarks
 ------------------------
diff --git a/pypy/doc/sandbox.rst b/pypy/doc/sandbox.rst
--- a/pypy/doc/sandbox.rst
+++ b/pypy/doc/sandbox.rst
@@ -82,7 +82,10 @@
 
 In pypy/translator/goal::
 
-   ./translate.py --sandbox targetpypystandalone.py
+   ./translate.py -O2 --sandbox targetpypystandalone.py
+
+If you don't have a regular PyPy installed, you should, because it's
+faster to translate, but you can also run ``python translate.py`` instead.
 
 
 To run it, use the tools in the pypy/translator/sandbox directory::
diff --git a/pypy/doc/windows.rst b/pypy/doc/windows.rst
--- a/pypy/doc/windows.rst
+++ b/pypy/doc/windows.rst
@@ -18,7 +18,8 @@
 Edition.  Other configurations may work as well.
 
 The translation scripts will set up the appropriate environment variables
-for the compiler.  They will attempt to locate the same compiler version that
+for the compiler, so you do not need to run vcvars before translation.  
+They will attempt to locate the same compiler version that
 was used to build the Python interpreter doing the
 translation.  Failing that, they will pick the most recent Visual Studio
 compiler they can find.  In addition, the target architecture
@@ -26,7 +27,7 @@
 using a 32 bit Python and vice versa.
 
 **Note:** PyPy is currently not supported for 64 bit Windows, and translation
-will be aborted in this case.
+will fail in this case.
 
 The compiler is all you need to build pypy-c, but it will miss some
 modules that relies on third-party libraries.  See below how to get
@@ -57,7 +58,8 @@
 install third-party libraries.  We chose to install them in the parent
 directory of the pypy checkout.  For example, if you installed pypy in
 ``d:\pypy\trunk\`` (This directory contains a README file), the base
-directory is ``d:\pypy``.
+directory is ``d:\pypy``. You may choose different values by setting the
+INCLUDE, LIB and PATH (for DLLs)
 
 The Boehm garbage collector
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -126,18 +128,54 @@
 ------------------------
 
 You can compile pypy with the mingw compiler, using the --cc=mingw32 option;
-mingw.exe must be on the PATH.
+gcc.exe must be on the PATH. If the -cc flag does not begin with "ming", it should be
+the name of a valid gcc-derivative compiler, i.e. x86_64-w64-mingw32-gcc for the 64 bit
+compiler creating a 64 bit target.
 
-libffi for the mingw32 compiler
+libffi for the mingw compiler
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-To enable the _rawffi (and ctypes) module, you need to compile a mingw32
-version of libffi.  I downloaded the `libffi source files`_, and extracted
-them in the base directory.  Then run::
+To enable the _rawffi (and ctypes) module, you need to compile a mingw
+version of libffi.  Here is one way to do this, wich should allow you to try
+to build for win64 or win32:
+
+#. Download and unzip a `mingw32 build`_ or `mingw64 build`_, say into c:\mingw
+#. If you do not use cygwin, you will need msys to provide make, 
+   autoconf tools and other goodies.
+
+    #. Download and unzip a `msys for mingw`_, say into c:\msys
+    #. Edit the c:\msys\etc\fstab file to mount c:\mingw
+
+#. Download and unzip the `libffi source files`_, and extract
+   them in the base directory.  
+#. Run c:\msys\msys.bat or a cygwin shell which should make you
+   feel better since it is a shell prompt with shell tools.
+#. From inside the shell, cd to the libffi directory and do::
 
     sh ./configure
     make
     cp .libs/libffi-5.dll <somewhere on the PATH>
 
+If you can't find the dll, and the libtool issued a warning about 
+"undefined symbols not allowed", you will need to edit the libffi
+Makefile in the toplevel directory. Add the flag -no-undefined to
+the definition of libffi_la_LDFLAGS
+
+If you wish to experiment with win64, you must run configure with flags::
+
+    sh ./configure --build=x86_64-w64-mingw32 --host=x86_64-w64-mingw32
+
+or such, depending on your mingw64 download.
+
+hacking on Pypy with the mingw compiler
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Since hacking on Pypy means running tests, you will need a way to specify
+the mingw compiler when hacking (as opposed to translating). As of
+March 2012, --cc is not a valid option for pytest.py. However if you set an
+environment variable CC it will allow you to choose a compiler.
+
+.. _'mingw32 build': http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Automated%20Builds
+.. _`mingw64 build`: http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Automated%20Builds
+.. _`msys for mingw`: http://sourceforge.net/projects/mingw-w64/files/External%20binary%20packages%20%28Win64%20hosted%29/MSYS%20%2832-bit%29   
 .. _`libffi source files`: http://sourceware.org/libffi/
 .. _`RPython translation toolchain`: translation.html
diff --git a/pypy/doc/you-want-to-help.rst b/pypy/doc/you-want-to-help.rst
new file mode 100644
--- /dev/null
+++ b/pypy/doc/you-want-to-help.rst
@@ -0,0 +1,86 @@
+
+You want to help with PyPy, now what?
+=====================================
+
+PyPy is a very large project that has a reputation of being hard to dive into.
+Some of this fame is warranted, some of it is purely accidental. There are three
+important lessons that everyone willing to contribute should learn:
+
+* PyPy has layers. There are many pieces of architecture that are very well
+  separated from each other. More about this below, but often the manifestation
+  of this is that things are at a different layer than you would expect them
+  to be. For example if you are looking for the JIT implementation, you will
+  not find it in the implementation of the Python programming language.
+
+* Because of the above, we are very serious about Test Driven Development.
+  It's not only what we believe in, but also that PyPy's architecture is
+  working very well with TDD in mind and not so well without it. Often
+  the development means progressing in an unrelated corner, one unittest
+  at a time; and then flipping a giant switch, bringing it all together.
+  (It generally works out of the box.  If it doesn't, then we didn't
+  write enough unit tests.)  It's worth repeating - PyPy
+  approach is great if you do TDD, not so great otherwise.
+
+* PyPy uses an entirely different set of tools - most of them included
+  in the PyPy repository. There is no Makefile, nor autoconf. More below
+
+Architecture
+============
+
+PyPy has layers. The 100 miles view:
+
+* `RPython`_ is the language in which we write interpreters. Not the entire
+  PyPy project is written in RPython, only the parts that are compiled in
+  the translation process. The interesting point is that RPython has no parser,
+  it's compiled from the live python objects, which make it possible to do
+  all kinds of metaprogramming during import time. In short, Python is a meta
+  programming language for RPython.
+
+  The RPython standard library is to be found in the ``rlib`` subdirectory.
+
+.. _`RPython`: coding-guide.html#RPython
+
+* The translation toolchain - this is the part that takes care about translating
+  RPython to flow graphs and then to C. There is more in the `architecture`_
+  document written about it.
+
+  It mostly lives in ``rpython``, ``annotator`` and ``objspace/flow``.
+
+.. _`architecture`: architecture.html 
+
+* Python Interpreter
+
+  xxx
+
+* Python modules
+
+  xxx
+
+* Just-in-Time Compiler (JIT): `we have a tracing JIT`_ that traces the
+  interpreter written in RPython, rather than the user program that it
+  interprets.  As a result it applies to any interpreter, i.e. any
+  language.  But getting it to work correctly is not trivial: it
+  requires a small number of precise "hints" and possibly some small
+  refactorings of the interpreter.  The JIT itself also has several
+  almost-independent parts: the tracer itself in ``jit/metainterp``, the
+  optimizer in ``jit/metainterp/optimizer`` that optimizes a list of
+  residual operations, and the backend in ``jit/backend/<machine-name>``
+  that turns it into machine code.  Writing a new backend is a
+  traditional way to get into the project.
+
+.. _`we have a tracing JIT`: jit/index.html
+
+* Garbage Collectors (GC): as you can notice if you are used to CPython's
+  C code, there are no ``Py_INCREF/Py_DECREF`` equivalents in RPython code.
+  `Garbage collection in PyPy`_ is inserted
+  during translation.  Moreover, this is not reference counting; it is a real
+  GC written as more RPython code.  The best one we have so far is in
+  ``rpython/memory/gc/minimark.py``.
+
+.. _`Garbage collection in PyPy`: garbage_collection.html
+
+
+Toolset
+=======
+
+xxx
diff --git a/pypy/interpreter/astcompiler/test/test_astbuilder.py b/pypy/interpreter/astcompiler/test/test_astbuilder.py
--- a/pypy/interpreter/astcompiler/test/test_astbuilder.py
+++ b/pypy/interpreter/astcompiler/test/test_astbuilder.py
@@ -10,16 +10,6 @@
 from pypy.interpreter.astcompiler import ast, consts
 
 
-try:
-    all
-except NameError:
-    def all(iterable):
-        for x in iterable:
-            if not x:
-                return False
-        return True
-
-
 class TestAstBuilder:
 
     def setup_class(cls):
diff --git a/pypy/interpreter/test/test_objspace.py b/pypy/interpreter/test/test_objspace.py
--- a/pypy/interpreter/test/test_objspace.py
+++ b/pypy/interpreter/test/test_objspace.py
@@ -312,8 +312,8 @@
             mods = space.get_builtinmodule_to_install()
             
             assert '__pypy__' in mods                # real builtin
-            assert 'array' not in mods               # in lib_pypy
-            assert 'faked+array' not in mods         # in lib_pypy
+            assert '_functools' not in mods               # in lib_pypy
+            assert 'faked+_functools' not in mods         # in lib_pypy
             assert 'this_doesnt_exist' not in mods   # not in lib_pypy
             assert 'faked+this_doesnt_exist' in mods # not in lib_pypy, but in
                                                      # ALL_BUILTIN_MODULES
diff --git a/pypy/interpreter/test/test_zzpickle_and_slow.py b/pypy/interpreter/test/test_zzpickle_and_slow.py
--- a/pypy/interpreter/test/test_zzpickle_and_slow.py
+++ b/pypy/interpreter/test/test_zzpickle_and_slow.py
@@ -75,6 +75,7 @@
 class AppTestInterpObjectPickling:
     pytestmark = py.test.mark.skipif("config.option.runappdirect")
     def setup_class(cls):
+        cls.space = gettestobjspace(usemodules=['struct'])
         _attach_helpers(cls.space)
 
     def teardown_class(cls):
diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py
--- a/pypy/jit/backend/test/runner_test.py
+++ b/pypy/jit/backend/test/runner_test.py
@@ -27,6 +27,12 @@
 def constfloat(x):
     return ConstFloat(longlong.getfloatstorage(x))
 
+def boxlonglong(ll):
+    if longlong.is_64_bit:
+        return BoxInt(ll)
+    else:
+        return BoxFloat(ll)
+
 
 class Runner(object):
 
@@ -1623,6 +1629,11 @@
                                      [boxfloat(2.5)], t).value
         assert res == longlong2float.float2longlong(2.5)
 
+        bytes = longlong2float.float2longlong(2.5)
+        res = self.execute_operation(rop.CONVERT_LONGLONG_BYTES_TO_FLOAT,
+                                     [boxlonglong(res)], 'float').value
+        assert longlong.getrealfloat(res) == 2.5
+
     def test_ooops_non_gc(self):
         x = lltype.malloc(lltype.Struct('x'), flavor='raw')
         v = heaptracker.adr2int(llmemory.cast_ptr_to_adr(x))
diff --git a/pypy/jit/backend/test/test_random.py b/pypy/jit/backend/test/test_random.py
--- a/pypy/jit/backend/test/test_random.py
+++ b/pypy/jit/backend/test/test_random.py
@@ -328,6 +328,15 @@
     def produce_into(self, builder, r):
         self.put(builder, [r.choice(builder.intvars)])
 
+class CastLongLongToFloatOperation(AbstractFloatOperation):
+    def produce_into(self, builder, r):
+        if longlong.is_64_bit:
+            self.put(builder, [r.choice(builder.intvars)])
+        else:
+            if not builder.floatvars:
+                raise CannotProduceOperation
+            self.put(builder, [r.choice(builder.floatvars)])
+
 class CastFloatToIntOperation(AbstractFloatOperation):
     def produce_into(self, builder, r):
         if not builder.floatvars:
@@ -450,6 +459,7 @@
 OPERATIONS.append(CastFloatToIntOperation(rop.CAST_FLOAT_TO_INT))
 OPERATIONS.append(CastIntToFloatOperation(rop.CAST_INT_TO_FLOAT))
 OPERATIONS.append(CastFloatToIntOperation(rop.CONVERT_FLOAT_BYTES_TO_LONGLONG))
+OPERATIONS.append(CastLongLongToFloatOperation(rop.CONVERT_LONGLONG_BYTES_TO_FLOAT))
 
 OperationBuilder.OPERATIONS = OPERATIONS
 
diff --git a/pypy/jit/backend/x86/assembler.py b/pypy/jit/backend/x86/assembler.py
--- a/pypy/jit/backend/x86/assembler.py
+++ b/pypy/jit/backend/x86/assembler.py
@@ -1251,6 +1251,15 @@
         else:
             self.mov(loc0, resloc)
 
+    def genop_convert_longlong_bytes_to_float(self, op, arglocs, resloc):
+        loc0, = arglocs
+        if longlong.is_64_bit:
+            assert isinstance(resloc, RegLoc)
+            assert isinstance(loc0, RegLoc)
+            self.mc.MOVD(resloc, loc0)
+        else:
+            self.mov(loc0, resloc)
+
     def genop_guard_int_is_true(self, op, guard_op, guard_token, arglocs, resloc):
         guard_opnum = guard_op.getopnum()
         self.mc.CMP(arglocs[0], imm0)
diff --git a/pypy/jit/backend/x86/regalloc.py b/pypy/jit/backend/x86/regalloc.py
--- a/pypy/jit/backend/x86/regalloc.py
+++ b/pypy/jit/backend/x86/regalloc.py
@@ -773,10 +773,24 @@
             self.Perform(op, [loc0], loc1)
             self.xrm.possibly_free_var(op.getarg(0))
         else:
-            loc0 = self.xrm.loc(op.getarg(0))
+            arg0 = op.getarg(0)
+            loc0 = self.xrm.loc(arg0)
+            loc1 = self.xrm.force_allocate_reg(op.result, forbidden_vars=[arg0])
+            self.Perform(op, [loc0], loc1)
+            self.xrm.possibly_free_var(arg0)
+
+    def consider_convert_longlong_bytes_to_float(self, op):
+        if longlong.is_64_bit:
+            loc0 = self.rm.make_sure_var_in_reg(op.getarg(0))
             loc1 = self.xrm.force_allocate_reg(op.result)
             self.Perform(op, [loc0], loc1)
-            self.xrm.possibly_free_var(op.getarg(0))
+            self.rm.possibly_free_var(op.getarg(0))
+        else:
+            arg0 = op.getarg(0)
+            loc0 = self.xrm.make_sure_var_in_reg(arg0)
+            loc1 = self.xrm.force_allocate_reg(op.result, forbidden_vars=[arg0])
+            self.Perform(op, [loc0], loc1)
+            self.xrm.possibly_free_var(arg0)
 
     def _consider_llong_binop_xx(self, op):
         # must force both arguments into xmm registers, because we don't
diff --git a/pypy/jit/backend/x86/rx86.py b/pypy/jit/backend/x86/rx86.py
--- a/pypy/jit/backend/x86/rx86.py
+++ b/pypy/jit/backend/x86/rx86.py
@@ -601,7 +601,9 @@
     CVTSS2SD_xb = xmminsn('\xF3', rex_nw, '\x0F\x5A',
                           register(1, 8), stack_bp(2))
 
-    # These work on machine sized registers.
+    # These work on machine sized registers, so MOVD is actually MOVQ
+    # when running on 64 bits.  Note a bug in the Intel documentation:
+    # http://lists.gnu.org/archive/html/bug-binutils/2007-07/msg00095.html
     MOVD_rx = xmminsn('\x66', rex_w, '\x0F\x7E', register(2, 8), register(1), '\xC0')
     MOVD_xr = xmminsn('\x66', rex_w, '\x0F\x6E', register(1, 8), register(2), '\xC0')
     MOVD_xb = xmminsn('\x66', rex_w, '\x0F\x6E', register(1, 8), stack_bp(2))
diff --git a/pypy/jit/backend/x86/test/test_rx86_32_auto_encoding.py b/pypy/jit/backend/x86/test/test_rx86_32_auto_encoding.py
--- a/pypy/jit/backend/x86/test/test_rx86_32_auto_encoding.py
+++ b/pypy/jit/backend/x86/test/test_rx86_32_auto_encoding.py
@@ -182,6 +182,12 @@
         filename  = str(testdir.join(FILENAME  % methname))
         g = open(inputname, 'w')
         g.write('\x09.string "%s"\n' % BEGIN_TAG)
+        #
+        if instrname == 'MOVD' and self.WORD == 8:
+            instrname = 'MOVQ'
+            if argmodes == 'xb':
+                py.test.skip('"as" uses an undocumented alternate encoding??')
+        #
         for args in args_lists:
             suffix = ""
     ##        all = instr.as_all_suffixes
@@ -229,9 +235,6 @@
                 # movq $xxx, %rax => movl $xxx, %eax
                 suffix = 'l'
                 ops[1] = reduce_to_32bit(ops[1])
-            if instrname.lower() == 'movd':
-                ops[0] = reduce_to_32bit(ops[0])
-                ops[1] = reduce_to_32bit(ops[1])
             #
             op = '\t%s%s %s%s' % (instrname.lower(), suffix,
                                   ', '.join(ops), following)
diff --git a/pypy/jit/codewriter/jtransform.py b/pypy/jit/codewriter/jtransform.py
--- a/pypy/jit/codewriter/jtransform.py
+++ b/pypy/jit/codewriter/jtransform.py
@@ -313,6 +313,7 @@
         return op
 
     rewrite_op_convert_float_bytes_to_longlong = _noop_rewrite
+    rewrite_op_convert_longlong_bytes_to_float = _noop_rewrite
 
     # ----------
     # Various kinds of calls
diff --git a/pypy/jit/codewriter/test/test_flatten.py b/pypy/jit/codewriter/test/test_flatten.py
--- a/pypy/jit/codewriter/test/test_flatten.py
+++ b/pypy/jit/codewriter/test/test_flatten.py
@@ -968,14 +968,22 @@
             int_return %i2
         """, transform=True)
 
-    def test_convert_float_bytes_to_int(self):
-        from pypy.rlib.longlong2float import float2longlong
+    def test_convert_float_bytes(self):
+        from pypy.rlib.longlong2float import float2longlong, longlong2float
         def f(x):
-            return float2longlong(x)
+            ll = float2longlong(x)
+            return longlong2float(ll)
+        if longlong.is_64_bit:
+            tmp_var = "%i0"
+            result_var = "%f1"
+        else:
+            tmp_var = "%f1"
+            result_var = "%f2"
         self.encoding_test(f, [25.0], """
-            convert_float_bytes_to_longlong %f0 -> %i0
-            int_return %i0
-        """)
+            convert_float_bytes_to_longlong %%f0 -> %(tmp_var)s
+            convert_longlong_bytes_to_float %(tmp_var)s -> %(result_var)s
+            float_return %(result_var)s
+        """ % {"result_var": result_var, "tmp_var": tmp_var}, transform=True)
 
 
 def check_force_cast(FROM, TO, operations, value):
diff --git a/pypy/jit/metainterp/blackhole.py b/pypy/jit/metainterp/blackhole.py
--- a/pypy/jit/metainterp/blackhole.py
+++ b/pypy/jit/metainterp/blackhole.py
@@ -672,6 +672,11 @@
         a = longlong.getrealfloat(a)
         return longlong2float.float2longlong(a)
 
+    @arguments(LONGLONG_TYPECODE, returns="f")
+    def bhimpl_convert_longlong_bytes_to_float(a):
+        a = longlong2float.longlong2float(a)
+        return longlong.getfloatstorage(a)
+
     # ----------
     # control flow operations
 
diff --git a/pypy/jit/metainterp/pyjitpl.py b/pypy/jit/metainterp/pyjitpl.py
--- a/pypy/jit/metainterp/pyjitpl.py
+++ b/pypy/jit/metainterp/pyjitpl.py
@@ -224,6 +224,7 @@
                     'float_neg', 'float_abs',
                     'cast_ptr_to_int', 'cast_int_to_ptr',
                     'convert_float_bytes_to_longlong',
+                    'convert_longlong_bytes_to_float',
                     ]:
         exec py.code.Source('''
             @arguments("box")
diff --git a/pypy/jit/metainterp/resoperation.py b/pypy/jit/metainterp/resoperation.py
--- a/pypy/jit/metainterp/resoperation.py
+++ b/pypy/jit/metainterp/resoperation.py
@@ -420,6 +420,7 @@
     'CAST_FLOAT_TO_SINGLEFLOAT/1',
     'CAST_SINGLEFLOAT_TO_FLOAT/1',
     'CONVERT_FLOAT_BYTES_TO_LONGLONG/1',
+    'CONVERT_LONGLONG_BYTES_TO_FLOAT/1',
     #
     'INT_LT/2b',
     'INT_LE/2b',
diff --git a/pypy/jit/metainterp/test/test_ajit.py b/pypy/jit/metainterp/test/test_ajit.py
--- a/pypy/jit/metainterp/test/test_ajit.py
+++ b/pypy/jit/metainterp/test/test_ajit.py
@@ -1,3 +1,4 @@
+import math
 import sys
 
 import py
@@ -15,7 +16,7 @@
     loop_invariant, elidable, promote, jit_debug, assert_green,
     AssertGreenFailed, unroll_safe, current_trace_length, look_inside_iff,
     isconstant, isvirtual, promote_string, set_param, record_known_class)
-from pypy.rlib.longlong2float import float2longlong
+from pypy.rlib.longlong2float import float2longlong, longlong2float
 from pypy.rlib.rarithmetic import ovfcheck, is_valid_int
 from pypy.rpython.lltypesystem import lltype, llmemory, rffi
 from pypy.rpython.ootypesystem import ootype
@@ -3795,15 +3796,15 @@
         res = self.interp_operations(g, [1])
         assert res == 3
 
-    def test_float2longlong(self):
+    def test_float_bytes(self):
         def f(n):
-            return float2longlong(n)
+            ll = float2longlong(n)
+            return longlong2float(ll)
 
         for x in [2.5, float("nan"), -2.5, float("inf")]:
             # There are tests elsewhere to verify the correctness of this.
-            expected = float2longlong(x)
             res = self.interp_operations(f, [x])
-            assert longlong.getfloatstorage(res) == expected
+            assert res == x or math.isnan(x) and math.isnan(res)
 
 
 class TestLLtype(BaseLLtypeTests, LLJitMixin):
diff --git a/pypy/module/__builtin__/interp_memoryview.py b/pypy/module/__builtin__/interp_memoryview.py
--- a/pypy/module/__builtin__/interp_memoryview.py
+++ b/pypy/module/__builtin__/interp_memoryview.py
@@ -69,6 +69,10 @@
         return W_MemoryView(buf)
 
     def descr_buffer(self, space):
+        """Note that memoryview() objects in PyPy support buffer(), whereas
+        not in CPython; but CPython supports passing memoryview() to most
+        built-in functions that accept buffers, with the notable exception
+        of the buffer() built-in."""
         return space.wrap(self.buf)
 
     def descr_tobytes(self, space):
diff --git a/pypy/module/__pypy__/__init__.py b/pypy/module/__pypy__/__init__.py
--- a/pypy/module/__pypy__/__init__.py
+++ b/pypy/module/__pypy__/__init__.py
@@ -16,13 +16,15 @@
     appleveldefs = {}
     interpleveldefs = {}
     if sys.platform.startswith("linux"):
+        from pypy.module.__pypy__ import interp_time
         interpleveldefs["clock_gettime"] = "interp_time.clock_gettime"
         interpleveldefs["clock_getres"] = "interp_time.clock_getres"
         for name in [
             "CLOCK_REALTIME", "CLOCK_MONOTONIC", "CLOCK_MONOTONIC_RAW",
             "CLOCK_PROCESS_CPUTIME_ID", "CLOCK_THREAD_CPUTIME_ID"
         ]:
-            interpleveldefs[name] = "space.wrap(interp_time.%s)" % name
+            if getattr(interp_time, name) is not None:
+                interpleveldefs[name] = "space.wrap(interp_time.%s)" % name
 
 
 class Module(MixedModule):
diff --git a/pypy/module/__pypy__/interp_time.py b/pypy/module/__pypy__/interp_time.py
--- a/pypy/module/__pypy__/interp_time.py
+++ b/pypy/module/__pypy__/interp_time.py
@@ -1,3 +1,4 @@
+from __future__ import with_statement
 import sys
 
 from pypy.interpreter.error import exception_from_errno
diff --git a/pypy/module/_ast/test/test_ast.py b/pypy/module/_ast/test/test_ast.py
--- a/pypy/module/_ast/test/test_ast.py
+++ b/pypy/module/_ast/test/test_ast.py
@@ -1,9 +1,10 @@
 import py
-
+from pypy.conftest import gettestobjspace
 
 class AppTestAST:
 
     def setup_class(cls):
+        cls.space = gettestobjspace(usemodules=['struct'])
         cls.w_ast = cls.space.appexec([], """():
     import _ast
     return _ast""")
diff --git a/pypy/module/_codecs/test/test_codecs.py b/pypy/module/_codecs/test/test_codecs.py
--- a/pypy/module/_codecs/test/test_codecs.py
+++ b/pypy/module/_codecs/test/test_codecs.py
@@ -4,7 +4,7 @@
 
 class AppTestCodecs:
     def setup_class(cls):
-        space = gettestobjspace(usemodules=('unicodedata',))
+        space = gettestobjspace(usemodules=('unicodedata', 'struct'))
         cls.space = space
 
     def test_register_noncallable(self):
diff --git a/pypy/module/_continuation/test/test_zpickle.py b/pypy/module/_continuation/test/test_zpickle.py
--- a/pypy/module/_continuation/test/test_zpickle.py
+++ b/pypy/module/_continuation/test/test_zpickle.py
@@ -106,8 +106,9 @@
     version = 0
 
     def setup_class(cls):
-        cls.space = gettestobjspace(usemodules=('_continuation',),
+        cls.space = gettestobjspace(usemodules=('_continuation', 'struct'),
                                     CALL_METHOD=True)
+        cls.space.config.translation.continuation = True
         cls.space.appexec([], """():
             global continulet, A, __name__
 
diff --git a/pypy/module/_hashlib/test/test_hashlib.py b/pypy/module/_hashlib/test/test_hashlib.py
--- a/pypy/module/_hashlib/test/test_hashlib.py
+++ b/pypy/module/_hashlib/test/test_hashlib.py
@@ -3,7 +3,7 @@
 
 class AppTestHashlib:
     def setup_class(cls):
-        cls.space = gettestobjspace(usemodules=['_hashlib'])
+        cls.space = gettestobjspace(usemodules=['_hashlib', 'array', 'struct'])
 
     def test_simple(self):
         import _hashlib
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
@@ -158,7 +158,7 @@
 
 class AppTestOpen:
     def setup_class(cls):
-        cls.space = gettestobjspace(usemodules=['_io', '_locale'])
+        cls.space = gettestobjspace(usemodules=['_io', '_locale', 'array', 'struct'])
         tmpfile = udir.join('tmpfile').ensure()
         cls.w_tmpfile = cls.space.wrap(str(tmpfile))
 
diff --git a/pypy/module/_multiprocessing/test/test_connection.py b/pypy/module/_multiprocessing/test/test_connection.py
--- a/pypy/module/_multiprocessing/test/test_connection.py
+++ b/pypy/module/_multiprocessing/test/test_connection.py
@@ -92,7 +92,8 @@
 
 class AppTestSocketConnection(BaseConnectionTest):
     def setup_class(cls):
-        space = gettestobjspace(usemodules=('_multiprocessing', 'thread', 'signal'))
+        space = gettestobjspace(usemodules=('_multiprocessing', 'thread', 'signal',
+                                            'struct', 'array'))
         cls.space = space
         cls.w_connections = space.newlist([])
 
diff --git a/pypy/module/_socket/test/test_sock_app.py b/pypy/module/_socket/test/test_sock_app.py
--- a/pypy/module/_socket/test/test_sock_app.py
+++ b/pypy/module/_socket/test/test_sock_app.py
@@ -6,7 +6,7 @@
 from pypy.rpython.lltypesystem import lltype, rffi
 
 def setup_module(mod):
-    mod.space = gettestobjspace(usemodules=['_socket', 'array'])
+    mod.space = gettestobjspace(usemodules=['_socket', 'array', 'struct'])
     global socket
     import socket
     mod.w_socket = space.appexec([], "(): import _socket as m; return m")
@@ -372,10 +372,9 @@
     def test_socket_connect(self):
         import _socket, os
         s = _socket.socket(_socket.AF_INET, _socket.SOCK_STREAM, 0)
-        # XXX temporarily we use python.org to test, will have more robust tests
-        # in the absence of a network connection later when more parts of the
-        # socket API are implemented.  Currently skip the test if there is no
-        # connection.
+        # it would be nice to have a test which works even if there is no
+        # network connection. However, this one is "good enough" for now. Skip
+        # it if there is no connection.
         try:
             s.connect(("www.python.org", 80))
         except _socket.gaierror, ex:
diff --git a/pypy/module/_ssl/test/test_ssl.py b/pypy/module/_ssl/test/test_ssl.py
--- a/pypy/module/_ssl/test/test_ssl.py
+++ b/pypy/module/_ssl/test/test_ssl.py
@@ -90,7 +90,7 @@
 
 class AppTestConnectedSSL:
     def setup_class(cls):
-        space = gettestobjspace(usemodules=('_ssl', '_socket'))
+        space = gettestobjspace(usemodules=('_ssl', '_socket', 'struct'))
         cls.space = space
 
     def setup_method(self, method):
@@ -179,7 +179,7 @@
     # to exercise the poll() calls
 
     def setup_class(cls):
-        space = gettestobjspace(usemodules=('_ssl', '_socket'))
+        space = gettestobjspace(usemodules=('_ssl', '_socket', 'struct'))
         cls.space = space
         cls.space.appexec([], """():
             import socket; socket.setdefaulttimeout(1)
diff --git a/pypy/module/cpyext/test/conftest.py b/pypy/module/cpyext/test/conftest.py
--- a/pypy/module/cpyext/test/conftest.py
+++ b/pypy/module/cpyext/test/conftest.py
@@ -10,7 +10,7 @@
     return False
 
 def pytest_funcarg__space(request):
-    return gettestobjspace(usemodules=['cpyext', 'thread', '_rawffi'])
+    return gettestobjspace(usemodules=['cpyext', 'thread', '_rawffi', 'array'])
 
 def pytest_funcarg__api(request):
     return request.cls.api
diff --git a/pypy/module/cpyext/test/test_api.py b/pypy/module/cpyext/test/test_api.py
--- a/pypy/module/cpyext/test/test_api.py
+++ b/pypy/module/cpyext/test/test_api.py
@@ -19,7 +19,8 @@
 
 class BaseApiTest(LeakCheckingTest):
     def setup_class(cls):
-        cls.space = space = gettestobjspace(usemodules=['cpyext', 'thread', '_rawffi'])
+        cls.space = space = gettestobjspace(usemodules=['cpyext', 'thread', '_rawffi',
+                                                        'array'])
 
         # warm up reference counts:
         # - the posix module allocates a HCRYPTPROV on Windows
diff --git a/pypy/module/cpyext/test/test_arraymodule.py b/pypy/module/cpyext/test/test_arraymodule.py
--- a/pypy/module/cpyext/test/test_arraymodule.py
+++ b/pypy/module/cpyext/test/test_arraymodule.py
@@ -1,3 +1,4 @@
+from pypy.conftest import gettestobjspace
 from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase
 
 import py
diff --git a/pypy/module/cpyext/test/test_cpyext.py b/pypy/module/cpyext/test/test_cpyext.py
--- a/pypy/module/cpyext/test/test_cpyext.py
+++ b/pypy/module/cpyext/test/test_cpyext.py
@@ -35,7 +35,7 @@
 
 class AppTestApi:
     def setup_class(cls):
-        cls.space = gettestobjspace(usemodules=['cpyext', 'thread', '_rawffi'])
+        cls.space = gettestobjspace(usemodules=['cpyext', 'thread', '_rawffi', 'array'])
         from pypy.rlib.libffi import get_libc_name
         cls.w_libc = cls.space.wrap(get_libc_name())
 
@@ -165,8 +165,9 @@
         return leaking
 
 class AppTestCpythonExtensionBase(LeakCheckingTest):
+    
     def setup_class(cls):
-        cls.space = gettestobjspace(usemodules=['cpyext', 'thread', '_rawffi'])
+        cls.space = gettestobjspace(usemodules=['cpyext', 'thread', '_rawffi', 'array'])
         cls.space.getbuiltinmodule("cpyext")
         from pypy.module.imp.importing import importhook
         importhook(cls.space, "os") # warm up reference counts
diff --git a/pypy/module/cpyext/test/test_import.py b/pypy/module/cpyext/test/test_import.py
--- a/pypy/module/cpyext/test/test_import.py
+++ b/pypy/module/cpyext/test/test_import.py
@@ -19,7 +19,7 @@
                                          space.wrap('__name__'))) == 'foobar'
 
     def test_getmoduledict(self, space, api):
-        testmod = "binascii"
+        testmod = "_functools"
         w_pre_dict = api.PyImport_GetModuleDict()
         assert not space.is_true(space.contains(w_pre_dict, space.wrap(testmod)))
 
diff --git a/pypy/module/fcntl/test/test_fcntl.py b/pypy/module/fcntl/test/test_fcntl.py
--- a/pypy/module/fcntl/test/test_fcntl.py
+++ b/pypy/module/fcntl/test/test_fcntl.py
@@ -13,7 +13,7 @@
 
 class AppTestFcntl:
     def setup_class(cls):
-        space = gettestobjspace(usemodules=('fcntl', 'array'))
+        space = gettestobjspace(usemodules=('fcntl', 'array', 'struct'))
         cls.space = space
         tmpprefix = str(udir.ensure('test_fcntl', dir=1).join('tmp_'))
         cls.w_tmp = space.wrap(tmpprefix)
diff --git a/pypy/module/imp/test/test_import.py b/pypy/module/imp/test/test_import.py
--- a/pypy/module/imp/test/test_import.py
+++ b/pypy/module/imp/test/test_import.py
@@ -987,6 +987,10 @@
             os.environ['LANG'] = oldlang
 
 class AppTestImportHooks(object):
+
+    def setup_class(cls):
+        cls.space = gettestobjspace(usemodules=('struct',))
+    
     def test_meta_path(self):
         tried_imports = []
         class Importer(object):
diff --git a/pypy/module/itertools/test/test_itertools.py b/pypy/module/itertools/test/test_itertools.py
--- a/pypy/module/itertools/test/test_itertools.py
+++ b/pypy/module/itertools/test/test_itertools.py
@@ -891,7 +891,7 @@
 
 class AppTestItertools27:
     def setup_class(cls):
-        cls.space = gettestobjspace(usemodules=['itertools'])
+        cls.space = gettestobjspace(usemodules=['itertools', 'struct'])
         if cls.space.is_true(cls.space.appexec([], """():
             import sys; return sys.version_info < (2, 7)
             """)):
diff --git a/pypy/module/marshal/test/make_test_marshal.py b/pypy/module/marshal/test/make_test_marshal.py
deleted file mode 100644
--- a/pypy/module/marshal/test/make_test_marshal.py
+++ /dev/null
@@ -1,78 +0,0 @@
-
-TESTCASES = """\
-    None
-    False
-    True
-    StopIteration
-    Ellipsis
-    42
-    -17
-    sys.maxint
-    -1.25
-    -1.25 #2
-    2+5j
-    2+5j #2
-    42L
-    -1234567890123456789012345678901234567890L
-    hello   # not interned
-    "hello"
-    ()
-    (1, 2)
-    []
-    [3, 4]
-    {}
-    {5: 6, 7: 8}
-    func.func_code
-    scopefunc.func_code
-    u'hello'
-    set()
-    set([1, 2])
-    frozenset()
-    frozenset([3, 4])
-""".strip().split('\n')
-
-def readable(s):
-    for c, repl in (
-        ("'", '_quote_'), ('"', '_Quote_'), (':', '_colon_'), ('.', '_dot_'),
-        ('[', '_list_'), (']', '_tsil_'), ('{', '_dict_'), ('}', '_tcid_'),
-        ('-', '_minus_'), ('+', '_plus_'),
-        (',', '_comma_'), ('(', '_brace_'), (')', '_ecarb_') ):
-        s = s.replace(c, repl)
-    lis = list(s)
-    for i, c in enumerate(lis):
-        if c.isalnum() or c == '_':
-            continue
-        lis[i] = '_'
-    return ''.join(lis)
-
-print """class AppTestMarshal:
-"""
-for line in TESTCASES:
-    line = line.strip()
-    name = readable(line)
-    version = ''
-    extra = ''
-    if line.endswith('#2'):
-        version = ', 2'
-        extra = '; assert len(s) in (9, 17)'
-    src = '''\
-    def test_%(name)s(self):
-        import sys
-        hello = "he"
-        hello += "llo"
-        def func(x):
-            return lambda y: x+y
-        scopefunc = func(42)
-        import marshal, StringIO
-        case = %(line)s
-        print "case: %%-30s   func=%(name)s" %% (case, )
-        s = marshal.dumps(case%(version)s)%(extra)s
-        x = marshal.loads(s)
-        assert x == case
-        f = StringIO.StringIO()
-        marshal.dump(case, f)
-        f.seek(0)
-        x = marshal.load(f)
-        assert x == case
-''' % {'name': name, 'line': line, 'version' : version, 'extra': extra}
-    print src
diff --git a/pypy/module/math/test/test_math.py b/pypy/module/math/test/test_math.py
--- a/pypy/module/math/test/test_math.py
+++ b/pypy/module/math/test/test_math.py
@@ -6,7 +6,7 @@
 
 class AppTestMath:
     def setup_class(cls):
-        cls.space = gettestobjspace(usemodules=['math'])
+        cls.space = gettestobjspace(usemodules=['math', 'struct'])
         cls.w_cases = cls.space.wrap(test_direct.MathTests.TESTCASES)
         cls.w_consistent_host = cls.space.wrap(test_direct.consistent_host)
 
diff --git a/pypy/module/micronumpy/app_numpy.py b/pypy/module/micronumpy/app_numpy.py
--- a/pypy/module/micronumpy/app_numpy.py
+++ b/pypy/module/micronumpy/app_numpy.py
@@ -16,7 +16,7 @@
         a[i][i] = 1
     return a
 
-def sum(a,axis=None):
+def sum(a,axis=None, out=None):
     '''sum(a, axis=None)
     Sum of array elements over a given axis.
 
@@ -43,17 +43,17 @@
     # TODO: add to doc (once it's implemented): cumsum : Cumulative sum of array elements.
     if not hasattr(a, "sum"):
         a = _numpypy.array(a)
-    return a.sum(axis)
+    return a.sum(axis=axis, out=out)
 
-def min(a, axis=None):
+def min(a, axis=None, out=None):
     if not hasattr(a, "min"):
         a = _numpypy.array(a)
-    return a.min(axis)
+    return a.min(axis=axis, out=out)
 
-def max(a, axis=None):
+def max(a, axis=None, out=None):
     if not hasattr(a, "max"):
         a = _numpypy.array(a)
-    return a.max(axis)
+    return a.max(axis=axis, out=out)
 
 def arange(start, stop=None, step=1, dtype=None):
     '''arange([start], stop[, step], dtype=None)
diff --git a/pypy/module/micronumpy/interp_boxes.py b/pypy/module/micronumpy/interp_boxes.py
--- a/pypy/module/micronumpy/interp_boxes.py
+++ b/pypy/module/micronumpy/interp_boxes.py
@@ -62,21 +62,24 @@
         return space.wrap(dtype.itemtype.bool(self))
 
     def _binop_impl(ufunc_name):
-        def impl(self, space, w_other):
+        def impl(self, space, w_other, w_out=None):
             from pypy.module.micronumpy import interp_ufuncs
-            return getattr(interp_ufuncs.get(space), ufunc_name).call(space, [self, w_other])
+            return getattr(interp_ufuncs.get(space), ufunc_name).call(space,
+                                                            [self, w_other, w_out])
         return func_with_new_name(impl, "binop_%s_impl" % ufunc_name)
 
     def _binop_right_impl(ufunc_name):
-        def impl(self, space, w_other):
+        def impl(self, space, w_other, w_out=None):
             from pypy.module.micronumpy import interp_ufuncs
-            return getattr(interp_ufuncs.get(space), ufunc_name).call(space, [w_other, self])
+            return getattr(interp_ufuncs.get(space), ufunc_name).call(space, 
+                                                            [w_other, self, w_out])
         return func_with_new_name(impl, "binop_right_%s_impl" % ufunc_name)
 
     def _unaryop_impl(ufunc_name):
-        def impl(self, space):
+        def impl(self, space, w_out=None):
             from pypy.module.micronumpy import interp_ufuncs
-            return getattr(interp_ufuncs.get(space), ufunc_name).call(space, [self])
+            return getattr(interp_ufuncs.get(space), ufunc_name).call(space,
+                                                                    [self, w_out])
         return func_with_new_name(impl, "unaryop_%s_impl" % ufunc_name)
 
     descr_add = _binop_impl("add")
diff --git a/pypy/module/micronumpy/interp_dtype.py b/pypy/module/micronumpy/interp_dtype.py
--- a/pypy/module/micronumpy/interp_dtype.py
+++ b/pypy/module/micronumpy/interp_dtype.py
@@ -359,6 +359,7 @@
             name="int64",
             char="q",
             w_box_type=space.gettypefor(interp_boxes.W_Int64Box),
+            alternate_constructors=[space.w_long],
         )
         self.w_uint64dtype = W_Dtype(
             types.UInt64(),
@@ -386,23 +387,6 @@
             alternate_constructors=[space.w_float],
             aliases=["float"],
         )
-        self.w_longlongdtype = W_Dtype(
-            types.Int64(),
-            num=9,
-            kind=SIGNEDLTR,
-            name='int64',
-            char='q',
-            w_box_type = space.gettypefor(interp_boxes.W_LongLongBox),
-            alternate_constructors=[space.w_long],
-        )
-        self.w_ulonglongdtype = W_Dtype(
-            types.UInt64(),
-            num=10,
-            kind=UNSIGNEDLTR,
-            name='uint64',
-            char='Q',
-            w_box_type = space.gettypefor(interp_boxes.W_ULongLongBox),
-        )
         self.w_stringdtype = W_Dtype(
             types.StringType(1),
             num=18,
@@ -435,17 +419,19 @@
             self.w_booldtype, self.w_int8dtype, self.w_uint8dtype,
             self.w_int16dtype, self.w_uint16dtype, self.w_int32dtype,
             self.w_uint32dtype, self.w_longdtype, self.w_ulongdtype,
-            self.w_longlongdtype, self.w_ulonglongdtype,
+            self.w_int64dtype, self.w_uint64dtype,
             self.w_float32dtype,
             self.w_float64dtype, self.w_stringdtype, self.w_unicodedtype,
             self.w_voiddtype,
         ]
-        self.dtypes_by_num_bytes = sorted(
+        self.float_dtypes_by_num_bytes = sorted(
             (dtype.itemtype.get_element_size(), dtype)
-            for dtype in self.builtin_dtypes
+            for dtype in [self.w_float32dtype, self.w_float64dtype]
         )
         self.dtypes_by_name = {}
-        for dtype in self.builtin_dtypes:
+        # we reverse, so the stuff with lower numbers override stuff with
+        # higher numbers
+        for dtype in reversed(self.builtin_dtypes):
             self.dtypes_by_name[dtype.name] = dtype
             can_name = dtype.kind + str(dtype.itemtype.get_element_size())
             self.dtypes_by_name[can_name] = dtype
@@ -473,7 +459,7 @@
             'LONG': self.w_longdtype,
             'UNICODE': self.w_unicodedtype,
             #'OBJECT',
-            'ULONGLONG': self.w_ulonglongdtype,
+            'ULONGLONG': self.w_uint64dtype,
             'STRING': self.w_stringdtype,
             #'CDOUBLE',
             #'DATETIME',
diff --git a/pypy/module/micronumpy/interp_iter.py b/pypy/module/micronumpy/interp_iter.py
--- a/pypy/module/micronumpy/interp_iter.py
+++ b/pypy/module/micronumpy/interp_iter.py
@@ -269,7 +269,7 @@
 
     def apply_transformations(self, arr, transformations):
         v = BaseIterator.apply_transformations(self, arr, transformations)
-        if len(arr.shape) == 1:
+        if len(arr.shape) == 1 and len(v.res_shape) == 1:
             return OneDimIterator(self.offset, self.strides[0],
                                   self.res_shape[0])
         return v
diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py
--- a/pypy/module/micronumpy/interp_numarray.py
+++ b/pypy/module/micronumpy/interp_numarray.py
@@ -83,8 +83,9 @@
         return space.wrap(W_NDimArray(shape[:], dtype=dtype))
 
     def _unaryop_impl(ufunc_name):
-        def impl(self, space):
-            return getattr(interp_ufuncs.get(space), ufunc_name).call(space, [self])
+        def impl(self, space, w_out=None):
+            return getattr(interp_ufuncs.get(space), ufunc_name).call(space,
+                                                                [self, w_out])
         return func_with_new_name(impl, "unaryop_%s_impl" % ufunc_name)
 
     descr_pos = _unaryop_impl("positive")
@@ -93,8 +94,9 @@
     descr_invert = _unaryop_impl("invert")
 
     def _binop_impl(ufunc_name):
-        def impl(self, space, w_other):
-            return getattr(interp_ufuncs.get(space), ufunc_name).call(space, [self, w_other])
+        def impl(self, space, w_other, w_out=None):
+            return getattr(interp_ufuncs.get(space), ufunc_name).call(space,
+                                                        [self, w_other, w_out])
         return func_with_new_name(impl, "binop_%s_impl" % ufunc_name)
 
     descr_add = _binop_impl("add")
@@ -124,12 +126,12 @@
         return space.newtuple([w_quotient, w_remainder])
 
     def _binop_right_impl(ufunc_name):
-        def impl(self, space, w_other):
+        def impl(self, space, w_other, w_out=None):
             w_other = scalar_w(space,
                 interp_ufuncs.find_dtype_for_scalar(space, w_other, self.find_dtype()),
                 w_other
             )
-            return getattr(interp_ufuncs.get(space), ufunc_name).call(space, [w_other, self])
+            return getattr(interp_ufuncs.get(space), ufunc_name).call(space, [w_other, self, w_out])
         return func_with_new_name(impl, "binop_right_%s_impl" % ufunc_name)
 
     descr_radd = _binop_right_impl("add")
@@ -152,13 +154,21 @@
         return space.newtuple([w_quotient, w_remainder])
 
     def _reduce_ufunc_impl(ufunc_name, promote_to_largest=False):
-        def impl(self, space, w_axis=None):
+        def impl(self, space, w_axis=None, w_out=None):
             if space.is_w(w_axis, space.w_None):
                 axis = -1
             else:
                 axis = space.int_w(w_axis)
+            if space.is_w(w_out, space.w_None) or not w_out:
+                out = None
+            elif not isinstance(w_out, BaseArray):
+                raise OperationError(space.w_TypeError, space.wrap( 
+                        'output must be an array'))
+            else:
+                out = w_out
             return getattr(interp_ufuncs.get(space), ufunc_name).reduce(space,
-                                        self, True, promote_to_largest, axis)
+                                        self, True, promote_to_largest, axis,
+                                                                   False, out)
         return func_with_new_name(impl, "reduce_%s_impl" % ufunc_name)
 
     descr_sum = _reduce_ufunc_impl("add")
@@ -213,6 +223,7 @@
     def descr_dot(self, space, w_other):
         other = convert_to_array(space, w_other)
         if isinstance(other, Scalar):
+            #Note: w_out is not modified, this is numpy compliant.
             return self.descr_mul(space, other)
         elif len(self.shape) < 2 and len(other.shape) < 2:
             w_res = self.descr_mul(space, other)
@@ -514,14 +525,14 @@
             )
         return w_result
 
-    def descr_mean(self, space, w_axis=None):
+    def descr_mean(self, space, w_axis=None, w_out=None):
         if space.is_w(w_axis, space.w_None):
             w_axis = space.wrap(-1)
             w_denom = space.wrap(support.product(self.shape))
         else:
             dim = space.int_w(w_axis)
             w_denom = space.wrap(self.shape[dim])
-        return space.div(self.descr_sum_promote(space, w_axis), w_denom)
+        return space.div(self.descr_sum_promote(space, w_axis, w_out), w_denom)
 
     def descr_var(self, space, w_axis=None):
         return get_appbridge_cache(space).call_method(space, '_var', self,
@@ -714,11 +725,12 @@
     """
     Class for representing virtual arrays, such as binary ops or ufuncs
     """
-    def __init__(self, name, shape, res_dtype):
+    def __init__(self, name, shape, res_dtype, out_arg=None):
         BaseArray.__init__(self, shape)
         self.forced_result = None
         self.res_dtype = res_dtype
         self.name = name
+        self.res = out_arg
         self.size = support.product(self.shape) * res_dtype.get_size()
 
     def _del_sources(self):
@@ -727,13 +739,18 @@
         raise NotImplementedError
 
     def compute(self):
-        ra = ResultArray(self, self.shape, self.res_dtype)
+        ra = ResultArray(self, self.shape, self.res_dtype, self.res)
         loop.compute(ra)
+        if self.res:
+            broadcast_dims = len(self.res.shape) - len(self.shape)
+            chunks = [Chunk(0,0,0,0)] * broadcast_dims + \
+                     [Chunk(0, i, 1, i) for i in self.shape]
+            return Chunks(chunks).apply(self.res)
         return ra.left
 
     def force_if_needed(self):
         if self.forced_result is None:
-            self.forced_result = self.compute()
+            self.forced_result = self.compute().get_concrete()
             self._del_sources()
 
     def get_concrete(self):
@@ -773,8 +790,9 @@
 
 
 class Call1(VirtualArray):
-    def __init__(self, ufunc, name, shape, calc_dtype, res_dtype, values):
-        VirtualArray.__init__(self, name, shape, res_dtype)
+    def __init__(self, ufunc, name, shape, calc_dtype, res_dtype, values,
+                                                            out_arg=None):
+        VirtualArray.__init__(self, name, shape, res_dtype, out_arg)
         self.values = values
         self.size = values.size
         self.ufunc = ufunc
@@ -786,6 +804,12 @@
     def create_sig(self):
         if self.forced_result is not None:
             return self.forced_result.create_sig()
+        if self.shape != self.values.shape:
+            #This happens if out arg is used
+            return signature.BroadcastUfunc(self.ufunc, self.name,
+                                            self.calc_dtype,
+                                            self.values.create_sig(),
+                                            self.res.create_sig())
         return signature.Call1(self.ufunc, self.name, self.calc_dtype,
                                self.values.create_sig())
 
@@ -793,8 +817,9 @@
     """
     Intermediate class for performing binary operations.
     """
-    def __init__(self, ufunc, name, shape, calc_dtype, res_dtype, left, right):
-        VirtualArray.__init__(self, name, shape, res_dtype)
+    def __init__(self, ufunc, name, shape, calc_dtype, res_dtype, left, right,
+            out_arg=None):
+        VirtualArray.__init__(self, name, shape, res_dtype, out_arg)
         self.ufunc = ufunc
         self.left = left
         self.right = right
@@ -832,8 +857,13 @@
         Call2.__init__(self, None, 'assign', shape, dtype, dtype, res, child)
 
     def create_sig(self):
-        return signature.ResultSignature(self.res_dtype, self.left.create_sig(),
-                                         self.right.create_sig())
+        if self.left.shape != self.right.shape:
+            sig = signature.BroadcastResultSignature(self.res_dtype,
+                        self.left.create_sig(), self.right.create_sig())
+        else:
+            sig = signature.ResultSignature(self.res_dtype, 
+                        self.left.create_sig(), self.right.create_sig())
+        return sig
 
 class ToStringArray(Call1):
     def __init__(self, child):
@@ -842,9 +872,9 @@
         self.s = StringBuilder(child.size * self.item_size)
         Call1.__init__(self, None, 'tostring', child.shape, dtype, dtype,
                        child)
-        self.res = W_NDimArray([1], dtype, 'C')
-        self.res_casted = rffi.cast(rffi.CArrayPtr(lltype.Char),
-                                    self.res.storage)
+        self.res_str = W_NDimArray([1], dtype, order='C')
+        self.res_str_casted = rffi.cast(rffi.CArrayPtr(lltype.Char),
+                                    self.res_str.storage)
 
     def create_sig(self):
         return signature.ToStringSignature(self.calc_dtype,
@@ -950,7 +980,7 @@
 
     def setitem(self, item, value):
         self.invalidated()
-        self.dtype.setitem(self, item, value)
+        self.dtype.setitem(self, item, value.convert_to(self.dtype))
 
     def calc_strides(self, shape):
         dtype = self.find_dtype()
@@ -1125,7 +1155,8 @@
 
 @unwrap_spec(subok=bool, copy=bool, ownmaskna=bool)
 def array(space, w_item_or_iterable, w_dtype=None, w_order=None,
-          subok=True, copy=True, w_maskna=None, ownmaskna=False):
+          subok=True, copy=True, w_maskna=None, ownmaskna=False,
+          w_ndmin=None):
     # find scalar
     if w_maskna is None:
         w_maskna = space.w_None
@@ -1170,8 +1201,13 @@
                 break
         if dtype is None:
             dtype = interp_dtype.get_dtype_cache(space).w_float64dtype
+    shapelen = len(shape)
+    if w_ndmin is not None and not space.is_w(w_ndmin, space.w_None):
+        ndmin = space.int_w(w_ndmin)
+        if ndmin > shapelen:
+            shape = [1] * (ndmin - shapelen) + shape
+            shapelen = ndmin
     arr = W_NDimArray(shape[:], dtype=dtype, order=order)
-    shapelen = len(shape)
     arr_iter = arr.create_iter()
     # XXX we might want to have a jitdriver here
     for i in range(len(elems_w)):
diff --git a/pypy/module/micronumpy/interp_ufuncs.py b/pypy/module/micronumpy/interp_ufuncs.py
--- a/pypy/module/micronumpy/interp_ufuncs.py
+++ b/pypy/module/micronumpy/interp_ufuncs.py
@@ -28,26 +28,38 @@
         return self.identity
 
     def descr_call(self, space, __args__):
+	from interp_numarray import BaseArray
         args_w, kwds_w = __args__.unpack()
         # it occurs to me that we don't support any datatypes that
         # require casting, change it later when we do
         kwds_w.pop('casting', None)
         w_subok = kwds_w.pop('subok', None)
         w_out = kwds_w.pop('out', space.w_None)
-        if ((w_subok is not None and space.is_true(w_subok)) or
-            not space.is_w(w_out, space.w_None)):
+        # Setup a default value for out
+        if space.is_w(w_out, space.w_None):
+            out = None
+        else:
+            out = w_out
+        if (w_subok is not None and space.is_true(w_subok)):
             raise OperationError(space.w_NotImplementedError,
                                  space.wrap("parameters unsupported"))
         if kwds_w or len(args_w) < self.argcount:
             raise OperationError(space.w_ValueError,
                 space.wrap("invalid number of arguments")
             )
-        elif len(args_w) > self.argcount:
-            # The extra arguments should actually be the output array, but we
-            # don't support that yet.
+        elif (len(args_w) > self.argcount and out is not None) or \
+             (len(args_w) > self.argcount + 1):
             raise OperationError(space.w_TypeError,
                 space.wrap("invalid number of arguments")
             )
+        # Override the default out value, if it has been provided in w_wargs
+        if len(args_w) > self.argcount:
+            out = args_w[-1]
+        else:
+            args_w = args_w[:] + [out]
+        if out is not None and not isinstance(out, BaseArray):
+            raise OperationError(space.w_TypeError, space.wrap(
+                                            'output must be an array'))
         return self.call(space, args_w)
 
     @unwrap_spec(skipna=bool, keepdims=bool)
@@ -105,28 +117,33 @@
         array([[ 1,  5],
                [ 9, 13]])
         """
-        if not space.is_w(w_out, space.w_None):
-            raise OperationError(space.w_NotImplementedError, space.wrap(
-                "out not supported"))
+        from pypy.module.micronumpy.interp_numarray import BaseArray
         if w_axis is None:
             axis = 0
         elif space.is_w(w_axis, space.w_None):
             axis = -1
         else:
             axis = space.int_w(w_axis)
-        return self.reduce(space, w_obj, False, False, axis, keepdims)
+        if space.is_w(w_out, space.w_None):
+            out = None
+        elif not isinstance(w_out, BaseArray):
+            raise OperationError(space.w_TypeError, space.wrap(
+                                                'output must be an array'))
+        else:
+            out = w_out
+        return self.reduce(space, w_obj, False, False, axis, keepdims, out)
 
-    def reduce(self, space, w_obj, multidim, promote_to_largest, dim,
-               keepdims=False):
+    def reduce(self, space, w_obj, multidim, promote_to_largest, axis,
+               keepdims=False, out=None):
         from pypy.module.micronumpy.interp_numarray import convert_to_array, \
-                                                           Scalar, ReduceArray
+                                             Scalar, ReduceArray, W_NDimArray
         if self.argcount != 2:
             raise OperationError(space.w_ValueError, space.wrap("reduce only "
                 "supported for binary functions"))
         assert isinstance(self, W_Ufunc2)
         obj = convert_to_array(space, w_obj)
-        if dim >= len(obj.shape):
-            raise OperationError(space.w_ValueError, space.wrap("axis(=%d) out of bounds" % dim))
+        if axis >= len(obj.shape):
+            raise OperationError(space.w_ValueError, space.wrap("axis(=%d) out of bounds" % axis))
         if isinstance(obj, Scalar):
             raise OperationError(space.w_TypeError, space.wrap("cannot reduce "
                 "on a scalar"))
@@ -144,21 +161,55 @@
         if self.identity is None and size == 0:
             raise operationerrfmt(space.w_ValueError, "zero-size array to "
                     "%s.reduce without identity", self.name)
-        if shapelen > 1 and dim >= 0:
-            return self.do_axis_reduce(obj, dtype, dim, keepdims)
-        arr = ReduceArray(self.func, self.name, self.identity, obj, dtype)
-        return loop.compute(arr)
+        if shapelen > 1 and axis >= 0:
+            if keepdims:
+                shape = obj.shape[:axis] + [1] + obj.shape[axis + 1:]
+            else:
+                shape = obj.shape[:axis] + obj.shape[axis + 1:]
+            if out:
+                #Test for shape agreement
+                if len(out.shape) > len(shape):
+                    raise operationerrfmt(space.w_ValueError,
+                        'output parameter for reduction operation %s' +
+                        ' has too many dimensions', self.name)
+                elif len(out.shape) < len(shape):
+                    raise operationerrfmt(space.w_ValueError,
+                        'output parameter for reduction operation %s' +
+                        ' does not have enough dimensions', self.name)
+                elif out.shape != shape:
+                    raise operationerrfmt(space.w_ValueError,
+                        'output parameter shape mismatch, expecting [%s]' +
+                        ' , got [%s]', 
+                        ",".join([str(x) for x in shape]),
+                        ",".join([str(x) for x in out.shape]),
+                        )
+                #Test for dtype agreement, perhaps create an itermediate
+                #if out.dtype != dtype:
+                #    raise OperationError(space.w_TypeError, space.wrap(
+                #        "mismatched  dtypes"))
+                return self.do_axis_reduce(obj, out.find_dtype(), axis, out)
+            else:
+                result = W_NDimArray(shape, dtype)
+                return self.do_axis_reduce(obj, dtype, axis, result)
+        if out:
+            if len(out.shape)>0:
+                raise operationerrfmt(space.w_ValueError, "output parameter "
+                              "for reduction operation %s has too many"
+                              " dimensions",self.name)
+            arr = ReduceArray(self.func, self.name, self.identity, obj,
+                                                            out.find_dtype())
+            val = loop.compute(arr)
+            assert isinstance(out, Scalar)
+            out.value = val
+        else:
+            arr = ReduceArray(self.func, self.name, self.identity, obj, dtype)
+            val = loop.compute(arr)
+        return val 
 
-    def do_axis_reduce(self, obj, dtype, dim, keepdims):
-        from pypy.module.micronumpy.interp_numarray import AxisReduce,\
-             W_NDimArray
-        if keepdims:
-            shape = obj.shape[:dim] + [1] + obj.shape[dim + 1:]
-        else:
-            shape = obj.shape[:dim] + obj.shape[dim + 1:]
-        result = W_NDimArray(shape, dtype)
+    def do_axis_reduce(self, obj, dtype, axis, result):
+        from pypy.module.micronumpy.interp_numarray import AxisReduce
         arr = AxisReduce(self.func, self.name, self.identity, obj.shape, dtype,
-                         result, obj, dim)
+                         result, obj, axis)
         loop.compute(arr)
         return arr.left
 
@@ -176,24 +227,55 @@
         self.bool_result = bool_result
 
     def call(self, space, args_w):
-        from pypy.module.micronumpy.interp_numarray import (Call1,
-            convert_to_array, Scalar)
-
-        [w_obj] = args_w
+        from pypy.module.micronumpy.interp_numarray import (Call1, BaseArray,
+            convert_to_array, Scalar, shape_agreement)
+        if len(args_w)<2:
+            [w_obj] = args_w
+            out = None
+        else:
+            [w_obj, out] = args_w
+            if space.is_w(out, space.w_None):
+                out = None
         w_obj = convert_to_array(space, w_obj)
         calc_dtype = find_unaryop_result_dtype(space,
                                   w_obj.find_dtype(),
                                   promote_to_float=self.promote_to_float,
                                   promote_bools=self.promote_bools)
-        if self.bool_result:
+        if out:
+            if not isinstance(out, BaseArray):
+                raise OperationError(space.w_TypeError, space.wrap(
+                                                'output must be an array'))
+            res_dtype = out.find_dtype()
+        elif self.bool_result:
             res_dtype = interp_dtype.get_dtype_cache(space).w_booldtype
         else:
             res_dtype = calc_dtype
         if isinstance(w_obj, Scalar):
-            return space.wrap(self.func(calc_dtype, w_obj.value.convert_to(calc_dtype)))
-
-        w_res = Call1(self.func, self.name, w_obj.shape, calc_dtype, res_dtype,
-                      w_obj)
+            arr = self.func(calc_dtype, w_obj.value.convert_to(calc_dtype))
+            if isinstance(out,Scalar):
+                out.value=arr
+            elif isinstance(out, BaseArray):
+                out.fill(space, arr)
+            else:
+                out = arr
+            return space.wrap(out)
+        if out:
+            assert isinstance(out, BaseArray) # For translation
+            broadcast_shape =  shape_agreement(space, w_obj.shape, out.shape)
+            if not broadcast_shape or broadcast_shape != out.shape:
+                raise operationerrfmt(space.w_ValueError,
+                    'output parameter shape mismatch, could not broadcast [%s]' +
+                    ' to [%s]', 
+                    ",".join([str(x) for x in w_obj.shape]),
+                    ",".join([str(x) for x in out.shape]),
+                    )
+            w_res = Call1(self.func, self.name, out.shape, calc_dtype,
+                                         res_dtype, w_obj, out)
+            #Force it immediately
+            w_res.get_concrete()
+        else:
+            w_res = Call1(self.func, self.name, w_obj.shape, calc_dtype,
+                                         res_dtype, w_obj)
         w_obj.add_invalidates(w_res)
         return w_res
 
@@ -212,32 +294,61 @@
 
     def call(self, space, args_w):
         from pypy.module.micronumpy.interp_numarray import (Call2,
-            convert_to_array, Scalar, shape_agreement)
-
-        [w_lhs, w_rhs] = args_w
+            convert_to_array, Scalar, shape_agreement, BaseArray)
+        if len(args_w)>2:
+            [w_lhs, w_rhs, w_out] = args_w
+        else:
+            [w_lhs, w_rhs] = args_w
+            w_out = None
         w_lhs = convert_to_array(space, w_lhs)
         w_rhs = convert_to_array(space, w_rhs)
-        calc_dtype = find_binop_result_dtype(space,
-            w_lhs.find_dtype(), w_rhs.find_dtype(),
-            int_only=self.int_only,
-            promote_to_float=self.promote_to_float,
-            promote_bools=self.promote_bools,
-        )
+        if space.is_w(w_out, space.w_None) or w_out is None:
+            out = None
+            calc_dtype = find_binop_result_dtype(space,
+                w_lhs.find_dtype(), w_rhs.find_dtype(),
+                int_only=self.int_only,
+                promote_to_float=self.promote_to_float,
+                promote_bools=self.promote_bools,
+            )
+        elif not isinstance(w_out, BaseArray):
+            raise OperationError(space.w_TypeError, space.wrap(
+                    'output must be an array'))
+        else:
+            out = w_out
+            calc_dtype = out.find_dtype()
         if self.comparison_func:
             res_dtype = interp_dtype.get_dtype_cache(space).w_booldtype
         else:
             res_dtype = calc_dtype
         if isinstance(w_lhs, Scalar) and isinstance(w_rhs, Scalar):
-            return space.wrap(self.func(calc_dtype,
+            arr = self.func(calc_dtype,
                 w_lhs.value.convert_to(calc_dtype),
                 w_rhs.value.convert_to(calc_dtype)
-            ))
+            )
+            if isinstance(out,Scalar):
+                out.value=arr
+            elif isinstance(out, BaseArray):
+                out.fill(space, arr)
+            else:
+                out = arr
+            return space.wrap(out)
         new_shape = shape_agreement(space, w_lhs.shape, w_rhs.shape)
+        # Test correctness of out.shape
+        if out and out.shape != shape_agreement(space, new_shape, out.shape):
+            raise operationerrfmt(space.w_ValueError,
+                'output parameter shape mismatch, could not broadcast [%s]' +
+                ' to [%s]', 
+                ",".join([str(x) for x in new_shape]),
+                ",".join([str(x) for x in out.shape]),
+                )
         w_res = Call2(self.func, self.name,
                       new_shape, calc_dtype,
-                      res_dtype, w_lhs, w_rhs)
+                      res_dtype, w_lhs, w_rhs, out)
         w_lhs.add_invalidates(w_res)
         w_rhs.add_invalidates(w_res)
+        if out:
+            #out.add_invalidates(w_res) #causes a recursion loop
+            w_res.get_concrete()
         return w_res
 
 
@@ -314,7 +425,7 @@
             return dt
         if dt.num >= 5:
             return interp_dtype.get_dtype_cache(space).w_float64dtype
-        for bytes, dtype in interp_dtype.get_dtype_cache(space).dtypes_by_num_bytes:
+        for bytes, dtype in interp_dtype.get_dtype_cache(space).float_dtypes_by_num_bytes:
             if (dtype.kind == interp_dtype.FLOATINGLTR and
                 dtype.itemtype.get_element_size() > dt.itemtype.get_element_size()):
                 return dtype
diff --git a/pypy/module/micronumpy/signature.py b/pypy/module/micronumpy/signature.py
--- a/pypy/module/micronumpy/signature.py
+++ b/pypy/module/micronumpy/signature.py
@@ -216,13 +216,14 @@
         return self.child.eval(frame, arr.child)
 
 class Call1(Signature):
-    _immutable_fields_ = ['unfunc', 'name', 'child', 'dtype']
+    _immutable_fields_ = ['unfunc', 'name', 'child', 'res', 'dtype']
 
-    def __init__(self, func, name, dtype, child):
+    def __init__(self, func, name, dtype, child, res=None):
         self.unfunc = func
         self.child = child
         self.name = name
         self.dtype = dtype
+        self.res  = res
 
     def hash(self):
         return compute_hash(self.name) ^ intmask(self.child.hash() << 1)
@@ -256,6 +257,29 @@
         v = self.child.eval(frame, arr.values).convert_to(arr.calc_dtype)
         return self.unfunc(arr.calc_dtype, v)
 
+
+class BroadcastUfunc(Call1):
+    def _invent_numbering(self, cache, allnumbers):
+        self.res._invent_numbering(cache, allnumbers)
+        self.child._invent_numbering(new_cache(), allnumbers)
+
+    def debug_repr(self):
+        return 'BroadcastUfunc(%s, %s)' % (self.name, self.child.debug_repr())
+
+    def _create_iter(self, iterlist, arraylist, arr, transforms):
+        from pypy.module.micronumpy.interp_numarray import Call1
+
+        assert isinstance(arr, Call1)
+        vtransforms = transforms + [BroadcastTransform(arr.values.shape)]
+        self.child._create_iter(iterlist, arraylist, arr.values, vtransforms)
+        self.res._create_iter(iterlist, arraylist, arr.res, transforms)
+
+    def eval(self, frame, arr):
+        from pypy.module.micronumpy.interp_numarray import Call1
+        assert isinstance(arr, Call1)
+        v = self.child.eval(frame, arr.values).convert_to(arr.calc_dtype)
+        return self.unfunc(arr.calc_dtype, v)
+
 class Call2(Signature):
     _immutable_fields_ = ['binfunc', 'name', 'calc_dtype', 'left', 'right']
 
@@ -316,7 +340,17 @@
 
         assert isinstance(arr, ResultArray)
         offset = frame.get_final_iter().offset
-        arr.left.setitem(offset, self.right.eval(frame, arr.right))
+        val = self.right.eval(frame, arr.right)
+        arr.left.setitem(offset, val)
+
+class BroadcastResultSignature(ResultSignature):
+    def _create_iter(self, iterlist, arraylist, arr, transforms):
+        from pypy.module.micronumpy.interp_numarray import ResultArray
+
+        assert isinstance(arr, ResultArray)
+        rtransforms = transforms + [BroadcastTransform(arr.left.shape)]
+        self.left._create_iter(iterlist, arraylist, arr.left, transforms)
+        self.right._create_iter(iterlist, arraylist, arr.right, rtransforms)
 
 class ToStringSignature(Call1):
     def __init__(self, dtype, child):
@@ -327,10 +361,10 @@
         from pypy.module.micronumpy.interp_numarray import ToStringArray
 
         assert isinstance(arr, ToStringArray)
-        arr.res.setitem(0, self.child.eval(frame, arr.values).convert_to(
+        arr.res_str.setitem(0, self.child.eval(frame, arr.values).convert_to(
             self.dtype))
         for i in range(arr.item_size):
-            arr.s.append(arr.res_casted[i])
+            arr.s.append(arr.res_str_casted[i])
 
 class BroadcastLeft(Call2):
     def _invent_numbering(self, cache, allnumbers):
@@ -455,6 +489,5 @@
             cur = arr.left.getitem(iterator.offset)
             value = self.binfunc(self.calc_dtype, cur, v)
         arr.left.setitem(iterator.offset, value)
-    
     def debug_repr(self):
         return 'AxisReduceSig(%s, %s)' % (self.name, self.right.debug_repr())
diff --git a/pypy/module/micronumpy/test/test_dtypes.py b/pypy/module/micronumpy/test/test_dtypes.py
--- a/pypy/module/micronumpy/test/test_dtypes.py
+++ b/pypy/module/micronumpy/test/test_dtypes.py
@@ -302,6 +302,7 @@
         else:
             raises(OverflowError, numpy.int32, 2147483648)
             raises(OverflowError, numpy.int32, '2147483648')
+        assert numpy.dtype('int32') is numpy.dtype(numpy.int32)
 
     def test_uint32(self):
         import sys
@@ -333,15 +334,11 @@
         assert numpy.dtype(numpy.int64).type is numpy.int64
         assert numpy.int64(3) == 3
 
-        if sys.maxint >= 2 ** 63 - 1:
-            assert numpy.int64(9223372036854775807) == 9223372036854775807
-            assert numpy.int64('9223372036854775807') == 9223372036854775807
-        else:
-            raises(OverflowError, numpy.int64, 9223372036854775807)
-            raises(OverflowError, numpy.int64, '9223372036854775807')
+        assert numpy.int64(9223372036854775807) == 9223372036854775807
+        assert numpy.int64(9223372036854775807) == 9223372036854775807
 
         raises(OverflowError, numpy.int64, 9223372036854775808)
-        raises(OverflowError, numpy.int64, '9223372036854775808')
+        raises(OverflowError, numpy.int64, 9223372036854775808L)
 
     def test_uint64(self):
         import sys
diff --git a/pypy/module/micronumpy/test/test_numarray.py b/pypy/module/micronumpy/test/test_numarray.py
--- a/pypy/module/micronumpy/test/test_numarray.py
+++ b/pypy/module/micronumpy/test/test_numarray.py
@@ -211,6 +211,18 @@
         assert a.shape == (3,)
         assert a.dtype is dtype(int)
 
+    def test_ndmin(self):
+        from _numpypy import array
+
+        arr = array([[[1]]], ndmin=1)
+        assert arr.shape == (1, 1, 1)
+
+    def test_noop_ndmin(self):
+        from _numpypy import array
+
+        arr = array([1], ndmin=3)
+        assert arr.shape == (1, 1, 1)
+
     def test_type(self):
         from _numpypy import array
         ar = array(range(5))
@@ -983,6 +995,10 @@
         assert a.sum() == 5
 
         raises(TypeError, 'a.sum(2, 3)')
+        d = array(0.)
+        b = a.sum(out=d)
+        assert b == d
+        assert isinstance(b, float)
 
     def test_reduce_nd(self):
         from numpypy import arange, array, multiply
@@ -1483,8 +1499,6 @@
         a = array([[1, 2], [3, 4], [5, 6], [7, 8],
                    [9, 10], [11, 12], [13, 14]])
         b = a[::2]
-        print a
-        print b
         assert (b == [[1, 2], [5, 6], [9, 10], [13, 14]]).all()
         c = b + b
         assert c[1][1] == 12
diff --git a/pypy/module/micronumpy/test/test_outarg.py b/pypy/module/micronumpy/test/test_outarg.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/micronumpy/test/test_outarg.py
@@ -0,0 +1,126 @@
+import py
+from pypy.module.micronumpy.test.test_base import BaseNumpyAppTest
+
+class AppTestOutArg(BaseNumpyAppTest):
+    def test_reduce_out(self):
+        from numpypy import arange, zeros, array
+        a = arange(15).reshape(5, 3)
+        b = arange(12).reshape(4,3)
+        c = a.sum(0, out=b[1])
+        assert (c == [30, 35, 40]).all()
+        assert (c == b[1]).all()
+        raises(ValueError, 'a.prod(0, out=arange(10))')
+        a=arange(12).reshape(3,2,2)
+        raises(ValueError, 'a.sum(0, out=arange(12).reshape(3,2,2))')
+        raises(ValueError, 'a.sum(0, out=arange(3))')
+        c = array([-1, 0, 1]).sum(out=zeros([], dtype=bool))
+        #You could argue that this should product False, but
+        # that would require an itermediate result. Cpython numpy
+        # gives True.
+        assert c == True
+        a = array([[-1, 0, 1], [1, 0, -1]])
+        c = a.sum(0, out=zeros((3,), dtype=bool))
+        assert (c == [True, False, True]).all()
+        c = a.sum(1, out=zeros((2,), dtype=bool))
+        assert (c == [True, True]).all()
+
+    def test_reduce_intermediary(self):
+        from numpypy import arange, array
+        a = arange(15).reshape(5, 3)
+        b = array(range(3), dtype=bool)
+        c = a.prod(0, out=b)
+        assert(b == [False,  True,  True]).all()
+
+    def test_ufunc_out(self):
+        from _numpypy import array, negative, zeros, sin
+        from math import sin as msin
+        a = array([[1, 2], [3, 4]])
+        c = zeros((2,2,2))
+        b = negative(a + a, out=c[1])
+        #test for view, and also test that forcing out also forces b
+        assert (c[:, :, 1] == [[0, 0], [-4, -8]]).all()
+        assert (b == [[-2, -4], [-6, -8]]).all()
+        #Test broadcast, type promotion
+        b = negative(3, out=a)
+        assert (a == -3).all()
+        c = zeros((2, 2), dtype=float)
+        b = negative(3, out=c)
+        assert b.dtype.kind == c.dtype.kind
+        assert b.shape == c.shape
+        a = array([1, 2])
+        b = sin(a, out=c)
+        assert(c == [[msin(1), msin(2)]] * 2).all()
+        b = sin(a, out=c+c)
+        assert (c == b).all()
+
+        #Test shape agreement
+        a = zeros((3,4))
+        b = zeros((3,5))
+        raises(ValueError, 'negative(a, out=b)')
+        b = zeros((1,4))
+        raises(ValueError, 'negative(a, out=b)')
+
+    def test_binfunc_out(self):
+        from _numpypy import array, add
+        a = array([[1, 2], [3, 4]])
+        out = array([[1, 2], [3, 4]])
+        c = add(a, a, out=out)
+        assert (c == out).all()
+        assert c.shape == a.shape
+        assert c.dtype is a.dtype
+        c[0,0] = 100
+        assert out[0, 0] == 100
+        out[:] = 100
+        raises(ValueError, 'c = add(a, a, out=out[1])')
+        c = add(a[0], a[1], out=out[1])
+        assert (c == out[1]).all()
+        assert (c == [4, 6]).all()
+        assert (out[0] == 100).all()
+        c = add(a[0], a[1], out=out)
+        assert (c == out[1]).all()
+        assert (c == out[0]).all()
+        out = array(16, dtype=int)
+        b = add(10, 10, out=out)
+        assert b==out
+        assert b.dtype == out.dtype
+        
+    def test_applevel(self):
+        from _numpypy import array, sum, max, min
+        a = array([[1, 2], [3, 4]])
+        out = array([[0, 0], [0, 0]])
+        c = sum(a, axis=0, out=out[0])
+        assert (c == [4, 6]).all()
+        assert (c == out[0]).all()
+        assert (c != out[1]).all()
+        c = max(a, axis=1, out=out[0])
+        assert (c == [2, 4]).all()
+        assert (c == out[0]).all()
+        assert (c != out[1]).all()
+        
+    def test_ufunc_cast(self):
+        from _numpypy import array, negative, add, sum
+        a = array(16, dtype = int)
+        c = array(0, dtype = float)
+        b = negative(a, out=c)
+        assert b == c
+        b = add(a, a, out=c)
+        assert b == c
+        d = array([16, 16], dtype=int)
+        b = sum(d, out=c)
+        assert b == c
+        try:
+            from _numpypy import version
+            v = version.version.split('.')
+        except:
+            v = ['1', '6', '0'] # numpypy is api compatable to what version?
+        if v[0]<'2':
+            b = negative(c, out=a)
+            assert b == a
+            b = add(c, c, out=a)
+            assert b == a
+            b = sum(array([16, 16], dtype=float), out=a)
+            assert b == a
+        else:
+            cast_error = raises(TypeError, negative, c, a)
+            assert str(cast_error.value) == \
+            "Cannot cast ufunc negative output from dtype('float64') to dtype('int64') with casting rule 'same_kind'"
diff --git a/pypy/module/micronumpy/test/test_ufuncs.py b/pypy/module/micronumpy/test/test_ufuncs.py
--- a/pypy/module/micronumpy/test/test_ufuncs.py
+++ b/pypy/module/micronumpy/test/test_ufuncs.py
@@ -197,7 +197,6 @@
 
     def test_signbit(self):
         from _numpypy import signbit, copysign
-        import struct
 
         assert (signbit([0, 0.0, 1, 1.0, float('inf'), float('nan')]) ==
             [False, False, False, False, False, False]).all()
diff --git a/pypy/module/micronumpy/test/test_zjit.py b/pypy/module/micronumpy/test/test_zjit.py
--- a/pypy/module/micronumpy/test/test_zjit.py
+++ b/pypy/module/micronumpy/test/test_zjit.py
@@ -131,7 +131,7 @@
         #            bogus. We need to improve the situation somehow.
         self.check_simple_loop({'getinteriorfield_raw': 2,
                                 'setinteriorfield_raw': 1,
-                                'arraylen_gc': 1,
+                                'arraylen_gc': 2,
                                 'guard_true': 1,
                                 'int_lt': 1,
                                 'jump': 1,
diff --git a/pypy/module/micronumpy/types.py b/pypy/module/micronumpy/types.py
--- a/pypy/module/micronumpy/types.py
+++ b/pypy/module/micronumpy/types.py
@@ -500,6 +500,19 @@
     BoxType = interp_boxes.W_ULongBox
     format_code = "L"
 
+def _int64_coerce(self, space, w_item):
+    try:
+        return self._base_coerce(space, w_item)
+    except OperationError, e:
+        if not e.match(space, space.w_OverflowError):
+            raise
+    bigint = space.bigint_w(w_item)
+    try:
+        value = bigint.tolonglong()
+    except OverflowError:
+        raise OperationError(space.w_OverflowError, space.w_None)
+    return self.box(value)
+
 class Int64(BaseType, Integer):
     _attrs_ = ()
 
@@ -507,6 +520,8 @@
     BoxType = interp_boxes.W_Int64Box
     format_code = "q"
 
+    _coerce = func_with_new_name(_int64_coerce, '_coerce')
+
 class NonNativeInt64(BaseType, NonNativeInteger):
     _attrs_ = ()
 
@@ -514,6 +529,8 @@
     BoxType = interp_boxes.W_Int64Box
     format_code = "q"    
 
+    _coerce = func_with_new_name(_int64_coerce, '_coerce')
+
 def _uint64_coerce(self, space, w_item):
     try:
         return self._base_coerce(space, w_item)
diff --git a/pypy/module/posix/test/test_posix2.py b/pypy/module/posix/test/test_posix2.py
--- a/pypy/module/posix/test/test_posix2.py
+++ b/pypy/module/posix/test/test_posix2.py
@@ -14,10 +14,10 @@
 
 def setup_module(mod):
     if os.name != 'nt':
-        mod.space = gettestobjspace(usemodules=['posix', 'fcntl'])
+        mod.space = gettestobjspace(usemodules=['posix', 'fcntl', 'struct'])
     else:
         # On windows, os.popen uses the subprocess module
-        mod.space = gettestobjspace(usemodules=['posix', '_rawffi', 'thread'])
+        mod.space = gettestobjspace(usemodules=['posix', '_rawffi', 'thread', 'struct'])
     mod.path = udir.join('posixtestfile.txt')
     mod.path.write("this is a test")
     mod.path2 = udir.join('test_posix2-')
diff --git a/pypy/module/pypyjit/test_pypy_c/test_containers.py b/pypy/module/pypyjit/test_pypy_c/test_containers.py
--- a/pypy/module/pypyjit/test_pypy_c/test_containers.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_containers.py
@@ -128,3 +128,82 @@
         loop, = log.loops_by_filename(self.filepath)
         ops = loop.ops_by_id('look')
         assert 'call' not in log.opnames(ops)
+
+    #XXX the following tests only work with strategies enabled
+
+    def test_should_not_create_intobject_with_sets(self):
+        def main(n):
+            i = 0
+            s = set()
+            while i < n:
+                s.add(i)
+                i += 1
+        log = self.run(main, [1000])
+        assert log.result == main(1000)
+        loop, = log.loops_by_filename(self.filepath)
+        opnames = log.opnames(loop.allops())
+        assert opnames.count('new_with_vtable') == 0
+
+    def test_should_not_create_stringobject_with_sets(self):
+        def main(n):
+            i = 0
+            s = set()
+            while i < n:
+                s.add(str(i))
+                i += 1
+        log = self.run(main, [1000])
+        assert log.result == main(1000)
+        loop, = log.loops_by_filename(self.filepath)
+        opnames = log.opnames(loop.allops())
+        assert opnames.count('new_with_vtable') == 0
+
+    def test_should_not_create_intobject_with_lists(self):
+        def main(n):
+            i = 0
+            l = []
+            while i < n:
+                l.append(i)
+                i += 1
+        log = self.run(main, [1000])
+        assert log.result == main(1000)
+        loop, = log.loops_by_filename(self.filepath)
+        opnames = log.opnames(loop.allops())
+        assert opnames.count('new_with_vtable') == 0
+
+    def test_should_not_create_stringobject_with_lists(self):
+        def main(n):
+            i = 0
+            l = []
+            while i < n:
+                l.append(str(i))
+                i += 1
+        log = self.run(main, [1000])
+        assert log.result == main(1000)
+        loop, = log.loops_by_filename(self.filepath)
+        opnames = log.opnames(loop.allops())
+        assert opnames.count('new_with_vtable') == 0
+
+    def test_optimized_create_list_from_string(self):
+        def main(n):
+            i = 0
+            l = []
+            while i < n:
+                l = list("abc" * i)
+                i += 1
+        log = self.run(main, [1000])
+        assert log.result == main(1000)
+        loop, = log.loops_by_filename(self.filepath)
+        opnames = log.opnames(loop.allops())
+        assert opnames.count('new_with_vtable') == 0
+
+    def test_optimized_create_set_from_list(self):
+        def main(n):
+            i = 0
+            while i < n:
+                s = set([1,2,3])
+                i += 1
+        log = self.run(main, [1000])
+        assert log.result == main(1000)
+        loop, = log.loops_by_filename(self.filepath)
+        opnames = log.opnames(loop.allops())
+        assert opnames.count('new_with_vtable') == 0
diff --git a/pypy/module/rctime/test/test_rctime.py b/pypy/module/rctime/test/test_rctime.py
--- a/pypy/module/rctime/test/test_rctime.py
+++ b/pypy/module/rctime/test/test_rctime.py
@@ -3,7 +3,7 @@
 
 class AppTestRCTime:
     def setup_class(cls):
-        space = gettestobjspace(usemodules=('rctime',))
+        space = gettestobjspace(usemodules=('rctime', 'struct'))
         cls.space = space
 
     def test_attributes(self):
diff --git a/pypy/module/test_lib_pypy/numpypy/core/test_numeric.py b/pypy/module/test_lib_pypy/numpypy/core/test_numeric.py
--- a/pypy/module/test_lib_pypy/numpypy/core/test_numeric.py
+++ b/pypy/module/test_lib_pypy/numpypy/core/test_numeric.py
@@ -142,3 +142,39 @@
         assert str(b) == "[7 8 9]"
         b = a[2:1, ]
         assert str(b) == "[]"
+
+    def test_equal(self):
+        from _numpypy import array
+        from numpypy import array_equal
+        
+        a = [1, 2, 3]
+        b = [1, 2, 3]
+        
+        assert array_equal(a, b)
+        assert array_equal(a, array(b))
+        assert array_equal(array(a), b)
+        assert array_equal(array(a), array(b))
+
+    def test_not_equal(self):
+        from _numpypy import array
+        from numpypy import array_equal
+        
+        a = [1, 2, 3]
+        b = [1, 2, 4]
+        
+        assert not array_equal(a, b)
+        assert not array_equal(a, array(b))
+        assert not array_equal(array(a), b)
+        assert not array_equal(array(a), array(b))
+
+    def test_mismatched_shape(self):
+        from _numpypy import array
+        from numpypy import array_equal
+        
+        a = [1, 2, 3]
+        b = [[1, 2, 3], [1, 2, 3]]
+        
+        assert not array_equal(a, b)
+        assert not array_equal(a, array(b))
+        assert not array_equal(array(a), b)
+        assert not array_equal(array(a), array(b))
diff --git a/pypy/module/test_lib_pypy/test_binascii.py b/pypy/module/test_lib_pypy/test_binascii.py
deleted file mode 100644
--- a/pypy/module/test_lib_pypy/test_binascii.py
+++ /dev/null
@@ -1,8 +0,0 @@
-
-""" Some more binascii.py tests
-"""
-
-class AppTestBinAscii:
-    def test_incorrect_padding(self):
-        import binascii
-        raises(binascii.Error, "'x'.decode('base64')")
diff --git a/pypy/module/zipimport/test/test_undocumented.py b/pypy/module/zipimport/test/test_undocumented.py
--- a/pypy/module/zipimport/test/test_undocumented.py
+++ b/pypy/module/zipimport/test/test_undocumented.py
@@ -19,7 +19,7 @@
 
 class AppTestZipImport:
     def setup_class(cls):
-        space = gettestobjspace(usemodules=['zipimport', 'rctime'])
+        space = gettestobjspace(usemodules=['zipimport', 'rctime', 'struct'])
         cls.space = space
         cls.w_created_paths = space.wrap(created_paths)
     
diff --git a/pypy/module/zipimport/test/test_zipimport.py b/pypy/module/zipimport/test/test_zipimport.py
--- a/pypy/module/zipimport/test/test_zipimport.py
+++ b/pypy/module/zipimport/test/test_zipimport.py
@@ -47,9 +47,9 @@
         """).compile()
 
         if cls.compression == ZIP_DEFLATED:
-            space = gettestobjspace(usemodules=['zipimport', 'zlib', 'rctime'])
+            space = gettestobjspace(usemodules=['zipimport', 'zlib', 'rctime', 'struct'])
         else:
-            space = gettestobjspace(usemodules=['zipimport', 'rctime'])
+            space = gettestobjspace(usemodules=['zipimport', 'rctime', 'struct'])
             
         cls.space = space
         tmpdir = udir.ensure('zipimport_%s' % cls.__name__, dir=1)
diff --git a/pypy/objspace/flow/model.py b/pypy/objspace/flow/model.py
--- a/pypy/objspace/flow/model.py
+++ b/pypy/objspace/flow/model.py
@@ -7,8 +7,7 @@
 from pypy.tool.uid import uid, Hashable
 from pypy.tool.descriptor import roproperty
 from pypy.tool.sourcetools import PY_IDENTIFIER, nice_repr_for_func
-from pypy.tool.identity_dict import identity_dict
-from pypy.rlib.rarithmetic import is_valid_int, r_longlong, r_ulonglong
+from pypy.rlib.rarithmetic import is_valid_int, r_longlong, r_ulonglong, r_uint
 
 
 """
@@ -546,7 +545,7 @@
                     for n in cases[:len(cases)-has_default]:
                         if is_valid_int(n):
                             continue
-                        if isinstance(n, (r_longlong, r_ulonglong)):
+                        if isinstance(n, (r_longlong, r_ulonglong, r_uint)):
                             continue
                         if isinstance(n, (str, unicode)) and len(n) == 1:
                             continue
diff --git a/pypy/objspace/flow/test/test_objspace.py b/pypy/objspace/flow/test/test_objspace.py
--- a/pypy/objspace/flow/test/test_objspace.py
+++ b/pypy/objspace/flow/test/test_objspace.py
@@ -1,6 +1,6 @@
 from __future__ import with_statement
 import new
-import py
+import py, sys
 from pypy.objspace.flow.model import Constant, Block, Link, Variable
 from pypy.objspace.flow.model import mkentrymap, c_last_exception
 from pypy.interpreter.argument import Arguments
@@ -893,6 +893,8 @@
         """ Tests code generated by pypy-c compiled with BUILD_LIST_FROM_ARG
         bytecode
         """
+        if sys.version_info < (2, 7):
+            py.test.skip("2.7 only test")
         self.patch_opcodes('BUILD_LIST_FROM_ARG')
         try:
             def f():
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
@@ -111,9 +111,15 @@
     length = len(data)
     start, stop, step, slicelength = w_slice.indices4(space, length)
     assert slicelength >= 0
-    newdata = [data[start + i*step] for i in range(slicelength)]
+    if step == 1 and 0 <= start <= stop:
+        newdata = data[start:stop]
+    else:
+        newdata = _getitem_slice_multistep(data, start, step, slicelength)
     return W_BytearrayObject(newdata)
 
+def _getitem_slice_multistep(data, start, step, slicelength):
+    return [data[start + i*step] for i in range(slicelength)]
+
 def contains__Bytearray_Int(space, w_bytearray, w_char):
     char = space.int_w(w_char)
     if not 0 <= char < 256:
diff --git a/pypy/objspace/std/celldict.py b/pypy/objspace/std/celldict.py
--- a/pypy/objspace/std/celldict.py
+++ b/pypy/objspace/std/celldict.py
@@ -127,10 +127,10 @@
     def iter(self, w_dict):
         return ModuleDictIteratorImplementation(self.space, self, w_dict)
 
-    def keys(self, w_dict):
+    def w_keys(self, w_dict):
         space = self.space
-        iterator = self.unerase(w_dict.dstorage).iteritems
-        return [space.wrap(key) for key, cell in iterator()]
+        l = self.unerase(w_dict.dstorage).keys()
+        return space.newlist_str(l)
 
     def values(self, w_dict):
         iterator = self.unerase(w_dict.dstorage).itervalues
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
@@ -90,9 +90,9 @@
 def _add_indirections():
     dict_methods = "setitem setitem_str getitem \
                     getitem_str delitem length \
-                    clear keys values \
+                    clear w_keys values \
                     items iter setdefault \
-                    popitem".split()
+                    popitem listview_str listview_int".split()
 
     def make_method(method):
         def f(self, *args):
@@ -113,7 +113,7 @@
     def get_empty_storage(self):
         raise NotImplementedError
 
-    def keys(self, w_dict):
+    def w_keys(self, w_dict):
         iterator = self.iter(w_dict)
         result = []
         while 1:
@@ -121,7 +121,7 @@
             if w_key is not None:
                 result.append(w_key)
             else:
-                return result
+                return self.space.newlist(result)
 
     def values(self, w_dict):
         iterator = self.iter(w_dict)
@@ -160,6 +160,11 @@
         w_dict.strategy = strategy
         w_dict.dstorage = storage
 
+    def listview_str(self, w_dict):
+        return None
+
+    def listview_int(self, w_dict):
+        return None
 
 class EmptyDictStrategy(DictStrategy):
 
@@ -371,8 +376,9 @@
             self.switch_to_object_strategy(w_dict)
             return w_dict.getitem(w_key)
 
-    def keys(self, w_dict):
-        return [self.wrap(key) for key in self.unerase(w_dict.dstorage).iterkeys()]
+    def w_keys(self, w_dict):
+        l = [self.wrap(key) for key in self.unerase(w_dict.dstorage).iterkeys()]
+        return self.space.newlist(l)
 
     def values(self, w_dict):
         return self.unerase(w_dict.dstorage).values()
@@ -425,8 +431,8 @@
     def iter(self, w_dict):
         return ObjectIteratorImplementation(self.space, self, w_dict)
 
-    def keys(self, w_dict):
-        return self.unerase(w_dict.dstorage).keys()
+    def w_keys(self, w_dict):
+        return self.space.newlist(self.unerase(w_dict.dstorage).keys())
 
 
 class StringDictStrategy(AbstractTypedStrategy, DictStrategy):
@@ -469,9 +475,15 @@
         assert key is not None
         return self.unerase(w_dict.dstorage).get(key, None)
 
+    def listview_str(self, w_dict):
+        return self.unerase(w_dict.dstorage).keys()
+
     def iter(self, w_dict):
         return StrIteratorImplementation(self.space, self, w_dict)
 
+    def w_keys(self, w_dict):
+        return self.space.newlist_str(self.listview_str(w_dict))
+
 
 class _WrappedIteratorMixin(object):
     _mixin_ = True
@@ -534,6 +546,14 @@
     def iter(self, w_dict):
         return IntIteratorImplementation(self.space, self, w_dict)
 
+    def listview_int(self, w_dict):
+        return self.unerase(w_dict.dstorage).keys()
+
+    def w_keys(self, w_dict):
+        # XXX there is no space.newlist_int yet
+        space = self.space
+        return space.call_function(space.w_list, w_dict)
+
 class IntIteratorImplementation(_WrappedIteratorMixin, IteratorImplementation):
     pass
 
@@ -688,7 +708,7 @@
     return space.newlist(w_self.items())
 
 def dict_keys__DictMulti(space, w_self):
-    return space.newlist(w_self.keys())
+    return w_self.w_keys()
 
 def dict_values__DictMulti(space, w_self):
     return space.newlist(w_self.values())
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
@@ -76,7 +76,7 @@
 
     def keys(self, w_dict):
         space = self.space
-        return [space.wrap(key) for key in self.unerase(w_dict.dstorage).dict_w.iterkeys()]
+        return space.newlist_str(self.unerase(w_dict.dstorage).dict_w.keys())
 
     def values(self, w_dict):
         return [unwrap_cell(self.space, w_value) for w_value in self.unerase(w_dict.dstorage).dict_w.itervalues()]
diff --git a/pypy/objspace/std/dicttype.py b/pypy/objspace/std/dicttype.py
--- a/pypy/objspace/std/dicttype.py
+++ b/pypy/objspace/std/dicttype.py
@@ -62,8 +62,14 @@
         w_fill = space.w_None
     if space.is_w(w_type, space.w_dict):
         w_dict = W_DictMultiObject.allocate_and_init_instance(space, w_type)
-        for w_key in space.listview(w_keys):
-            w_dict.setitem(w_key, w_fill)
+
+        strlist = space.listview_str(w_keys)
+        if strlist is not None:
+            for key in strlist:
+                w_dict.setitem_str(key, w_fill)
+        else:
+            for w_key in space.listview(w_keys):
+                w_dict.setitem(w_key, w_fill)
     else:
         w_dict = space.call_function(w_type)
         for w_key in space.listview(w_keys):
diff --git a/pypy/objspace/std/frozensettype.py b/pypy/objspace/std/frozensettype.py
--- a/pypy/objspace/std/frozensettype.py
+++ b/pypy/objspace/std/frozensettype.py
@@ -39,13 +39,11 @@
 def descr__frozenset__new__(space, w_frozensettype,
                             w_iterable=gateway.NoneNotWrapped):
     from pypy.objspace.std.setobject import W_FrozensetObject
-    from pypy.objspace.std.setobject import make_setdata_from_w_iterable
     if (space.is_w(w_frozensettype, space.w_frozenset) and
         w_iterable is not None and type(w_iterable) is W_FrozensetObject):
         return w_iterable
     w_obj = space.allocate_instance(W_FrozensetObject, w_frozensettype)
-    data = make_setdata_from_w_iterable(space, w_iterable)
-    W_FrozensetObject.__init__(w_obj, space, data)
+    W_FrozensetObject.__init__(w_obj, space, w_iterable)
     return w_obj
 
 frozenset_typedef = StdTypeDef("frozenset",
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
@@ -29,9 +29,8 @@
 class W_SeqIterObject(W_AbstractSeqIterObject):
     """Sequence iterator implementation for general sequences."""
 
-class W_FastListIterObject(W_AbstractSeqIterObject):
-    """Sequence iterator specialized for lists, accessing directly their
-    RPython-level list of wrapped objects.
+class W_FastListIterObject(W_AbstractSeqIterObject): # XXX still needed
+    """Sequence iterator specialized for lists.
     """
 
 class W_ReverseSeqIterObject(W_Object):
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
@@ -139,6 +139,16 @@
         new erased object as storage"""
         self.strategy.init_from_list_w(self, list_w)
 
+    def clear(self, space):
+        """Initializes (or overrides) the listobject as empty."""
+        self.space = space
+        if space.config.objspace.std.withliststrategies:
+            strategy = space.fromcache(EmptyListStrategy)
+        else:
+            strategy = space.fromcache(ObjectListStrategy)
+        self.strategy = strategy
+        strategy.clear(self)
+
     def clone(self):
         """Returns a clone by creating a new listobject
         with the same strategy and a copy of the storage"""
@@ -200,6 +210,11 @@
         """ Return the items in the list as unwrapped strings. If the list does
         not use the list strategy, return None. """
         return self.strategy.getitems_str(self)
+
+    def getitems_int(self):
+        """ Return the items in the list as unwrapped ints. If the list does
+        not use the list strategy, return None. """
+        return self.strategy.getitems_int(self)
     # ___________________________________________________
 
 
@@ -300,6 +315,9 @@
     def getitems_str(self, w_list):
         return None
 
+    def getitems_int(self, w_list):
+        return None
+
     def getstorage_copy(self, w_list):
         raise NotImplementedError
 
@@ -358,6 +376,9 @@
         assert len(list_w) == 0
         w_list.lstorage = self.erase(None)
 
+    def clear(self, w_list):
+        w_list.lstorage = self.erase(None)
+
     erase, unerase = rerased.new_erasing_pair("empty")
     erase = staticmethod(erase)
     unerase = staticmethod(unerase)
@@ -516,6 +537,9 @@
             raise IndexError
         return start + i * step
 
+    def getitems_int(self, w_list):
+        return self._getitems_range(w_list, False)
+
     def getitem(self, w_list, i):
         return self.wrap(self._getitem_unwrapped(w_list, i))
 
@@ -696,6 +720,7 @@
             for i in l:
                 if i == obj:
                     return True
+            return False
         return ListStrategy.contains(self, w_list, w_obj)
 
     def length(self, w_list):
@@ -937,6 +962,9 @@
     def init_from_list_w(self, w_list, list_w):
         w_list.lstorage = self.erase(list_w)
 
+    def clear(self, w_list):
+        w_list.lstorage = self.erase([])
+
     def contains(self, w_list, w_obj):
         return ListStrategy.contains(self, w_list, w_obj)
 
@@ -970,6 +998,9 @@
         if reverse:
             l.reverse()
 
+    def getitems_int(self, w_list):
+        return self.unerase(w_list.lstorage)
+
 class FloatListStrategy(AbstractUnwrappedStrategy, ListStrategy):
     _none_value = 0.0
     _applevel_repr = "float"
@@ -1027,37 +1058,49 @@
     def getitems_str(self, w_list):
         return self.unerase(w_list.lstorage)
 
-
 # _______________________________________________________
 
 init_signature = Signature(['sequence'], None, None)
 init_defaults = [None]
 
 def init__List(space, w_list, __args__):
-    from pypy.objspace.std.tupleobject import W_TupleObject
+    from pypy.objspace.std.tupleobject import W_AbstractTupleObject
     # this is on the silly side
     w_iterable, = __args__.parse_obj(
             None, 'list', init_signature, init_defaults)
-    w_list.__init__(space, [])
+    w_list.clear(space)
     if w_iterable is not None:
-        # unfortunately this is duplicating space.unpackiterable to avoid
-        # assigning a new RPython list to 'wrappeditems', which defeats the
-        # W_FastListIterObject optimization.
-        if isinstance(w_iterable, W_ListObject):
-            w_list.extend(w_iterable)
-        elif isinstance(w_iterable, W_TupleObject):
-            w_list.extend(W_ListObject(space, w_iterable.getitems_copy(space)))
-        else:
-            _init_from_iterable(space, w_list, w_iterable)
+        if type(w_iterable) is W_ListObject:
+            w_iterable.copy_into(w_list)
+            return
+        elif isinstance(w_iterable, W_AbstractTupleObject):
+            w_list.__init__(space, w_iterable.getitems_copy(space))
+            return
+
+        intlist = space.listview_int(w_iterable)
+        if intlist is not None:
+            w_list.strategy = strategy = space.fromcache(IntegerListStrategy)
+             # need to copy because intlist can share with w_iterable
+            w_list.lstorage = strategy.erase(intlist[:])
+            return
+
+        strlist = space.listview_str(w_iterable)
+        if strlist is not None:
+            w_list.strategy = strategy = space.fromcache(StringListStrategy)
+             # need to copy because intlist can share with w_iterable
+            w_list.lstorage = strategy.erase(strlist[:])
+            return
+
+        # xxx special hack for speed
+        from pypy.interpreter.generator import GeneratorIterator
+        if isinstance(w_iterable, GeneratorIterator):
+            w_iterable.unpack_into_w(w_list)
+            return
+        # /xxx
+        _init_from_iterable(space, w_list, w_iterable)
 
 def _init_from_iterable(space, w_list, w_iterable):
     # in its own function to make the JIT look into init__List
-    # xxx special hack for speed
-    from pypy.interpreter.generator import GeneratorIterator
-    if isinstance(w_iterable, GeneratorIterator):
-        w_iterable.unpack_into_w(w_list)
-        return
-    # /xxx
     w_iterator = space.iter(w_iterable)
     while True:
         try:
diff --git a/pypy/objspace/std/listtype.py b/pypy/objspace/std/listtype.py
--- a/pypy/objspace/std/listtype.py
+++ b/pypy/objspace/std/listtype.py
@@ -43,7 +43,7 @@
 def descr__new__(space, w_listtype, __args__):
     from pypy.objspace.std.listobject import W_ListObject
     w_obj = space.allocate_instance(W_ListObject, w_listtype)
-    W_ListObject.__init__(w_obj, space, [])
+    w_obj.clear(space)
     return w_obj
 
 # ____________________________________________________________
diff --git a/pypy/objspace/std/mapdict.py b/pypy/objspace/std/mapdict.py
--- a/pypy/objspace/std/mapdict.py
+++ b/pypy/objspace/std/mapdict.py
@@ -694,6 +694,8 @@
         self.delitem(w_dict, w_key)
         return (w_key, w_value)
 
+    # XXX could implement a more efficient w_keys based on space.newlist_str
+
 def materialize_r_dict(space, obj, dict_w):
     map = obj._get_mapdict_map()
     new_obj = map.materialize_r_dict(space, obj, dict_w)
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
@@ -227,10 +227,7 @@
             return W_ComplexObject(x.real, x.imag)
 
         if isinstance(x, set):
-            rdict_w = r_dict(self.eq_w, self.hash_w)
-            for item in x:
-                rdict_w[self.wrap(item)] = None
-            res = W_SetObject(self, rdict_w)
+            res = W_SetObject(self, self.newlist([self.wrap(item) for item in x]))
             return res
 
         if isinstance(x, frozenset):
@@ -325,7 +322,7 @@
 
     def newset(self):
         from pypy.objspace.std.setobject import newset
-        return W_SetObject(self, newset(self))
+        return W_SetObject(self, None)
 
     def newslice(self, w_start, w_end, w_step):
         return W_SliceObject(w_start, w_end, w_step)
@@ -402,8 +399,8 @@
 
     def unpackiterable(self, w_obj, expected_length=-1):
         if isinstance(w_obj, W_AbstractTupleObject):
-            t = w_obj.getitems_copy(self)
-        elif isinstance(w_obj, W_ListObject):
+            t = w_obj.getitems_copy(space)
+        elif type(w_obj) is W_ListObject:
             t = w_obj.getitems_copy()
         else:
             return ObjSpace.unpackiterable(self, w_obj, expected_length)
@@ -416,8 +413,8 @@
         """ Fast paths
         """
         if isinstance(w_obj, W_AbstractTupleObject):
-            t = w_obj.tolist(self)
-        elif isinstance(w_obj, W_ListObject):
+            t = w_obj.tolist(space)
+        elif type(w_obj) is W_ListObject:
             if unroll:
                 t = w_obj.getitems_unroll()
             else:
@@ -438,7 +435,7 @@
         return self.fixedview(w_obj, expected_length, unroll=True)
 
     def listview(self, w_obj, expected_length=-1):
-        if isinstance(w_obj, W_ListObject):
+        if type(w_obj) is W_ListObject:
             t = w_obj.getitems()
         elif isinstance(w_obj, W_AbstractTupleObject):
             t = w_obj.getitems_copy(self)
@@ -449,8 +446,25 @@
         return t
 
     def listview_str(self, w_obj):
-        if isinstance(w_obj, W_ListObject):
+        # note: uses exact type checking for objects with strategies,
+        # and isinstance() for others.  See test_listobject.test_uses_custom...
+        if type(w_obj) is W_ListObject:
             return w_obj.getitems_str()
+        if type(w_obj) is W_DictMultiObject:
+            return w_obj.listview_str()
+        if type(w_obj) is W_SetObject or type(w_obj) is W_FrozensetObject:
+            return w_obj.listview_str()
+        if isinstance(w_obj, W_StringObject):
+            return w_obj.listview_str()
+        return None
+
+    def listview_int(self, w_obj):
+        if type(w_obj) is W_ListObject:
+            return w_obj.getitems_int()
+        if type(w_obj) is W_DictMultiObject:
+            return w_obj.listview_int()
+        if type(w_obj) is W_SetObject or type(w_obj) is W_FrozensetObject:
+            return w_obj.listview_int()
         return None
 
     def sliceindices(self, w_slice, w_length):
diff --git a/pypy/objspace/std/ropeobject.py b/pypy/objspace/std/ropeobject.py
--- a/pypy/objspace/std/ropeobject.py
+++ b/pypy/objspace/std/ropeobject.py
@@ -41,11 +41,6 @@
             return w_self
         return W_RopeObject(w_self._node)
 
-    def unicode_w(w_self, space):
-        # XXX should this use the default encoding?
-        from pypy.objspace.std.unicodetype import plain_str2unicode
-        return plain_str2unicode(space, w_self._node.flatten_string())
-
 W_RopeObject.EMPTY = W_RopeObject(rope.LiteralStringNode.EMPTY)
 W_RopeObject.PREBUILT = [W_RopeObject(rope.LiteralStringNode.PREBUILT[i])
                              for i in range(256)]
diff --git a/pypy/objspace/std/setobject.py b/pypy/objspace/std/setobject.py
--- a/pypy/objspace/std/setobject.py
+++ b/pypy/objspace/std/setobject.py
@@ -7,6 +7,12 @@
 from pypy.interpreter.argument import Signature
 from pypy.objspace.std.settype import set_typedef as settypedef
 from pypy.objspace.std.frozensettype import frozenset_typedef as frozensettypedef
+from pypy.rlib import rerased
+from pypy.rlib.objectmodel import instantiate
+from pypy.interpreter.generator import GeneratorIterator
+from pypy.objspace.std.listobject import W_ListObject
+from pypy.objspace.std.intobject import W_IntObject
+from pypy.objspace.std.stringobject import W_StringObject
 
 class W_BaseSetObject(W_Object):
     typedef = None
@@ -20,88 +26,859 @@
             return True
         return False
 
-
-    def __init__(w_self, space, setdata):
+    def __init__(w_self, space, w_iterable=None):
         """Initialize the set by taking ownership of 'setdata'."""
-        assert setdata is not None
-        w_self.setdata = setdata
+        w_self.space = space
+        set_strategy_and_setdata(space, w_self, w_iterable)
 
     def __repr__(w_self):
         """representation for debugging purposes"""
-        reprlist = [repr(w_item) for w_item in w_self.setdata.keys()]
+        reprlist = [repr(w_item) for w_item in w_self.getkeys()]
         return "<%s(%s)>" % (w_self.__class__.__name__, ', '.join(reprlist))
 
+    def from_storage_and_strategy(w_self, storage, strategy):
+        obj = w_self._newobj(w_self.space, None)
+        assert isinstance(obj, W_BaseSetObject)
+        obj.strategy = strategy
+        obj.sstorage = storage
+        return obj
+
     _lifeline_ = None
     def getweakref(self):
         return self._lifeline_
+
     def setweakref(self, space, weakreflifeline):
         self._lifeline_ = weakreflifeline
     def delweakref(self):
         self._lifeline_ = None
 
+    def switch_to_object_strategy(self, space):
+        d = self.strategy.getdict_w(self)
+        self.strategy = strategy = space.fromcache(ObjectSetStrategy)
+        self.sstorage = strategy.erase(d)
+
+    def switch_to_empty_strategy(self):
+        self.strategy = strategy = self.space.fromcache(EmptySetStrategy)
+        self.sstorage = strategy.get_empty_storage()
+
+    # _____________ strategy methods ________________
+
+
+    def clear(self):
+        """ Removes all elements from the set. """
+        self.strategy.clear(self)
+
+    def copy_real(self):
+        """ Returns a clone of the set. Frozensets storages are also copied."""
+        return self.strategy.copy_real(self)
+
+    def length(self):
+        """ Returns the number of items inside the set. """
+        return self.strategy.length(self)
+
+    def add(self, w_key):
+        """ Adds an element to the set. The element must be wrapped. """
+        self.strategy.add(self, w_key)
+
+    def remove(self, w_item):
+        """ Removes the given element from the set. Element must be wrapped. """
+        return self.strategy.remove(self, w_item)
+
+    def getdict_w(self):
+        """ Returns a dict with all elements of the set. Needed only for switching to ObjectSetStrategy. """
+        return self.strategy.getdict_w(self)
+
+    def listview_str(self):
+        """ If this is a string set return its contents as a list of uwnrapped strings. Otherwise return None. """
+        return self.strategy.listview_str(self)
+
+    def listview_int(self):
+        """ If this is an int set return its contents as a list of uwnrapped ints. Otherwise return None. """
+        return self.strategy.listview_int(self)
+
+    def get_storage_copy(self):
+        """ Returns a copy of the storage. Needed when we want to clone all elements from one set and
+        put them into another. """
+        return self.strategy.get_storage_copy(self)
+
+    def getkeys(self):
+        """ Returns a list of all elements inside the set. Only used in __repr__. Use as less as possible."""
+        return self.strategy.getkeys(self)
+
+    def difference(self, w_other):
+        """ Returns a set with all items that are in this set, but not in w_other. W_other must be a set."""
+        return self.strategy.difference(self, w_other)
+
+    def difference_update(self, w_other):
+        """ As difference but overwrites the sets content with the result. W_other must be a set."""
+        self.strategy.difference_update(self, w_other)
+
+    def symmetric_difference(self, w_other):
+        """ Returns a set with all items that are either in this set or in w_other, but not in both. W_other must be a set. """
+        return self.strategy.symmetric_difference(self, w_other)
+
+    def symmetric_difference_update(self, w_other):
+        """ As symmetric_difference but overwrites the content of the set with the result. W_other must be a set."""
+        self.strategy.symmetric_difference_update(self, w_other)
+
+    def intersect(self, w_other):
+        """ Returns a set with all items that exists in both sets, this set and in w_other. W_other must be a set. """
+        return self.strategy.intersect(self, w_other)
+
+    def intersect_update(self, w_other):
+        """ Keeps only those elements found in both sets, removing all other elements. W_other must be a set."""
+        self.strategy.intersect_update(self, w_other)
+
+    def issubset(self, w_other):
+        """ Checks wether this set is a subset of w_other. W_other must be a set. """
+        return self.strategy.issubset(self, w_other)
+
+    def isdisjoint(self, w_other):
+        """ Checks wether this set and the w_other are completly different, i.e. have no equal elements. W_other must be a set."""
+        return self.strategy.isdisjoint(self, w_other)
+
+    def update(self, w_other):
+        """ Appends all elements from the given set to this set. W_other must be a set."""
+        self.strategy.update(self, w_other)
+
+    def has_key(self, w_key):
+        """ Checks wether this set contains the given wrapped key."""
+        return self.strategy.has_key(self, w_key)
+
+    def equals(self, w_other):
+        """ Checks wether this set and the given set are equal, i.e. contain the same elements. W_other must be a set."""
+        return self.strategy.equals(self, w_other)
+
+    def iter(self):
+        """ Returns an iterator of the elements from this set. """
+        return self.strategy.iter(self)
+
+    def popitem(self):
+        """ Removes an arbitrary element from the set. May raise KeyError if set is empty."""
+        return self.strategy.popitem(self)
+
 class W_SetObject(W_BaseSetObject):
     from pypy.objspace.std.settype import set_typedef as typedef
 
-    def _newobj(w_self, space, rdict_w):
-        """Make a new set by taking ownership of 'rdict_w'."""
+    def _newobj(w_self, space, w_iterable):
+        """Make a new set by taking ownership of 'w_iterable'."""
         if type(w_self) is W_SetObject:
-            return W_SetObject(space, rdict_w)
+            return W_SetObject(space, w_iterable)
         w_type = space.type(w_self)
         w_obj = space.allocate_instance(W_SetObject, w_type)
-        W_SetObject.__init__(w_obj, space, rdict_w)
+        W_SetObject.__init__(w_obj, space, w_iterable)
         return w_obj
 
 class W_FrozensetObject(W_BaseSetObject):
     from pypy.objspace.std.frozensettype import frozenset_typedef as typedef
     hash = 0
 
-    def _newobj(w_self, space, rdict_w):
-        """Make a new frozenset by taking ownership of 'rdict_w'."""
+    def _newobj(w_self, space, w_iterable):
+        """Make a new frozenset by taking ownership of 'w_iterable'."""
         if type(w_self) is W_FrozensetObject:
-            return W_FrozensetObject(space, rdict_w)
+            return W_FrozensetObject(space, w_iterable)
         w_type = space.type(w_self)
         w_obj = space.allocate_instance(W_FrozensetObject, w_type)
-        W_FrozensetObject.__init__(w_obj, space, rdict_w)
+        W_FrozensetObject.__init__(w_obj, space, w_iterable)
         return w_obj
 
 registerimplementation(W_BaseSetObject)
 registerimplementation(W_SetObject)
 registerimplementation(W_FrozensetObject)
 
-class W_SetIterObject(W_Object):
-    from pypy.objspace.std.settype import setiter_typedef as typedef
+class SetStrategy(object):
+    def __init__(self, space):
+        self.space = space
 
-    def __init__(w_self, setdata):
-        w_self.content = content = setdata
-        w_self.len = len(content)
-        w_self.pos = 0
-        w_self.iterator = w_self.content.iterkeys()
+    def get_empty_dict(self):
+        """ Returns an empty dictionary depending on the strategy. Used to initalize a new storage. """
+        raise NotImplementedError
 
-    def next_entry(w_self):
-        for w_key in w_self.iterator:
+    def get_empty_storage(self):
+        """ Returns an empty storage (erased) object. Used to initialize an empty set."""
+        raise NotImplementedError
+
+    def listview_str(self, w_set):
+        return None
+
+    def listview_int(self, w_set):
+        return None
+
+    #def erase(self, storage):
+    #    raise NotImplementedError
+
+    #def unerase(self, storage):
+    #    raise NotImplementedError
+
+    # __________________ methods called on W_SetObject _________________
+
+    def clear(self, w_set):
+        raise NotImplementedError
+
+    def copy_real(self, w_set):
+        raise NotImplementedError
+
+    def length(self, w_set):
+        raise NotImplementedError
+
+    def add(self, w_set, w_key):
+        raise NotImplementedError
+
+    def remove(self, w_set, w_item):
+        raise NotImplementedError
+
+    def getdict_w(self, w_set):
+        raise NotImplementedError
+
+    def get_storage_copy(self, w_set):
+        raise NotImplementedError
+
+    def getkeys(self, w_set):
+        raise NotImplementedError
+
+    def difference(self, w_set, w_other):
+        raise NotImplementedError
+
+    def difference_update(self, w_set, w_other):
+        raise NotImplementedError
+
+    def symmetric_difference(self, w_set, w_other):
+        raise NotImplementedError
+
+    def symmetric_difference_update(self, w_set, w_other):
+        raise NotImplementedError
+
+    def intersect(self, w_set, w_other):
+        raise NotImplementedError
+
+    def intersect_update(self, w_set, w_other):
+        raise NotImplementedError
+
+    def issubset(self, w_set, w_other):
+        raise NotImplementedError
+
+    def isdisjoint(self, w_set, w_other):
+        raise NotImplementedError
+
+    def update(self, w_set, w_other):
+        raise NotImplementedError
+
+    def has_key(self, w_set, w_key):
+        raise NotImplementedError
+
+    def equals(self, w_set, w_other):
+        raise NotImplementedError
+
+    def iter(self, w_set):
+        raise NotImplementedError
+
+    def popitem(self, w_set):
+        raise NotImplementedError
+
+class EmptySetStrategy(SetStrategy):
+
+    erase, unerase = rerased.new_erasing_pair("empty")
+    erase = staticmethod(erase)
+    unerase = staticmethod(unerase)
+
+    def get_empty_storage(self):
+        return self.erase(None)
+
+    def is_correct_type(self, w_key):
+        return False
+
+    def length(self, w_set):
+        return 0
+
+    def clear(self, w_set):
+        pass
+
+    def copy_real(self, w_set):
+        storage = self.erase(None)
+        clone = w_set.from_storage_and_strategy(storage, self)
+        return clone
+
+    def add(self, w_set, w_key):
+        if type(w_key) is W_IntObject:
+            strategy = self.space.fromcache(IntegerSetStrategy)
+        elif type(w_key) is W_StringObject:
+            strategy = self.space.fromcache(StringSetStrategy)
+        else:
+            strategy = self.space.fromcache(ObjectSetStrategy)
+        w_set.strategy = strategy
+        w_set.sstorage = strategy.get_empty_storage()
+        w_set.add(w_key)
+
+    def remove(self, w_set, w_item):
+        return False
+
+    def getdict_w(self, w_set):
+        return newset(self.space)
+
+    def get_storage_copy(self, w_set):
+        return w_set.sstorage
+
+    def getkeys(self, w_set):
+        return []
+
+    def has_key(self, w_set, w_key):
+        return False
+
+    def equals(self, w_set, w_other):
+        if w_other.strategy is self or w_other.length() == 0:
+            return True
+        return False
+
+    def difference(self, w_set, w_other):
+        return w_set.copy_real()
+
+    def difference_update(self, w_set, w_other):
+        pass
+
+    def intersect(self, w_set, w_other):
+        return w_set.copy_real()
+
+    def intersect_update(self, w_set, w_other):
+        pass
+
+    def isdisjoint(self, w_set, w_other):
+        return True
+
+    def issubset(self, w_set, w_other):
+        return True
+
+    def symmetric_difference(self, w_set, w_other):
+        return w_other.copy_real()
+
+    def symmetric_difference_update(self, w_set, w_other):
+        w_set.strategy = w_other.strategy
+        w_set.sstorage = w_other.get_storage_copy()
+
+    def update(self, w_set, w_other):
+        w_set.strategy = w_other.strategy
+        w_set.sstorage = w_other.get_storage_copy()
+
+    def iter(self, w_set):
+        return EmptyIteratorImplementation(self.space, w_set)
+
+    def popitem(self, w_set):
+        raise OperationError(self.space.w_KeyError,
+                                self.space.wrap('pop from an empty set'))
+
+class AbstractUnwrappedSetStrategy(object):
+    _mixin_ = True
+
+    def is_correct_type(self, w_key):
+        """ Checks wether the given wrapped key fits this strategy."""
+        raise NotImplementedError
+
+    def unwrap(self, w_item):
+        """ Returns the unwrapped value of the given wrapped item."""
+        raise NotImplementedError
+
+    def wrap(self, item):
+        """ Returns a wrapped version of the given unwrapped item. """
+        raise NotImplementedError
+
+    def get_storage_from_list(self, list_w):
+        setdata = self.get_empty_dict()
+        for w_item in list_w:
+            setdata[self.unwrap(w_item)] = None
+        return self.erase(setdata)
+
+    def get_storage_from_unwrapped_list(self, items):
+        setdata = self.get_empty_dict()
+        for item in items:
+            setdata[item] = None
+        return self.erase(setdata)
+
+    def length(self, w_set):
+        return len(self.unerase(w_set.sstorage))
+
+    def clear(self, w_set):
+        w_set.switch_to_empty_strategy()
+
+    def copy_real(self, w_set):
+        # may be used internally on frozen sets, although frozenset().copy()
+        # returns self in frozenset_copy__Frozenset.
+        strategy = w_set.strategy
+        d = self.unerase(w_set.sstorage)
+        storage = self.erase(d.copy())
+        clone = w_set.from_storage_and_strategy(storage, strategy)
+        return clone
+
+    def add(self, w_set, w_key):
+        if self.is_correct_type(w_key):
+            d = self.unerase(w_set.sstorage)
+            d[self.unwrap(w_key)] = None
+        else:
+            w_set.switch_to_object_strategy(self.space)
+            w_set.add(w_key)
+
+    def remove(self, w_set, w_item):
+        from pypy.objspace.std.dictmultiobject import _never_equal_to_string
+        d = self.unerase(w_set.sstorage)
+        if not self.is_correct_type(w_item):
+            #XXX check type of w_item and immediately return False in some cases
+            w_set.switch_to_object_strategy(self.space)
+            return w_set.remove(w_item)
+
+        key = self.unwrap(w_item)
+        try:
+            del d[key]
+            return True
+        except KeyError:
+            return False
+
+    def getdict_w(self, w_set):
+        result = newset(self.space)
+        keys = self.unerase(w_set.sstorage).keys()
+        for key in keys:
+            result[self.wrap(key)] = None
+        return result
+
+    def get_storage_copy(self, w_set):
+        d = self.unerase(w_set.sstorage)
+        copy = self.erase(d.copy())
+        return copy
+
+    def getkeys(self, w_set):
+        keys = self.unerase(w_set.sstorage).keys()
+        keys_w = [self.wrap(key) for key in keys]
+        return keys_w
+
+    def has_key(self, w_set, w_key):
+        from pypy.objspace.std.dictmultiobject import _never_equal_to_string
+        if not self.is_correct_type(w_key):
+            #XXX check type of w_item and immediately return False in some cases
+            w_set.switch_to_object_strategy(self.space)
+            return w_set.has_key(w_key)
+        d = self.unerase(w_set.sstorage)
+        return self.unwrap(w_key) in d
+
+    def equals(self, w_set, w_other):
+        if w_set.length() != w_other.length():
+            return False
+        items = self.unerase(w_set.sstorage).keys()
+        for key in items:
+            if not w_other.has_key(self.wrap(key)):
+                return False
+        return True
+
+    def _difference_wrapped(self, w_set, w_other):
+        strategy = self.space.fromcache(ObjectSetStrategy)
+
+        d_new = strategy.get_empty_dict()
+        for obj in self.unerase(w_set.sstorage):
+            w_item = self.wrap(obj)
+            if not w_other.has_key(w_item):
+                d_new[w_item] = None
+
+        return strategy.erase(d_new)
+
+    def _difference_unwrapped(self, w_set, w_other):
+        iterator = self.unerase(w_set.sstorage).iterkeys()
+        other_dict = self.unerase(w_other.sstorage)
+        result_dict = self.get_empty_dict()
+        for key in iterator:
+            if key not in other_dict:
+                result_dict[key] = None
+        return self.erase(result_dict)
+
+    def _difference_base(self, w_set, w_other):
+        if self is w_other.strategy:
+            strategy = w_set.strategy
+            storage = self._difference_unwrapped(w_set, w_other)
+        elif not w_set.strategy.may_contain_equal_elements(w_other.strategy):
+            strategy = w_set.strategy
+            storage = w_set.sstorage
+        else:
+            strategy = self.space.fromcache(ObjectSetStrategy)
+            storage = self._difference_wrapped(w_set, w_other)
+        return storage, strategy
+
+    def difference(self, w_set, w_other):
+        storage, strategy = self._difference_base(w_set, w_other)
+        w_newset = w_set.from_storage_and_strategy(storage, strategy)
+        return w_newset
+
+    def difference_update(self, w_set, w_other):
+        storage, strategy = self._difference_base(w_set, w_other)
+        w_set.strategy = strategy
+        w_set.sstorage = storage
+
+    def _symmetric_difference_unwrapped(self, w_set, w_other):
+        d_new = self.get_empty_dict()
+        d_this = self.unerase(w_set.sstorage)
+        d_other = self.unerase(w_other.sstorage)
+        for key in d_other.keys():
+            if not key in d_this:
+                d_new[key] = None
+        for key in d_this.keys():
+            if not key in d_other:
+                d_new[key] = None
+
+        storage = self.erase(d_new)
+        return storage
+
+    def _symmetric_difference_wrapped(self, w_set, w_other):
+        newsetdata = newset(self.space)
+        for obj in self.unerase(w_set.sstorage):
+            w_item = self.wrap(obj)
+            if not w_other.has_key(w_item):
+                newsetdata[w_item] = None
+
+        w_iterator = w_other.iter()
+        while True:
+            w_item = w_iterator.next_entry()
+            if w_item is None:
+                break
+            if not w_set.has_key(w_item):
+                newsetdata[w_item] = None
+
+        strategy = self.space.fromcache(ObjectSetStrategy)
+        return strategy.erase(newsetdata)
+
+    def _symmetric_difference_base(self, w_set, w_other):
+        if self is w_other.strategy:
+            strategy = w_set.strategy
+            storage = self._symmetric_difference_unwrapped(w_set, w_other)
+        else:
+            strategy = self.space.fromcache(ObjectSetStrategy)
+            storage = self._symmetric_difference_wrapped(w_set, w_other)
+        return storage, strategy
+
+    def symmetric_difference(self, w_set, w_other):
+        storage, strategy = self._symmetric_difference_base(w_set, w_other)
+        return w_set.from_storage_and_strategy(storage, strategy)
+
+    def symmetric_difference_update(self, w_set, w_other):
+        storage, strategy = self._symmetric_difference_base(w_set, w_other)
+        w_set.strategy = strategy
+        w_set.sstorage = storage
+
+    def _intersect_base(self, w_set, w_other):
+        if self is w_other.strategy:
+            strategy = w_set.strategy
+            storage = strategy._intersect_unwrapped(w_set, w_other)
+        elif not w_set.strategy.may_contain_equal_elements(w_other.strategy):
+            strategy = self.space.fromcache(EmptySetStrategy)
+            storage = strategy.get_empty_storage()
+        else:
+            strategy = self.space.fromcache(ObjectSetStrategy)
+            storage = self._intersect_wrapped(w_set, w_other)
+        return storage, strategy
+
+    def _intersect_wrapped(self, w_set, w_other):
+        result = newset(self.space)
+        for key in self.unerase(w_set.sstorage):
+            w_key = self.wrap(key)
+            if w_other.has_key(w_key):
+                result[w_key] = None
+
+        strategy = self.space.fromcache(ObjectSetStrategy)
+        return strategy.erase(result)
+
+    def _intersect_unwrapped(self, w_set, w_other):
+        result = self.get_empty_dict()
+        d_this = self.unerase(w_set.sstorage)
+        d_other = self.unerase(w_other.sstorage)
+        for key in d_this:
+            if key in d_other:
+                result[key] = None
+        return self.erase(result)
+
+    def intersect(self, w_set, w_other):
+        if w_set.length() > w_other.length():
+            return w_other.intersect(w_set)
+
+        storage, strategy = self._intersect_base(w_set, w_other)
+        return w_set.from_storage_and_strategy(storage, strategy)
+
+    def intersect_update(self, w_set, w_other):
+        if w_set.length() > w_other.length():
+            w_intersection = w_other.intersect(w_set)
+            strategy = w_intersection.strategy
+            storage = w_intersection.sstorage
+        else:
+            storage, strategy = self._intersect_base(w_set, w_other)
+        w_set.strategy = strategy
+        w_set.sstorage = storage
+
+    def _issubset_unwrapped(self, w_set, w_other):
+        d_other = self.unerase(w_other.sstorage)
+        for item in self.unerase(w_set.sstorage):
+            if not item in d_other:
+                return False
+        return True
+
+    def _issubset_wrapped(self, w_set, w_other):
+        for obj in self.unerase(w_set.sstorage):
+            w_item = self.wrap(obj)
+            if not w_other.has_key(w_item):
+                return False
+        return True
+
+    def issubset(self, w_set, w_other):
+        if w_set.length() == 0:
+            return True
+
+        if w_set.strategy is w_other.strategy:
+            return self._issubset_unwrapped(w_set, w_other)
+        elif not w_set.strategy.may_contain_equal_elements(w_other.strategy):
+            return False
+        else:
+            return self._issubset_wrapped(w_set, w_other)
+
+    def _isdisjoint_unwrapped(self, w_set, w_other):
+        d_set = self.unerase(w_set.sstorage)
+        d_other = self.unerase(w_other.sstorage)
+        for key in d_set:
+            if key in d_other:
+                return False
+        return True
+
+    def _isdisjoint_wrapped(self, w_set, w_other):
+        d = self.unerase(w_set.sstorage)
+        for key in d:
+            if w_other.has_key(self.wrap(key)):
+                return False
+        return True
+
+    def isdisjoint(self, w_set, w_other):
+        if w_other.length() == 0:
+            return True
+        if w_set.length() > w_other.length():
+            return w_other.isdisjoint(w_set)
+
+        if w_set.strategy is w_other.strategy:
+            return self._isdisjoint_unwrapped(w_set, w_other)
+        elif not w_set.strategy.may_contain_equal_elements(w_other.strategy):
+            return True
+        else:
+            return self._isdisjoint_wrapped(w_set, w_other)
+
+    def update(self, w_set, w_other):
+        if self is w_other.strategy:
+            d_set = self.unerase(w_set.sstorage)
+            d_other = self.unerase(w_other.sstorage)
+            d_set.update(d_other)
+            return
+
+        w_set.switch_to_object_strategy(self.space)
+        w_set.update(w_other)
+
+    def popitem(self, w_set):
+        storage = self.unerase(w_set.sstorage)
+        try:
+            # this returns a tuple because internally sets are dicts
+            result = storage.popitem()
+        except KeyError:
+            # strategy may still be the same even if dict is empty
+            raise OperationError(self.space.w_KeyError,
+                            self.space.wrap('pop from an empty set'))
+        return self.wrap(result[0])
+
+class StringSetStrategy(AbstractUnwrappedSetStrategy, SetStrategy):
+    erase, unerase = rerased.new_erasing_pair("string")
+    erase = staticmethod(erase)
+    unerase = staticmethod(unerase)
+
+    def get_empty_storage(self):
+        return self.erase({})
+
+    def get_empty_dict(self):
+        return {}
+
+    def listview_str(self, w_set):
+        return self.unerase(w_set.sstorage).keys()
+
+    def is_correct_type(self, w_key):
+        return type(w_key) is W_StringObject
+
+    def may_contain_equal_elements(self, strategy):
+        if strategy is self.space.fromcache(IntegerSetStrategy):
+            return False
+        if strategy is self.space.fromcache(EmptySetStrategy):
+            return False
+        return True
+
+    def unwrap(self, w_item):
+        return self.space.str_w(w_item)
+
+    def wrap(self, item):
+        return self.space.wrap(item)
+
+    def iter(self, w_set):
+        return StringIteratorImplementation(self.space, self, w_set)
+
+class IntegerSetStrategy(AbstractUnwrappedSetStrategy, SetStrategy):
+    erase, unerase = rerased.new_erasing_pair("integer")
+    erase = staticmethod(erase)
+    unerase = staticmethod(unerase)
+
+    def get_empty_storage(self):
+        return self.erase({})
+
+    def get_empty_dict(self):
+        return {}
+
+    def listview_int(self, w_set):
+        return self.unerase(w_set.sstorage).keys()
+
+    def is_correct_type(self, w_key):
+        from pypy.objspace.std.intobject import W_IntObject
+        return type(w_key) is W_IntObject
+
+    def may_contain_equal_elements(self, strategy):
+        if strategy is self.space.fromcache(StringSetStrategy):
+            return False
+        if strategy is self.space.fromcache(EmptySetStrategy):
+            return False
+        return True
+
+    def unwrap(self, w_item):
+        return self.space.int_w(w_item)
+
+    def wrap(self, item):
+        return self.space.wrap(item)
+
+    def iter(self, w_set):
+        return IntegerIteratorImplementation(self.space, self, w_set)
+
+class ObjectSetStrategy(AbstractUnwrappedSetStrategy, SetStrategy):
+    erase, unerase = rerased.new_erasing_pair("object")
+    erase = staticmethod(erase)
+    unerase = staticmethod(unerase)
+
+    def get_empty_storage(self):
+        return self.erase(self.get_empty_dict())
+
+    def get_empty_dict(self):
+        return newset(self.space)
+
+    def is_correct_type(self, w_key):
+        return True
+
+    def may_contain_equal_elements(self, strategy):
+        if strategy is self.space.fromcache(EmptySetStrategy):
+            return False
+        return True
+
+    def unwrap(self, w_item):
+        return w_item
+
+    def wrap(self, item):
+        return item
+
+    def iter(self, w_set):
+        return RDictIteratorImplementation(self.space, self, w_set)
+
+    def update(self, w_set, w_other):
+        d_obj = self.unerase(w_set.sstorage)
+        w_iterator = w_other.iter()
+        while True:
+            w_item = w_iterator.next_entry()
+            if w_item is None:
+                break
+            d_obj[w_item] = None
+
+class IteratorImplementation(object):
+    def __init__(self, space, implementation):
+        self.space = space
+        self.setimplementation = implementation
+        self.len = implementation.length()
+        self.pos = 0
+
+    def next(self):
+        if self.setimplementation is None:
+            return None
+        if self.len != self.setimplementation.length():
+            self.len = -1   # Make this error state sticky
+            raise OperationError(self.space.w_RuntimeError,
+                     self.space.wrap("set changed size during iteration"))
+        # look for the next entry
+        if self.pos < self.len:
+            result = self.next_entry()
+            self.pos += 1
+            return result
+        # no more entries
+        self.setimplementation = None
+        return None
+
+    def next_entry(self):
+        """ Purely abstract method
+        """
+        raise NotImplementedError
+
+    def length(self):
+        if self.setimplementation is not None:
+            return self.len - self.pos
+        return 0
+
+class EmptyIteratorImplementation(IteratorImplementation):
+    def next_entry(self):
+        return None
+
+
+class StringIteratorImplementation(IteratorImplementation):
+    def __init__(self, space, strategy, w_set):
+        IteratorImplementation.__init__(self, space, w_set)
+        d = strategy.unerase(w_set.sstorage)
+        self.iterator = d.iterkeys()
+
+    def next_entry(self):
+        for key in self.iterator:
+            return self.space.wrap(key)
+        else:
+            return None
+
+class IntegerIteratorImplementation(IteratorImplementation):
+    #XXX same implementation in dictmultiobject on dictstrategy-branch
+    def __init__(self, space, strategy, dictimplementation):
+        IteratorImplementation.__init__(self, space, dictimplementation)
+        d = strategy.unerase(dictimplementation.sstorage)
+        self.iterator = d.iterkeys()
+
+    def next_entry(self):
+        # note that this 'for' loop only runs once, at most
+        for key in self.iterator:
+            return self.space.wrap(key)
+        else:
+            return None
+
+class RDictIteratorImplementation(IteratorImplementation):
+    def __init__(self, space, strategy, dictimplementation):
+        IteratorImplementation.__init__(self, space, dictimplementation)
+        d = strategy.unerase(dictimplementation.sstorage)
+        self.iterator = d.iterkeys()
+
+    def next_entry(self):
+        # note that this 'for' loop only runs once, at most
+        for w_key in self.iterator:
             return w_key
         else:
             return None
 
+class W_SetIterObject(W_Object):
+    from pypy.objspace.std.settype import setiter_typedef as typedef
+    # XXX this class should be killed, and the various
+    # iterimplementations should be W_Objects directly.
+
+    def __init__(w_self, space, iterimplementation):
+        w_self.space = space
+        w_self.iterimplementation = iterimplementation
+
 registerimplementation(W_SetIterObject)
 
 def iter__SetIterObject(space, w_setiter):
     return w_setiter
 
 def next__SetIterObject(space, w_setiter):
-    content = w_setiter.content
-    if content is not None:
-        if w_setiter.len != len(content):
-            w_setiter.len = -1   # Make this error state sticky
-            raise OperationError(space.w_RuntimeError,
-                     space.wrap("Set changed size during iteration"))
-        # look for the next entry
-        w_result = w_setiter.next_entry()
-        if w_result is not None:
-            w_setiter.pos += 1
-            return w_result
-        # no more entries
-        w_setiter.content = None
+    iterimplementation = w_setiter.iterimplementation
+    w_key = iterimplementation.next()
+    if w_key is not None:
+        return w_key
     raise OperationError(space.w_StopIteration, space.w_None)
 
 # XXX __length_hint__()
@@ -116,107 +893,91 @@
 def newset(space):
     return r_dict(space.eq_w, space.hash_w, force_non_null=True)
 
-def make_setdata_from_w_iterable(space, w_iterable=None):
-    """Return a new r_dict with the content of w_iterable."""
+def set_strategy_and_setdata(space, w_set, w_iterable):
+    from pypy.objspace.std.intobject import W_IntObject
+    if w_iterable is None :
+        w_set.strategy = strategy = space.fromcache(EmptySetStrategy)
+        w_set.sstorage = strategy.get_empty_storage()
+        return
+
     if isinstance(w_iterable, W_BaseSetObject):
-        return w_iterable.setdata.copy()
-    data = newset(space)
-    if w_iterable is not None:
-        for w_item in space.listview(w_iterable):
-            data[w_item] = None
-    return data
+        w_set.strategy = w_iterable.strategy
+        w_set.sstorage = w_iterable.get_storage_copy()
+        return
+
+    stringlist = space.listview_str(w_iterable)
+    if stringlist is not None:
+        strategy = space.fromcache(StringSetStrategy)
+        w_set.strategy = strategy
+        w_set.sstorage = strategy.get_storage_from_unwrapped_list(stringlist)
+        return
+
+    intlist = space.listview_int(w_iterable)
+    if intlist is not None:
+        strategy = space.fromcache(IntegerSetStrategy)
+        w_set.strategy = strategy
+        w_set.sstorage = strategy.get_storage_from_unwrapped_list(intlist)
+        return
+
+    iterable_w = space.listview(w_iterable)
+
+    if len(iterable_w) == 0:
+        w_set.strategy = strategy = space.fromcache(EmptySetStrategy)
+        w_set.sstorage = strategy.get_empty_storage()
+        return
+
+    _pick_correct_strategy(space, w_set, iterable_w)
+
+def _pick_correct_strategy(space, w_set, iterable_w):
+    # check for integers
+    for w_item in iterable_w:
+        if type(w_item) is not W_IntObject:
+            break
+    else:
+        w_set.strategy = space.fromcache(IntegerSetStrategy)
+        w_set.sstorage = w_set.strategy.get_storage_from_list(iterable_w)
+        return
+
+    # check for strings
+    for w_item in iterable_w:
+        if type(w_item) is not W_StringObject:
+            break
+    else:
+        w_set.strategy = space.fromcache(StringSetStrategy)
+        w_set.sstorage = w_set.strategy.get_storage_from_list(iterable_w)
+        return
+
+    w_set.strategy = space.fromcache(ObjectSetStrategy)
+    w_set.sstorage = w_set.strategy.get_storage_from_list(iterable_w)
 
 def _initialize_set(space, w_obj, w_iterable=None):
-    w_obj.setdata.clear()
-    if w_iterable is not None:
-        w_obj.setdata = make_setdata_from_w_iterable(space, w_iterable)
+    w_obj.clear()
+    set_strategy_and_setdata(space, w_obj, w_iterable)
 
 def _convert_set_to_frozenset(space, w_obj):
-    if space.isinstance_w(w_obj, space.w_set):
-        return W_FrozensetObject(space,
-                                 make_setdata_from_w_iterable(space, w_obj))
+    if isinstance(w_obj, W_SetObject):
+        w_frozen = W_FrozensetObject(space, None)
+        w_frozen.strategy = w_obj.strategy
+        w_frozen.sstorage = w_obj.sstorage
+        return w_frozen
+    elif space.isinstance_w(w_obj, space.w_set):
+        w_frz = space.allocate_instance(W_FrozensetObject, space.w_frozenset)
+        W_FrozensetObject.__init__(w_frz, space, w_obj)
+        return w_frz
     else:
         return None
 
-# helper functions for set operation on dicts
-
-def _is_eq(ld, rd):
-    if len(ld) != len(rd):
-        return False
-    for w_key in ld:
-        if w_key not in rd:
-            return False
-    return True
-
-def _difference_dict(space, ld, rd):
-    result = newset(space)
-    for w_key in ld:
-        if w_key not in rd:
-            result[w_key] = None
-    return result
-
-def _difference_dict_update(space, ld, rd):
-    if ld is rd:
-        ld.clear()     # for the case 'a.difference_update(a)'
-    else:
-        for w_key in rd:
-            try:
-                del ld[w_key]
-            except KeyError:
-                pass
-
-def _intersection_dict(space, ld, rd):
-    result = newset(space)
-    if len(ld) > len(rd):
-        ld, rd = rd, ld     # loop over the smaller dict
-    for w_key in ld:
-        if w_key in rd:
-            result[w_key] = None
-    return result
-
-def _isdisjoint_dict(ld, rd):
-    if len(ld) > len(rd):
-        ld, rd = rd, ld     # loop over the smaller dict
-    for w_key in ld:
-        if w_key in rd:
-            return False
-    return True
-
-def _symmetric_difference_dict(space, ld, rd):
-    result = newset(space)
-    for w_key in ld:
-        if w_key not in rd:
-            result[w_key] = None
-    for w_key in rd:
-        if w_key not in ld:
-            result[w_key] = None
-    return result
-
-def _issubset_dict(ldict, rdict):
-    if len(ldict) > len(rdict):
-        return False
-
-    for w_key in ldict:
-        if w_key not in rdict:
-            return False
-    return True
-
-
-#end helper functions
-
 def set_update__Set(space, w_left, others_w):
     """Update a set with the union of itself and another."""
-    ld = w_left.setdata
     for w_other in others_w:
         if isinstance(w_other, W_BaseSetObject):
-            ld.update(w_other.setdata)     # optimization only
+            w_left.update(w_other)     # optimization only
         else:
             for w_key in space.listview(w_other):
-                ld[w_key] = None
+                w_left.add(w_key)
 
 def inplace_or__Set_Set(space, w_left, w_other):
-    ld, rd = w_left.setdata, w_other.setdata
-    ld.update(rd)
+    w_left.update(w_other)
     return w_left
 
 inplace_or__Set_Frozenset = inplace_or__Set_Set
@@ -226,10 +987,10 @@
 
     This has no effect if the element is already present.
     """
-    w_left.setdata[w_other] = None
+    w_left.add(w_other)
 
 def set_copy__Set(space, w_set):
-    return w_set._newobj(space, w_set.setdata.copy())
+    return w_set.copy_real()
 
 def frozenset_copy__Frozenset(space, w_left):
     if type(w_left) is W_FrozensetObject:
@@ -238,63 +999,51 @@
         return set_copy__Set(space, w_left)
 
 def set_clear__Set(space, w_left):
-    w_left.setdata.clear()
+    w_left.clear()
 
 def sub__Set_Set(space, w_left, w_other):
-    ld, rd = w_left.setdata, w_other.setdata
-    new_ld = _difference_dict(space, ld, rd)
-    return w_left._newobj(space, new_ld)
+    return w_left.difference(w_other)
 
 sub__Set_Frozenset = sub__Set_Set
 sub__Frozenset_Set = sub__Set_Set
 sub__Frozenset_Frozenset = sub__Set_Set
 
 def set_difference__Set(space, w_left, others_w):
-    result = w_left.setdata
-    if len(others_w) == 0:
-        result = result.copy()
-    for w_other in others_w:
-        if isinstance(w_other, W_BaseSetObject):
-            rd = w_other.setdata     # optimization only
-        else:
-            rd = make_setdata_from_w_iterable(space, w_other)
-        result = _difference_dict(space, result, rd)
-    return w_left._newobj(space, result)
+    result = w_left.copy_real()
+    set_difference_update__Set(space, result, others_w)
+    return result
 
 frozenset_difference__Frozenset = set_difference__Set
 
 
 def set_difference_update__Set(space, w_left, others_w):
-    ld = w_left.setdata
     for w_other in others_w:
         if isinstance(w_other, W_BaseSetObject):
             # optimization only
-            _difference_dict_update(space, ld, w_other.setdata)
+            w_left.difference_update(w_other)
         else:
-            for w_key in space.listview(w_other):
-                try:
-                    del ld[w_key]
-                except KeyError:
-                    pass
+            w_other_as_set = w_left._newobj(space, w_other)
+            w_left.difference_update(w_other_as_set)
 
 def inplace_sub__Set_Set(space, w_left, w_other):
-    ld, rd = w_left.setdata, w_other.setdata
-    _difference_dict_update(space, ld, rd)
+    w_left.difference_update(w_other)
     return w_left
 
 inplace_sub__Set_Frozenset = inplace_sub__Set_Set
 
 def eq__Set_Set(space, w_left, w_other):
     # optimization only (the general case is eq__Set_settypedef)
-    return space.wrap(_is_eq(w_left.setdata, w_other.setdata))
+    return space.wrap(w_left.equals(w_other))
 
 eq__Set_Frozenset = eq__Set_Set
 eq__Frozenset_Frozenset = eq__Set_Set
 eq__Frozenset_Set = eq__Set_Set
 
 def eq__Set_settypedef(space, w_left, w_other):
-    rd = make_setdata_from_w_iterable(space, w_other)
-    return space.wrap(_is_eq(w_left.setdata, rd))
+    # tested in test_buildinshortcut.py
+    #XXX do not make new setobject here
+    w_other_as_set = w_left._newobj(space, w_other)
+    return space.wrap(w_left.equals(w_other_as_set))
 
 eq__Set_frozensettypedef = eq__Set_settypedef
 eq__Frozenset_settypedef = eq__Set_settypedef
@@ -308,15 +1057,16 @@
 eq__Frozenset_ANY = eq__Set_ANY
 
 def ne__Set_Set(space, w_left, w_other):
-    return space.wrap(not _is_eq(w_left.setdata, w_other.setdata))
+    return space.wrap(not w_left.equals(w_other))
 
 ne__Set_Frozenset = ne__Set_Set
 ne__Frozenset_Frozenset = ne__Set_Set
 ne__Frozenset_Set = ne__Set_Set
 
 def ne__Set_settypedef(space, w_left, w_other):
-    rd = make_setdata_from_w_iterable(space, w_other)
-    return space.wrap(not _is_eq(w_left.setdata, rd))
+    #XXX this is not tested
+    w_other_as_set = w_left._newobj(space, w_other)
+    return space.wrap(not w_left.equals(w_other_as_set))
 
 ne__Set_frozensettypedef = ne__Set_settypedef
 ne__Frozenset_settypedef = ne__Set_settypedef
@@ -331,12 +1081,12 @@
 
 def contains__Set_ANY(space, w_left, w_other):
     try:
-        return space.newbool(w_other in w_left.setdata)
+        return space.newbool(w_left.has_key(w_other))
     except OperationError, e:
         if e.match(space, space.w_TypeError):
             w_f = _convert_set_to_frozenset(space, w_other)
             if w_f is not None:
-                return space.newbool(w_f in w_left.setdata)
+                return space.newbool(w_left.has_key(w_f))
         raise
 
 contains__Frozenset_ANY = contains__Set_ANY
@@ -345,19 +1095,23 @@
     # optimization only (the general case works too)
     if space.is_w(w_left, w_other):
         return space.w_True
-    ld, rd = w_left.setdata, w_other.setdata
-    return space.wrap(_issubset_dict(ld, rd))
+    if w_left.length() > w_other.length():
+        return space.w_False
+    return space.wrap(w_left.issubset(w_other))
 
 set_issubset__Set_Frozenset = set_issubset__Set_Set
 frozenset_issubset__Frozenset_Set = set_issubset__Set_Set
 frozenset_issubset__Frozenset_Frozenset = set_issubset__Set_Set
 
 def set_issubset__Set_ANY(space, w_left, w_other):
-    if space.is_w(w_left, w_other):
-        return space.w_True
+    # not checking whether w_left is w_other here, because if that were the
+    # case the more precise multimethod would have applied.
 
-    ld, rd = w_left.setdata, make_setdata_from_w_iterable(space, w_other)
-    return space.wrap(_issubset_dict(ld, rd))
+    w_other_as_set = w_left._newobj(space, w_other)
+
+    if w_left.length() > w_other_as_set.length():
+        return space.w_False
+    return space.wrap(w_left.issubset(w_other_as_set))
 
 frozenset_issubset__Frozenset_ANY = set_issubset__Set_ANY
 
@@ -370,9 +1124,9 @@
     # optimization only (the general case works too)
     if space.is_w(w_left, w_other):
         return space.w_True
-
-    ld, rd = w_left.setdata, w_other.setdata
-    return space.wrap(_issubset_dict(rd, ld))
+    if w_left.length() < w_other.length():
+        return space.w_False
+    return space.wrap(w_other.issubset(w_left))
 
 set_issuperset__Set_Frozenset = set_issuperset__Set_Set
 set_issuperset__Frozenset_Set = set_issuperset__Set_Set
@@ -382,8 +1136,11 @@
     if space.is_w(w_left, w_other):
         return space.w_True
 
-    ld, rd = w_left.setdata, make_setdata_from_w_iterable(space, w_other)
-    return space.wrap(_issubset_dict(rd, ld))
+    w_other_as_set = w_left._newobj(space, w_other)
+
+    if w_left.length() < w_other_as_set.length():
+        return space.w_False
+    return space.wrap(w_other_as_set.issubset(w_left))
 
 frozenset_issuperset__Frozenset_ANY = set_issuperset__Set_ANY
 
@@ -395,7 +1152,7 @@
 # automatic registration of "lt(x, y)" as "not ge(y, x)" would not give the
 # correct answer here!
 def lt__Set_Set(space, w_left, w_other):
-    if len(w_left.setdata) >= len(w_other.setdata):
+    if w_left.length() >= w_other.length():
         return space.w_False
     else:
         return le__Set_Set(space, w_left, w_other)
@@ -405,7 +1162,7 @@
 lt__Frozenset_Frozenset = lt__Set_Set
 
 def gt__Set_Set(space, w_left, w_other):
-    if len(w_left.setdata) <= len(w_other.setdata):
+    if w_left.length() <= w_other.length():
         return space.w_False
     else:
         return ge__Set_Set(space, w_left, w_other)
@@ -421,26 +1178,19 @@
     Returns True if successfully removed.
     """
     try:
-        del w_left.setdata[w_item]
-        return True
-    except KeyError:
-        return False
+        deleted = w_left.remove(w_item)
     except OperationError, e:
         if not e.match(space, space.w_TypeError):
             raise
-        w_f = _convert_set_to_frozenset(space, w_item)
-        if w_f is None:
-            raise
+        else:
+            w_f = _convert_set_to_frozenset(space, w_item)
+            if w_f is None:
+                raise
+            deleted = w_left.remove(w_f)
 
-    try:
-        del w_left.setdata[w_f]
-        return True
-    except KeyError:
-        return False
-    except OperationError, e:
-        if not e.match(space, space.w_TypeError):
-            raise
-        return False
+    if w_left.length() == 0:
+        w_left.switch_to_empty_strategy()
+    return deleted
 
 def set_discard__Set_ANY(space, w_left, w_item):
     _discard_from_set(space, w_left, w_item)
@@ -454,8 +1204,12 @@
     if w_set.hash != 0:
         return space.wrap(w_set.hash)
     hash = r_uint(1927868237)
-    hash *= r_uint(len(w_set.setdata) + 1)
-    for w_item in w_set.setdata:
+    hash *= r_uint(w_set.length() + 1)
+    w_iterator = w_set.iter()
+    while True:
+        w_item = w_iterator.next_entry()
+        if w_item is None:
+            break
         h = space.hash_w(w_item)
         value = (r_uint(h ^ (h << 16) ^ 89869747)  * multi)
         hash = hash ^ value
@@ -468,71 +1222,75 @@
     return space.wrap(hash)
 
 def set_pop__Set(space, w_left):
-    try:
-        w_key, _ = w_left.setdata.popitem()
-    except KeyError:
-        raise OperationError(space.w_KeyError,
-                                space.wrap('pop from an empty set'))
-    return w_key
+    return w_left.popitem()
 
 def and__Set_Set(space, w_left, w_other):
-    ld, rd = w_left.setdata, w_other.setdata
-    new_ld = _intersection_dict(space, ld, rd)
-    return w_left._newobj(space, new_ld)
+    new_set = w_left.intersect(w_other)
+    return new_set
 
 and__Set_Frozenset = and__Set_Set
 and__Frozenset_Set = and__Set_Set
 and__Frozenset_Frozenset = and__Set_Set
 
-def _intersection_multiple(space, w_left, others_w):
-    result = w_left.setdata
-    for w_other in others_w:
+def set_intersection__Set(space, w_left, others_w):
+    #XXX find smarter implementations
+    others_w = [w_left] + others_w
+
+    # find smallest set in others_w to reduce comparisons
+    startindex, startlength = 0, -1
+    for i in range(len(others_w)):
+        w_other = others_w[i]
+        try:
+            length = space.int_w(space.len(w_other))
+        except OperationError, e:
+            if (e.match(space, space.w_TypeError) or
+                e.match(space, space.w_AttributeError)):
+                continue
+            raise
+
+        if startlength == -1 or length < startlength:
+            startindex = i
+            startlength = length
+
+    others_w[startindex], others_w[0] = others_w[0], others_w[startindex]
+
+    result = w_left._newobj(space, others_w[0])
+    for i in range(1,len(others_w)):
+        w_other = others_w[i]
         if isinstance(w_other, W_BaseSetObject):
             # optimization only
-            result = _intersection_dict(space, result, w_other.setdata)
+            result.intersect_update(w_other)
         else:
-            result2 = newset(space)
-            for w_key in space.listview(w_other):
-                if w_key in result:
-                    result2[w_key] = None
-            result = result2
+            w_other_as_set = w_left._newobj(space, w_other)
+            result.intersect_update(w_other_as_set)
     return result
 
-def set_intersection__Set(space, w_left, others_w):
-    if len(others_w) == 0:
-        result = w_left.setdata.copy()
-    else:
-        result = _intersection_multiple(space, w_left, others_w)
-    return w_left._newobj(space, result)
-
 frozenset_intersection__Frozenset = set_intersection__Set
 
 def set_intersection_update__Set(space, w_left, others_w):
-    result = _intersection_multiple(space, w_left, others_w)
-    w_left.setdata = result
+    result = set_intersection__Set(space, w_left, others_w)
+    w_left.strategy = result.strategy
+    w_left.sstorage = result.sstorage
+    return
 
 def inplace_and__Set_Set(space, w_left, w_other):
-    ld, rd = w_left.setdata, w_other.setdata
-    new_ld = _intersection_dict(space, ld, rd)
-    w_left.setdata = new_ld
+    w_left.intersect_update(w_other)
     return w_left
 
 inplace_and__Set_Frozenset = inplace_and__Set_Set
 
 def set_isdisjoint__Set_Set(space, w_left, w_other):
     # optimization only (the general case works too)
-    ld, rd = w_left.setdata, w_other.setdata
-    disjoint = _isdisjoint_dict(ld, rd)
-    return space.newbool(disjoint)
+    return space.newbool(w_left.isdisjoint(w_other))
 
 set_isdisjoint__Set_Frozenset = set_isdisjoint__Set_Set
 set_isdisjoint__Frozenset_Frozenset = set_isdisjoint__Set_Set
 set_isdisjoint__Frozenset_Set = set_isdisjoint__Set_Set
 
 def set_isdisjoint__Set_ANY(space, w_left, w_other):
-    ld = w_left.setdata
+    #XXX may be optimized when other strategies are added
     for w_key in space.listview(w_other):
-        if w_key in ld:
+        if w_left.has_key(w_key):
             return space.w_False
     return space.w_True
 
@@ -540,9 +1298,8 @@
 
 def set_symmetric_difference__Set_Set(space, w_left, w_other):
     # optimization only (the general case works too)
-    ld, rd = w_left.setdata, w_other.setdata
-    new_ld = _symmetric_difference_dict(space, ld, rd)
-    return w_left._newobj(space, new_ld)
+    w_result = w_left.symmetric_difference(w_other)
+    return w_result
 
 set_symmetric_difference__Set_Frozenset = set_symmetric_difference__Set_Set
 set_symmetric_difference__Frozenset_Set = set_symmetric_difference__Set_Set
@@ -556,26 +1313,23 @@
 
 
 def set_symmetric_difference__Set_ANY(space, w_left, w_other):
-    ld, rd = w_left.setdata, make_setdata_from_w_iterable(space, w_other)
-    new_ld = _symmetric_difference_dict(space, ld, rd)
-    return w_left._newobj(space, new_ld)
+    w_other_as_set = w_left._newobj(space, w_other)
+    w_result = w_left.symmetric_difference(w_other_as_set)
+    return w_result
 
 frozenset_symmetric_difference__Frozenset_ANY = \
         set_symmetric_difference__Set_ANY
 
 def set_symmetric_difference_update__Set_Set(space, w_left, w_other):
     # optimization only (the general case works too)
-    ld, rd = w_left.setdata, w_other.setdata
-    new_ld = _symmetric_difference_dict(space, ld, rd)
-    w_left.setdata = new_ld
+    w_left.symmetric_difference_update(w_other)
 
 set_symmetric_difference_update__Set_Frozenset = \
                                     set_symmetric_difference_update__Set_Set
 
 def set_symmetric_difference_update__Set_ANY(space, w_left, w_other):
-    ld, rd = w_left.setdata, make_setdata_from_w_iterable(space, w_other)
-    new_ld = _symmetric_difference_dict(space, ld, rd)
-    w_left.setdata = new_ld
+    w_other_as_set = w_left._newobj(space, w_other)
+    w_left.symmetric_difference_update(w_other_as_set)
 
 def inplace_xor__Set_Set(space, w_left, w_other):
     set_symmetric_difference_update__Set_Set(space, w_left, w_other)
@@ -584,34 +1338,33 @@
 inplace_xor__Set_Frozenset = inplace_xor__Set_Set
 
 def or__Set_Set(space, w_left, w_other):
-    ld, rd = w_left.setdata, w_other.setdata
-    result = ld.copy()
-    result.update(rd)
-    return w_left._newobj(space, result)
+    w_copy = w_left.copy_real()
+    w_copy.update(w_other)
+    return w_copy
 
 or__Set_Frozenset = or__Set_Set
 or__Frozenset_Set = or__Set_Set
 or__Frozenset_Frozenset = or__Set_Set
 
 def set_union__Set(space, w_left, others_w):
-    result = w_left.setdata.copy()
+    result = w_left.copy_real()
     for w_other in others_w:
         if isinstance(w_other, W_BaseSetObject):
-            result.update(w_other.setdata)     # optimization only
+            result.update(w_other)     # optimization only
         else:
             for w_key in space.listview(w_other):
-                result[w_key] = None
-    return w_left._newobj(space, result)
+                result.add(w_key)
+    return result
 
 frozenset_union__Frozenset = set_union__Set
 
 def len__Set(space, w_left):
-    return space.newint(len(w_left.setdata))
+    return space.newint(w_left.length())
 
 len__Frozenset = len__Set
 
 def iter__Set(space, w_left):
-    return W_SetIterObject(w_left.setdata)
+    return W_SetIterObject(space, w_left.iter())
 
 iter__Frozenset = iter__Set
 
diff --git a/pypy/objspace/std/settype.py b/pypy/objspace/std/settype.py
--- a/pypy/objspace/std/settype.py
+++ b/pypy/objspace/std/settype.py
@@ -68,7 +68,7 @@
 def descr__new__(space, w_settype, __args__):
     from pypy.objspace.std.setobject import W_SetObject, newset
     w_obj = space.allocate_instance(W_SetObject, w_settype)
-    W_SetObject.__init__(w_obj, space, newset(space))
+    W_SetObject.__init__(w_obj, space)
     return w_obj
 
 set_typedef = StdTypeDef("set",
diff --git a/pypy/objspace/std/stringobject.py b/pypy/objspace/std/stringobject.py
--- a/pypy/objspace/std/stringobject.py
+++ b/pypy/objspace/std/stringobject.py
@@ -37,6 +37,20 @@
             return None
         return space.wrap(compute_unique_id(space.str_w(self)))
 
+    def unicode_w(w_self, space):
+        # Use the default encoding.
+        from pypy.objspace.std.unicodetype import unicode_from_string, \
+                decode_object
+        w_defaultencoding = space.call_function(space.sys.get(
+                                                'getdefaultencoding'))
+        from pypy.objspace.std.unicodetype import _get_encoding_and_errors, \
+            unicode_from_string, decode_object
+        encoding, errors = _get_encoding_and_errors(space, w_defaultencoding,
+                                                    space.w_None)
+        if encoding is None and errors is None:
+            return space.unicode_w(unicode_from_string(space, w_self))
+        return space.unicode_w(decode_object(space, w_self, encoding, errors))
+
 
 class W_StringObject(W_AbstractStringObject):
     from pypy.objspace.std.stringtype import str_typedef as typedef
@@ -55,19 +69,13 @@
     def str_w(w_self, space):
         return w_self._value
 
-    def unicode_w(w_self, space):
-        # Use the default encoding.
-        from pypy.objspace.std.unicodetype import unicode_from_string, \
-                decode_object
-        w_defaultencoding = space.call_function(space.sys.get(
-                                                'getdefaultencoding'))
-        from pypy.objspace.std.unicodetype import _get_encoding_and_errors, \
-            unicode_from_string, decode_object
-        encoding, errors = _get_encoding_and_errors(space, w_defaultencoding,
-                                                    space.w_None)
-        if encoding is None and errors is None:
-            return space.unicode_w(unicode_from_string(space, w_self))
-        return space.unicode_w(decode_object(space, w_self, encoding, errors))
+    def listview_str(w_self):
+        return _create_list_from_string(w_self._value)
+
+def _create_list_from_string(value):
+    # need this helper function to allow the jit to look inside and inline
+    # listview_str
+    return [s for s in value]
 
 registerimplementation(W_StringObject)
 
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
@@ -85,6 +85,20 @@
     def setup_class(cls):
         from pypy import conftest
         cls.space = conftest.gettestobjspace(**WITH_BUILTINSHORTCUT)
+        w_fakeint = cls.space.appexec([], """():
+            class FakeInt(object):
+                def __init__(self, value):
+                    self.value = value
+                def __hash__(self):
+                    return hash(self.value)
+
+                def __eq__(self, other):
+                    if other == self.value:
+                        return True
+                    return False
+            return FakeInt
+            """)
+        cls.w_FakeInt = w_fakeint
 
 class AppTestString(test_stringobject.AppTestStringObject):
     def setup_class(cls):
diff --git a/pypy/objspace/std/test/test_dictmultiobject.py b/pypy/objspace/std/test/test_dictmultiobject.py
--- a/pypy/objspace/std/test/test_dictmultiobject.py
+++ b/pypy/objspace/std/test/test_dictmultiobject.py
@@ -131,6 +131,45 @@
         assert self.space.eq_w(space.call_function(get, w("33")), w(None))
         assert self.space.eq_w(space.call_function(get, w("33"), w(44)), w(44))
 
+    def test_fromkeys_fastpath(self):
+        space = self.space
+        w = space.wrap
+
+        w_l = self.space.newlist([w("a"),w("b")])
+        w_l.getitems = None
+        w_d = space.call_method(space.w_dict, "fromkeys", w_l)
+
+        assert space.eq_w(w_d.getitem_str("a"), space.w_None)
+        assert space.eq_w(w_d.getitem_str("b"), space.w_None)
+
+    def test_listview_str_dict(self):
+        w = self.space.wrap
+
+        w_d = self.space.newdict()
+        w_d.initialize_content([(w("a"), w(1)), (w("b"), w(2))])
+
+        assert self.space.listview_str(w_d) == ["a", "b"]
+
+    def test_listview_int_dict(self):
+        w = self.space.wrap
+        w_d = self.space.newdict()
+        w_d.initialize_content([(w(1), w("a")), (w(2), w("b"))])
+
+        assert self.space.listview_int(w_d) == [1, 2]
+
+    def test_keys_on_string_int_dict(self):
+        w = self.space.wrap
+        w_d = self.space.newdict()
+        w_d.initialize_content([(w(1), w("a")), (w(2), w("b"))])
+
+        w_l = self.space.call_method(w_d, "keys")
+        assert sorted(self.space.listview_int(w_l)) == [1,2]
+
+        w_d = self.space.newdict()
+        w_d.initialize_content([(w("a"), w(1)), (w("b"), w(6))])
+
+        w_l = self.space.call_method(w_d, "keys")
+        assert sorted(self.space.listview_str(w_l)) == ["a", "b"]
 
 class AppTest_DictObject:
     def setup_class(cls):
@@ -793,7 +832,9 @@
         return x == y
     eq_w = eq
     def newlist(self, l):
-        return []
+        return l
+    def newlist_str(self, l):
+        return l
     DictObjectCls = W_DictMultiObject
     def type(self, w_obj):
         if isinstance(w_obj, FakeString):
@@ -933,7 +974,7 @@
 
     def test_keys(self):
         self.fill_impl()
-        keys = self.impl.keys()
+        keys = self.impl.w_keys() # wrapped lists = lists in the fake space
         keys.sort()
         assert keys == [self.string, self.string2]
         self.check_not_devolved()
@@ -1011,8 +1052,8 @@
         d.setitem("s", 12)
         d.delitem(F())
 
-        assert "s" not in d.keys()
-        assert F() not in d.keys()
+        assert "s" not in d.w_keys()
+        assert F() not in d.w_keys()
 
 class TestStrDictImplementation(BaseTestRDictImplementation):
     StrategyClass = StringDictStrategy
diff --git a/pypy/objspace/std/test/test_listobject.py b/pypy/objspace/std/test/test_listobject.py
--- a/pypy/objspace/std/test/test_listobject.py
+++ b/pypy/objspace/std/test/test_listobject.py
@@ -486,6 +486,14 @@
         list.__init__(l, ['a', 'b', 'c'])
         assert l is l0
         assert l == ['a', 'b', 'c']
+        list.__init__(l)
+        assert l == []
+
+    def test_explicit_new_init_more_cases(self):
+        for assignment in [[], (), [3], ["foo"]]:
+            l = [1, 2]
+            l.__init__(assignment)
+            assert l == list(assignment)
 
     def test_extend_list(self):
         l = l0 = [1]
@@ -1173,6 +1181,20 @@
         assert l == []
         assert list(g) == []
 
+    def test_uses_custom_iterator(self):
+        # obscure corner case: space.listview*() must not shortcut subclasses
+        # of dicts, because the OrderedDict in the stdlib relies on this.
+        # we extend the use case to lists and sets, i.e. all types that have
+        # strategies, to avoid surprizes depending on the strategy.
+        for base, arg in [(list, []), (list, [5]), (list, ['x']),
+                          (set, []),  (set,  [5]), (set,  ['x']),
+                          (dict, []), (dict, [(5,6)]), (dict, [('x',7)])]:
+            print base, arg
+            class SubClass(base):
+                def __iter__(self):
+                    return iter("foobar")
+            assert list(SubClass(arg)) == ['f', 'o', 'o', 'b', 'a', 'r']
+
 class AppTestForRangeLists(AppTestW_ListObject):
 
     def setup_class(cls):
diff --git a/pypy/objspace/std/test/test_liststrategies.py b/pypy/objspace/std/test/test_liststrategies.py
--- a/pypy/objspace/std/test/test_liststrategies.py
+++ b/pypy/objspace/std/test/test_liststrategies.py
@@ -420,7 +420,7 @@
 
     def test_listview_str(self):
         space = self.space
-        assert space.listview_str(space.wrap("a")) is None
+        assert space.listview_str(space.wrap(1)) == None
         w_l = self.space.newlist([self.space.wrap('a'), self.space.wrap('b')])
         assert space.listview_str(w_l) == ["a", "b"]
 
@@ -463,6 +463,44 @@
         w_res = listobject.list_pop__List_ANY(space, w_l, space.w_None) # does not crash
         assert space.unwrap(w_res) == 3
 
+    def test_create_list_from_set(self):
+        from pypy.objspace.std.setobject import W_SetObject
+        from pypy.objspace.std.setobject import _initialize_set
+
+        space = self.space
+        w = space.wrap
+
+        w_l = W_ListObject(space, [space.wrap(1), space.wrap(2), space.wrap(3)])
+
+        w_set = W_SetObject(self.space)
+        _initialize_set(self.space, w_set, w_l)
+        w_set.iter = None # make sure fast path is used
+
+        w_l2 = W_ListObject(space, [])
+        space.call_method(w_l2, "__init__", w_set)
+
+        w_l2.sort(False)
+        assert space.eq_w(w_l, w_l2)
+
+        w_l = W_ListObject(space, [space.wrap("a"), space.wrap("b"), space.wrap("c")])
+        _initialize_set(self.space, w_set, w_l)
+
+        space.call_method(w_l2, "__init__", w_set)
+
+        w_l2.sort(False)
+        assert space.eq_w(w_l, w_l2)
+
+
+    def test_listview_str_list(self):
+        space = self.space
+        w_l = W_ListObject(space, [space.wrap("a"), space.wrap("b")])
+        assert self.space.listview_str(w_l) == ["a", "b"]
+
+    def test_listview_int_list(self):
+        space = self.space
+        w_l = W_ListObject(space, [space.wrap(1), space.wrap(2), space.wrap(3)])
+        assert self.space.listview_int(w_l) == [1, 2, 3]
+
 
 class TestW_ListStrategiesDisabled:
     def setup_class(cls):
diff --git a/pypy/objspace/std/test/test_obj.py b/pypy/objspace/std/test/test_obj.py
--- a/pypy/objspace/std/test/test_obj.py
+++ b/pypy/objspace/std/test/test_obj.py
@@ -265,4 +265,7 @@
     space = objspace.StdObjSpace()
     w_a = space.wrap("a")
     space.type = None
+    # if it crashes, it means that space._type_isinstance didn't go through
+    # the fast path, and tries to call type() (which is set to None just
+    # above)
     space.isinstance_w(w_a, space.w_str) # does not crash
diff --git a/pypy/objspace/std/test/test_setobject.py b/pypy/objspace/std/test/test_setobject.py
--- a/pypy/objspace/std/test/test_setobject.py
+++ b/pypy/objspace/std/test/test_setobject.py
@@ -8,12 +8,14 @@
 is not too wrong.
 """
 import py.test
-from pypy.objspace.std.setobject import W_SetObject, W_FrozensetObject
+from pypy.objspace.std.setobject import W_SetObject, W_FrozensetObject, IntegerSetStrategy
 from pypy.objspace.std.setobject import _initialize_set
-from pypy.objspace.std.setobject import newset, make_setdata_from_w_iterable
+from pypy.objspace.std.setobject import newset
 from pypy.objspace.std.setobject import and__Set_Set
 from pypy.objspace.std.setobject import set_intersection__Set
 from pypy.objspace.std.setobject import eq__Set_Set
+from pypy.conftest import gettestobjspace
+from pypy.objspace.std.listobject import W_ListObject
 
 letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
 
@@ -29,12 +31,11 @@
         self.false = self.space.w_False
 
     def test_and(self):
-        s = W_SetObject(self.space, newset(self.space))
+        s = W_SetObject(self.space)
         _initialize_set(self.space, s, self.word)
-        t0 = W_SetObject(self.space, newset(self.space))
+        t0 = W_SetObject(self.space)
         _initialize_set(self.space, t0, self.otherword)
-        t1 = W_FrozensetObject(self.space,
-                make_setdata_from_w_iterable(self.space, self.otherword))
+        t1 = W_FrozensetObject(self.space, self.otherword)
         r0 = and__Set_Set(self.space, s, t0)
         r1 = and__Set_Set(self.space, s, t1)
         assert eq__Set_Set(self.space, r0, r1) == self.true
@@ -42,9 +43,9 @@
         assert eq__Set_Set(self.space, r0, sr) == self.true
 
     def test_compare(self):
-        s = W_SetObject(self.space, newset(self.space))
+        s = W_SetObject(self.space)
         _initialize_set(self.space, s, self.word)
-        t = W_SetObject(self.space, newset(self.space))
+        t = W_SetObject(self.space)
         _initialize_set(self.space, t, self.word)
         assert self.space.eq_w(s,t)
         u = self.space.wrap(set('simsalabim'))
@@ -54,7 +55,247 @@
         s = self.space.newset()
         assert self.space.str_w(self.space.repr(s)) == 'set([])'
 
+    def test_intersection_order(self):
+        # theses tests make sure that intersection is done in the correct order
+        # (smallest first)
+        space = self.space
+        a = W_SetObject(self.space)
+        _initialize_set(self.space, a, self.space.wrap("abcdefg"))
+        a.intersect = None
+
+        b = W_SetObject(self.space)
+        _initialize_set(self.space, b, self.space.wrap("abc"))
+
+        result = set_intersection__Set(space, a, [b])
+        assert space.is_true(self.space.eq(result, W_SetObject(space, self.space.wrap("abc"))))
+
+        c = W_SetObject(self.space)
+        _initialize_set(self.space, c, self.space.wrap("e"))
+
+        d = W_SetObject(self.space)
+        _initialize_set(self.space, d, self.space.wrap("ab"))
+
+        # if ordering works correct we should start with set e
+        a.get_storage_copy = None
+        b.get_storage_copy = None
+        d.get_storage_copy = None
+
+        result = set_intersection__Set(space, a, [d,c,b])
+        assert space.is_true(self.space.eq(result, W_SetObject(space, self.space.wrap(""))))
+
+    def test_create_set_from_list(self):
+        from pypy.objspace.std.setobject import ObjectSetStrategy, StringSetStrategy
+        from pypy.objspace.std.floatobject import W_FloatObject
+        from pypy.objspace.std.model import W_Object
+
+        w = self.space.wrap
+        intstr = self.space.fromcache(IntegerSetStrategy)
+        tmp_func = intstr.get_storage_from_list
+        # test if get_storage_from_list is no longer used
+        intstr.get_storage_from_list = None
+
+        w_list = W_ListObject(self.space, [w(1), w(2), w(3)])
+        w_set = W_SetObject(self.space)
+        _initialize_set(self.space, w_set, w_list)
+        assert w_set.strategy is intstr
+        assert intstr.unerase(w_set.sstorage) == {1:None, 2:None, 3:None}
+
+        w_list = W_ListObject(self.space, [w("1"), w("2"), w("3")])
+        w_set = W_SetObject(self.space)
+        _initialize_set(self.space, w_set, w_list)
+        assert w_set.strategy is self.space.fromcache(StringSetStrategy)
+        assert w_set.strategy.unerase(w_set.sstorage) == {"1":None, "2":None, "3":None}
+
+        w_list = W_ListObject(self.space, [w("1"), w(2), w("3")])
+        w_set = W_SetObject(self.space)
+        _initialize_set(self.space, w_set, w_list)
+        assert w_set.strategy is self.space.fromcache(ObjectSetStrategy)
+        for item in w_set.strategy.unerase(w_set.sstorage):
+            assert isinstance(item, W_Object)
+
+        w_list = W_ListObject(self.space, [w(1.0), w(2.0), w(3.0)])
+        w_set = W_SetObject(self.space)
+        _initialize_set(self.space, w_set, w_list)
+        assert w_set.strategy is self.space.fromcache(ObjectSetStrategy)
+        for item in w_set.strategy.unerase(w_set.sstorage):
+            assert isinstance(item, W_FloatObject)
+
+        # changed cached object, need to change it back for other tests to pass
+        intstr.get_storage_from_list = tmp_func
+
+    def test_listview_str_int_on_set(self):
+        w = self.space.wrap
+
+        w_a = W_SetObject(self.space)
+        _initialize_set(self.space, w_a, w("abcdefg"))
+        assert sorted(self.space.listview_str(w_a)) == list("abcdefg")
+        assert self.space.listview_int(w_a) is None
+
+        w_b = W_SetObject(self.space)
+        _initialize_set(self.space, w_b, self.space.newlist([w(1),w(2),w(3),w(4),w(5)]))
+        assert sorted(self.space.listview_int(w_b)) == [1,2,3,4,5]
+        assert self.space.listview_str(w_b) is None
+
 class AppTestAppSetTest:
+
+    def setup_class(self):
+        self.space = gettestobjspace()
+        w_fakeint = self.space.appexec([], """():
+            class FakeInt(object):
+                def __init__(self, value):
+                    self.value = value
+                def __hash__(self):
+                    return hash(self.value)
+
+                def __eq__(self, other):
+                    if other == self.value:
+                        return True
+                    return False
+            return FakeInt
+            """)
+        self.w_FakeInt = w_fakeint
+
+    def test_fakeint(self):
+        f1 = self.FakeInt(4)
+        assert f1 == 4
+        assert hash(f1) == hash(4)
+
+    def test_simple(self):
+        a = set([1,2,3])
+        b = set()
+        b.add(4)
+        c = a.union(b)
+        assert c == set([1,2,3,4])
+
+    def test_generator(self):
+        def foo():
+            for i in [1,2,3,4,5]:
+                yield i
+        b = set(foo())
+        assert b == set([1,2,3,4,5])
+
+        a = set(x for x in [1,2,3])
+        assert a == set([1,2,3])
+
+    def test_generator2(self):
+        def foo():
+            for i in [1,2,3]:
+                yield i
+        class A(set):
+            pass
+        a = A([1,2,3,4,5])
+        b = a.difference(foo())
+        assert b == set([4,5])
+
+    def test_or(self):
+        a = set([0,1,2])
+        b = a | set([1,2,3])
+        assert b == set([0,1,2,3])
+
+        # test inplace or
+        a |= set([1,2,3])
+        assert a == b
+
+    def test_clear(self):
+        a = set([1,2,3])
+        a.clear()
+        assert a == set()
+
+    def test_sub(self):
+        a = set([1,2,3,4,5])
+        b = set([2,3,4])
+        a - b == [1,5]
+        a.__sub__(b) == [1,5]
+
+        #inplace sub
+        a = set([1,2,3,4])
+        b = set([1,4])
+        a -= b
+        assert a == set([2,3])
+
+    def test_issubset(self):
+        a = set([1,2,3,4])
+        b = set([2,3])
+        assert b.issubset(a)
+        c = [1,2,3,4]
+        assert b.issubset(c)
+
+        a = set([1,2,3,4])
+        b = set(['1','2'])
+        assert not b.issubset(a)
+
+    def test_issuperset(self):
+        a = set([1,2,3,4])
+        b = set([2,3])
+        assert a.issuperset(b)
+        c = [2,3]
+        assert a.issuperset(c)
+
+        c = [1,1,1,1,1]
+        assert a.issuperset(c)
+        assert set([1,1,1,1,1]).issubset(a)
+
+        a = set([1,2,3])
+        assert a.issuperset(a)
+        assert not a.issuperset(set([1,2,3,4,5]))
+
+    def test_inplace_and(test):
+        a = set([1,2,3,4])
+        b = set([0,2,3,5,6])
+        a &= b
+        assert a == set([2,3])
+
+    def test_discard_remove(self):
+        a = set([1,2,3,4,5])
+        a.remove(1)
+        assert a == set([2,3,4,5])
+        a.discard(2)
+        assert a == set([3,4,5])
+
+        raises(KeyError, "a.remove(6)")
+
+    def test_pop(self):
+        b = set()
+        raises(KeyError, "b.pop()")
+
+        a = set([1,2,3,4,5])
+        for i in xrange(5):
+            a.pop()
+        assert a == set()
+        raises(KeyError, "a.pop()")
+
+    def test_symmetric_difference(self):
+        a = set([1,2,3])
+        b = set([3,4,5])
+        c = a.symmetric_difference(b)
+        assert c == set([1,2,4,5])
+
+        a = set([1,2,3])
+        b = [3,4,5]
+        c = a.symmetric_difference(b)
+        assert c == set([1,2,4,5])
+
+        a = set([1,2,3])
+        b = set('abc')
+        c = a.symmetric_difference(b)
+        assert c == set([1,2,3,'a','b','c'])
+
+    def test_symmetric_difference_update(self):
+        a = set([1,2,3])
+        b = set([3,4,5])
+        a.symmetric_difference_update(b)
+        assert a == set([1,2,4,5])
+
+        a = set([1,2,3])
+        b = [3,4,5]
+        a.symmetric_difference_update(b)
+        assert a == set([1,2,4,5])
+
+        a = set([1,2,3])
+        b = set([3,4,5])
+        a ^= b
+        assert a == set([1,2,4,5])
+
     def test_subtype(self):
         class subset(set):pass
         a = subset()
@@ -131,6 +372,8 @@
         assert (set('abc') != set('abcd'))
         assert (frozenset('abc') != frozenset('abcd'))
         assert (frozenset('abc') != set('abcd'))
+        assert set() != set('abc')
+        assert set('abc') != set('abd')
 
     def test_libpython_equality(self):
         for thetype in [frozenset, set]:
@@ -178,6 +421,9 @@
         s1 = set('abc')
         s1.update('d', 'ef', frozenset('g'))
         assert s1 == set('abcdefg')
+        s1 = set()
+        s1.update(set('abcd'))
+        assert s1 == set('abcd')
 
     def test_recursive_repr(self):
         class A(object):
@@ -330,6 +576,7 @@
         assert not set([1,2,5]).isdisjoint(frozenset([4,5,6]))
         assert not set([1,2,5]).isdisjoint([4,5,6])
         assert not set([1,2,5]).isdisjoint((4,5,6))
+        assert set([1,2,3]).isdisjoint(set([3.5,4.0]))
 
     def test_intersection(self):
         assert set([1,2,3]).intersection(set([2,3,4])) == set([2,3])
@@ -347,6 +594,35 @@
         assert s.intersection() == s
         assert s.intersection() is not s
 
+    def test_intersection_swap(self):
+        s1 = s3 = set([1,2,3,4,5])
+        s2 = set([2,3,6,7])
+        s1 &= s2
+        assert s1 == set([2,3])
+        assert s3 == set([2,3])
+
+    def test_intersection_generator(self):
+        def foo():
+            for i in range(5):
+                yield i
+
+        s1 = s2 = set([1,2,3,4,5,6])
+        assert s1.intersection(foo()) == set([1,2,3,4])
+        s1.intersection_update(foo())
+        assert s1 == set([1,2,3,4])
+        assert s2 == set([1,2,3,4])
+
+    def test_intersection_string(self):
+        s = set([1,2,3])
+        o = 'abc'
+        assert s.intersection(o) == set()
+
+    def test_intersection_float(self):
+        a = set([1,2,3])
+        b = set([3.0,4.0,5.0])
+        c = a.intersection(b)
+        assert c == set([3.0])
+
     def test_difference(self):
         assert set([1,2,3]).difference(set([2,3,4])) == set([1])
         assert set([1,2,3]).difference(frozenset([2,3,4])) == set([1])
@@ -361,6 +637,9 @@
         s = set([1,2,3])
         assert s.difference() == s
         assert s.difference() is not s
+        assert set([1,2,3]).difference(set([2,3,4,'5'])) == set([1])
+        assert set([1,2,3,'5']).difference(set([2,3,4])) == set([1,'5'])
+        assert set().difference(set([1,2,3])) == set()
 
     def test_intersection_update(self):
         s = set([1,2,3,4,7])
@@ -381,3 +660,250 @@
         assert s == set([2,3])
         s.difference_update(s)
         assert s == set([])
+
+    def test_empty_empty(self):
+        assert set() == set([])
+
+    def test_empty_difference(self):
+        e = set()
+        x = set([1,2,3])
+        assert e.difference(x) == set()
+        assert x.difference(e) == x
+
+        e.difference_update(x)
+        assert e == set()
+        x.difference_update(e)
+        assert x == set([1,2,3])
+
+        assert e.symmetric_difference(x) == x
+        assert x.symmetric_difference(e) == x
+
+        e.symmetric_difference_update(e)
+        assert e == e
+        e.symmetric_difference_update(x)
+        assert e == x
+
+        x.symmetric_difference_update(set())
+        assert x == set([1,2,3])
+
+    def test_fastpath_with_strategies(self):
+        a = set([1,2,3])
+        b = set(["a","b","c"])
+        assert a.difference(b) == a
+        assert b.difference(a) == b
+
+        a = set([1,2,3])
+        b = set(["a","b","c"])
+        assert a.intersection(b) == set()
+        assert b.intersection(a) == set()
+
+        a = set([1,2,3])
+        b = set(["a","b","c"])
+        assert not a.issubset(b)
+        assert not b.issubset(a)
+
+        a = set([1,2,3])
+        b = set(["a","b","c"])
+        assert a.isdisjoint(b)
+        assert b.isdisjoint(a)
+
+    def test_empty_intersect(self):
+        e = set()
+        x = set([1,2,3])
+        assert e.intersection(x) == e
+        assert x.intersection(e) == e
+        assert e & x == e
+        assert x & e == e
+
+        e.intersection_update(x)
+        assert e == set()
+        e &= x
+        assert e == set()
+        x.intersection_update(e)
+        assert x == set()
+
+    def test_empty_issuper(self):
+        e = set()
+        x = set([1,2,3])
+        assert e.issuperset(e) == True
+        assert e.issuperset(x) == False
+        assert x.issuperset(e) == True
+
+        assert e.issuperset(set())
+        assert e.issuperset([])
+
+    def test_empty_issubset(self):
+        e = set()
+        x = set([1,2,3])
+        assert e.issubset(e) == True
+        assert e.issubset(x) == True
+        assert x.issubset(e) == False
+        assert e.issubset([])
+
+    def test_empty_isdisjoint(self):
+        e = set()
+        x = set([1,2,3])
+        assert e.isdisjoint(e) == True
+        assert e.isdisjoint(x) == True
+        assert x.isdisjoint(e) == True
+
+    def test_empty_unhashable(self):
+        s = set()
+        raises(TypeError, s.difference, [[]])
+        raises(TypeError, s.difference_update, [[]])
+        raises(TypeError, s.intersection, [[]])
+        raises(TypeError, s.intersection_update, [[]])
+        raises(TypeError, s.symmetric_difference, [[]])
+        raises(TypeError, s.symmetric_difference_update, [[]])
+        raises(TypeError, s.update, [[]])
+
+    def test_super_with_generator(self):
+        def foo():
+            for i in [1,2,3]:
+                yield i
+        set([1,2,3,4,5]).issuperset(foo())
+
+    def test_isdisjoint_with_generator(self):
+        def foo():
+            for i in [1,2,3]:
+                yield i
+        set([1,2,3,4,5]).isdisjoint(foo())
+
+    def test_fakeint_and_equals(self):
+        s1 = set([1,2,3,4])
+        s2 = set([1,2,self.FakeInt(3), 4])
+        assert s1 == s2
+
+    def test_fakeint_and_discard(self):
+        # test with object strategy
+        s = set([1, 2, 'three', 'four'])
+        s.discard(self.FakeInt(2))
+        assert s == set([1, 'three', 'four'])
+
+        s.remove(self.FakeInt(1))
+        assert s == set(['three', 'four'])
+        raises(KeyError, s.remove, self.FakeInt(16))
+
+        # test with int strategy
+        s = set([1,2,3,4])
+        s.discard(self.FakeInt(4))
+        assert s == set([1,2,3])
+        s.remove(self.FakeInt(3))
+        assert s == set([1,2])
+        raises(KeyError, s.remove, self.FakeInt(16))
+
+    def test_fakeobject_and_has_key(self):
+        s = set([1,2,3,4,5])
+        assert 5 in s
+        assert self.FakeInt(5) in s
+
+    def test_fakeobject_and_pop(self):
+        s = set([1,2,3,self.FakeInt(4),5])
+        assert s.pop()
+        assert s.pop()
+        assert s.pop()
+        assert s.pop()
+        assert s.pop()
+        assert s == set([])
+
+    def test_fakeobject_and_difference(self):
+        s = set([1,2,'3',4])
+        s.difference_update([self.FakeInt(1), self.FakeInt(2)])
+        assert s == set(['3',4])
+
+        s = set([1,2,3,4])
+        s.difference_update([self.FakeInt(1), self.FakeInt(2)])
+        assert s == set([3,4])
+
+    def test_frozenset_behavior(self):
+        s = set([1,2,3,frozenset([4])])
+        raises(TypeError, s.difference_update, [1,2,3,set([4])])
+
+        s = set([1,2,3,frozenset([4])])
+        s.discard(set([4]))
+        assert s == set([1,2,3])
+
+    def test_discard_unhashable(self):
+        s = set([1,2,3,4])
+        raises(TypeError, s.discard, [1])
+
+    def test_discard_evil_compare(self):
+        class Evil(object):
+            def __init__(self, value):
+                self.value = value
+            def __hash__(self):
+                return hash(self.value)
+            def __eq__(self, other):
+                if isinstance(other, frozenset):
+                    raise TypeError
+                if other == self.value:
+                    return True
+                return False
+        s = set([1,2, Evil(frozenset([1]))])
+        raises(TypeError, s.discard, set([1]))
+
+    def test_create_set_from_set(self):
+        # no sharing
+        x = set([1,2,3])
+        y = set(x)
+        a = x.pop()
+        assert y == set([1,2,3])
+        assert len(x) == 2
+        assert x.union(set([a])) == y
+
+    def test_never_change_frozenset(self):
+        a = frozenset([1,2])
+        b = a.copy()
+        assert a is b
+
+        a = frozenset([1,2])
+        b = a.union(set([3,4]))
+        assert b == set([1,2,3,4])
+        assert a == set([1,2])
+
+        a = frozenset()
+        b = a.union(set([3,4]))
+        assert b == set([3,4])
+        assert a == set()
+
+        a = frozenset([1,2])#multiple
+        b = a.union(set([3,4]),[5,6])
+        assert b == set([1,2,3,4,5,6])
+        assert a == set([1,2])
+
+        a = frozenset([1,2,3])
+        b = a.difference(set([3,4,5]))
+        assert b == set([1,2])
+        assert a == set([1,2,3])
+
+        a = frozenset([1,2,3])#multiple
+        b = a.difference(set([3]), [2])
+        assert b == set([1])
+        assert a == set([1,2,3])
+
+        a = frozenset([1,2,3])
+        b = a.symmetric_difference(set([3,4,5]))
+        assert b == set([1,2,4,5])
+        assert a == set([1,2,3])
+
+        a = frozenset([1,2,3])
+        b = a.intersection(set([3,4,5]))
+        assert b == set([3])
+        assert a == set([1,2,3])
+
+        a = frozenset([1,2,3])#multiple
+        b = a.intersection(set([2,3,4]), [2])
+        assert b == set([2])
+        assert a == set([1,2,3])
+
+        raises(AttributeError, "frozenset().update()")
+        raises(AttributeError, "frozenset().difference_update()")
+        raises(AttributeError, "frozenset().symmetric_difference_update()")
+        raises(AttributeError, "frozenset().intersection_update()")
+
+    def test_intersection_obj(self):
+        class Obj:
+            def __getitem__(self, i):
+                return [5, 3, 4][i]
+        s = set([10,3,2]).intersection(Obj())
+        assert list(s) == [3]
diff --git a/pypy/objspace/std/test/test_setstrategies.py b/pypy/objspace/std/test/test_setstrategies.py
new file mode 100644
--- /dev/null
+++ b/pypy/objspace/std/test/test_setstrategies.py
@@ -0,0 +1,107 @@
+from pypy.objspace.std.setobject import W_SetObject
+from pypy.objspace.std.setobject import IntegerSetStrategy, ObjectSetStrategy, EmptySetStrategy
+from pypy.objspace.std.listobject import W_ListObject
+
+class TestW_SetStrategies:
+
+    def wrapped(self, l):
+        return W_ListObject(self.space, [self.space.wrap(x) for x in l])
+
+    def test_from_list(self):
+        s = W_SetObject(self.space, self.wrapped([1,2,3,4,5]))
+        assert s.strategy is self.space.fromcache(IntegerSetStrategy)
+
+        s = W_SetObject(self.space, self.wrapped([1,"two",3,"four",5]))
+        assert s.strategy is self.space.fromcache(ObjectSetStrategy)
+
+        s = W_SetObject(self.space)
+        assert s.strategy is self.space.fromcache(EmptySetStrategy)
+
+        s = W_SetObject(self.space, self.wrapped([]))
+        assert s.strategy is self.space.fromcache(EmptySetStrategy)
+
+    def test_switch_to_object(self):
+        s = W_SetObject(self.space, self.wrapped([1,2,3,4,5]))
+        s.add(self.space.wrap("six"))
+        assert s.strategy is self.space.fromcache(ObjectSetStrategy)
+
+        s1 = W_SetObject(self.space, self.wrapped([1,2,3,4,5]))
+        s2 = W_SetObject(self.space, self.wrapped(["six", "seven"]))
+        s1.update(s2)
+        assert s1.strategy is self.space.fromcache(ObjectSetStrategy)
+
+    def test_symmetric_difference(self):
+        s1 = W_SetObject(self.space, self.wrapped([1,2,3,4,5]))
+        s2 = W_SetObject(self.space, self.wrapped(["six", "seven"]))
+        s1.symmetric_difference_update(s2)
+        assert s1.strategy is self.space.fromcache(ObjectSetStrategy)
+
+    def test_intersection(self):
+        s1 = W_SetObject(self.space, self.wrapped([1,2,3,4,5]))
+        s2 = W_SetObject(self.space, self.wrapped([4,5, "six", "seven"]))
+        s3 = s1.intersect(s2)
+        skip("for now intersection with ObjectStrategy always results in another ObjectStrategy")
+        assert s3.strategy is self.space.fromcache(IntegerSetStrategy)
+
+    def test_clear(self):
+        s1 = W_SetObject(self.space, self.wrapped([1,2,3,4,5]))
+        s1.clear()
+        assert s1.strategy is self.space.fromcache(EmptySetStrategy)
+
+    def test_remove(self):
+        from pypy.objspace.std.setobject import set_remove__Set_ANY
+        s1 = W_SetObject(self.space, self.wrapped([1]))
+        set_remove__Set_ANY(self.space, s1, self.space.wrap(1))
+        assert s1.strategy is self.space.fromcache(EmptySetStrategy)
+
+    def test_union(self):
+        from pypy.objspace.std.setobject import set_union__Set
+        s1 = W_SetObject(self.space, self.wrapped([1,2,3,4,5]))
+        s2 = W_SetObject(self.space, self.wrapped([4,5,6,7]))
+        s3 = W_SetObject(self.space, self.wrapped([4,'5','6',7]))
+        s4 = set_union__Set(self.space, s1, [s2])
+        s5 = set_union__Set(self.space, s1, [s3])
+        assert s4.strategy is self.space.fromcache(IntegerSetStrategy)
+        assert s5.strategy is self.space.fromcache(ObjectSetStrategy)
+
+    def test_discard(self):
+        class FakeInt(object):
+            def __init__(self, value):
+                self.value = value
+            def __hash__(self):
+                return hash(self.value)
+            def __eq__(self, other):
+                if other == self.value:
+                    return True
+                return False
+
+        from pypy.objspace.std.setobject import set_discard__Set_ANY
+
+        s1 = W_SetObject(self.space, self.wrapped([1,2,3,4,5]))
+        set_discard__Set_ANY(self.space, s1, self.space.wrap("five"))
+        skip("currently not supported")
+        assert s1.strategy is self.space.fromcache(IntegerSetStrategy)
+
+        set_discard__Set_ANY(self.space, s1, self.space.wrap(FakeInt(5)))
+        assert s1.strategy is self.space.fromcache(ObjectSetStrategy)
+
+    def test_has_key(self):
+        class FakeInt(object):
+            def __init__(self, value):
+                self.value = value
+            def __hash__(self):
+                return hash(self.value)
+            def __eq__(self, other):
+                if other == self.value:
+                    return True
+                return False
+
+        from pypy.objspace.std.setobject import set_discard__Set_ANY
+
+        s1 = W_SetObject(self.space, self.wrapped([1,2,3,4,5]))
+        assert not s1.has_key(self.space.wrap("five"))
+        skip("currently not supported")
+        assert s1.strategy is self.space.fromcache(IntegerSetStrategy)
+
+        assert s1.has_key(self.space.wrap(FakeInt(2)))
+        assert s1.strategy is self.space.fromcache(ObjectSetStrategy)
diff --git a/pypy/objspace/std/test/test_stringobject.py b/pypy/objspace/std/test/test_stringobject.py
--- a/pypy/objspace/std/test/test_stringobject.py
+++ b/pypy/objspace/std/test/test_stringobject.py
@@ -85,6 +85,10 @@
         w_slice = space.newslice(w(1), w_None, w(2))
         assert self.space.eq_w(space.getitem(w_str, w_slice), w('el'))
 
+    def test_listview_str(self):
+        w_str = self.space.wrap('abcd')
+        assert self.space.listview_str(w_str) == list("abcd")
+
 class AppTestStringObject:
 
     def test_format_wrongchar(self):
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
@@ -244,8 +244,12 @@
             skip("disabled")
         if self.runappdirect:
             total = 500000
+            def rand():
+                import random
+                return random.randrange(0, 5)
         else:
             total = 50
+            rand = self.rand
         #
         class A(object):
             hash = None
@@ -256,7 +260,7 @@
             a = A()
             a.next = tail.next
             tail.next = a
-            for j in range(self.rand()):
+            for j in range(rand()):
                 any = any.next
             if any.hash is None:
                 any.hash = hash(any)
diff --git a/pypy/rlib/_rffi_stacklet.py b/pypy/rlib/_rffi_stacklet.py
--- a/pypy/rlib/_rffi_stacklet.py
+++ b/pypy/rlib/_rffi_stacklet.py
@@ -14,7 +14,7 @@
     includes = ['src/stacklet/stacklet.h'],
     separate_module_sources = ['#include "src/stacklet/stacklet.c"\n'],
 )
-if sys.platform == 'win32':
+if 'masm' in dir(eci.platform): # Microsoft compiler
     if is_emulated_long:
         asmsrc = 'switch_x64_msvc.asm'
     else:
diff --git a/pypy/rlib/_rsocket_rffi.py b/pypy/rlib/_rsocket_rffi.py
--- a/pypy/rlib/_rsocket_rffi.py
+++ b/pypy/rlib/_rsocket_rffi.py
@@ -58,12 +58,12 @@
     header_lines = [
         '#include <WinSock2.h>',
         '#include <WS2tcpip.h>',
+        '#include <Mstcpip.h>',
         # winsock2 defines AF_UNIX, but not sockaddr_un
         '#undef AF_UNIX',
         ]
     if _MSVC:
         header_lines.extend([
-            '#include <Mstcpip.h>',
             # these types do not exist on microsoft compilers
             'typedef int ssize_t;',
             'typedef unsigned __int16 uint16_t;',
@@ -71,6 +71,7 @@
             ])
     else: # MINGW
         includes = ('stdint.h',)
+        """
         header_lines.extend([
             '''\
             #ifndef _WIN32_WINNT
@@ -88,6 +89,7 @@
                 u_long  keepaliveinterval;
             };'''
             ])
+        """
     HEADER = '\n'.join(header_lines)
     COND_HEADER = ''
 constants = {}
diff --git a/pypy/rlib/clibffi.py b/pypy/rlib/clibffi.py
--- a/pypy/rlib/clibffi.py
+++ b/pypy/rlib/clibffi.py
@@ -114,9 +114,10 @@
         )
 
     eci = rffi_platform.configure_external_library(
-        'libffi', eci,
+        'libffi-5', eci,
         [dict(prefix='libffi-',
               include_dir='include', library_dir='.libs'),
+         dict(prefix=r'c:\mingw64', include_dir='include', library_dir='lib'),
          ])
 else:
     libffidir = py.path.local(pypydir).join('translator', 'c', 'src', 'libffi_msvc')
diff --git a/pypy/rlib/longlong2float.py b/pypy/rlib/longlong2float.py
--- a/pypy/rlib/longlong2float.py
+++ b/pypy/rlib/longlong2float.py
@@ -6,6 +6,7 @@
 in which it does not work.
 """
 
+from __future__ import with_statement
 from pypy.annotation import model as annmodel
 from pypy.rlib.rarithmetic import r_int64
 from pypy.rpython.lltypesystem import lltype, rffi
@@ -20,7 +21,7 @@
 FLOAT_ARRAY_PTR = lltype.Ptr(lltype.Array(rffi.FLOAT))
 
 # these definitions are used only in tests, when not translated
-def longlong2float_emulator(llval):
+def longlong2float(llval):
     with lltype.scoped_alloc(DOUBLE_ARRAY_PTR.TO, 1) as d_array:
         ll_array = rffi.cast(LONGLONG_ARRAY_PTR, d_array)
         ll_array[0] = llval
@@ -50,12 +51,6 @@
 
 eci = ExternalCompilationInfo(includes=['string.h', 'assert.h'],
                               post_include_bits=["""
-static double pypy__longlong2float(long long x) {
-    double dd;
-    assert(sizeof(double) == 8 && sizeof(long long) == 8);
-    memcpy(&dd, &x, 8);
-    return dd;
-}
 static float pypy__uint2singlefloat(unsigned int x) {
     float ff;
     assert(sizeof(float) == 4 && sizeof(unsigned int) == 4);
@@ -70,12 +65,6 @@
 }
 """])
 
-longlong2float = rffi.llexternal(
-    "pypy__longlong2float", [rffi.LONGLONG], rffi.DOUBLE,
-    _callable=longlong2float_emulator, compilation_info=eci,
-    _nowrapper=True, elidable_function=True, sandboxsafe=True,
-    oo_primitive="pypy__longlong2float")
-
 uint2singlefloat = rffi.llexternal(
     "pypy__uint2singlefloat", [rffi.UINT], rffi.FLOAT,
     _callable=uint2singlefloat_emulator, compilation_info=eci,
@@ -98,4 +87,17 @@
 
     def specialize_call(self, hop):
         [v_float] = hop.inputargs(lltype.Float)
-        return hop.genop("convert_float_bytes_to_longlong", [v_float], resulttype=hop.r_result)
+        hop.exception_cannot_occur()
+        return hop.genop("convert_float_bytes_to_longlong", [v_float], resulttype=lltype.SignedLongLong)
+
+class LongLong2FloatEntry(ExtRegistryEntry):
+    _about_ = longlong2float
+
+    def compute_result_annotation(self, s_longlong):
+        assert annmodel.SomeInteger(knowntype=r_int64).contains(s_longlong)
+        return annmodel.SomeFloat()
+
+    def specialize_call(self, hop):
+        [v_longlong] = hop.inputargs(lltype.SignedLongLong)
+        hop.exception_cannot_occur()
+        return hop.genop("convert_longlong_bytes_to_float", [v_longlong], resulttype=lltype.Float)
diff --git a/pypy/rlib/parsing/pypackrat.py b/pypy/rlib/parsing/pypackrat.py
--- a/pypy/rlib/parsing/pypackrat.py
+++ b/pypy/rlib/parsing/pypackrat.py
@@ -1,6 +1,8 @@
 
 from pypy.rlib.parsing.tree import Nonterminal, Symbol
-from makepackrat import PackratParser, BacktrackException, Status
+from pypy.rlib.parsing.makepackrat import PackratParser, BacktrackException, Status
+
+
 class Parser(object):
     def NAME(self):
         return self._NAME().result
diff --git a/pypy/rlib/rmmap.py b/pypy/rlib/rmmap.py
--- a/pypy/rlib/rmmap.py
+++ b/pypy/rlib/rmmap.py
@@ -711,9 +711,9 @@
     free = c_munmap_safe
 
 elif _MS_WINDOWS:
-    def mmap(fileno, length, flags=0, tagname="", access=_ACCESS_DEFAULT, offset=0):
+    def mmap(fileno, length, tagname="", access=_ACCESS_DEFAULT, offset=0):
         # XXX flags is or-ed into access by now.
-        
+        flags = 0
         # check size boundaries
         _check_map_size(length)
         map_size = length
diff --git a/pypy/rlib/rwin32.py b/pypy/rlib/rwin32.py
--- a/pypy/rlib/rwin32.py
+++ b/pypy/rlib/rwin32.py
@@ -141,6 +141,10 @@
         cfile = udir.join('dosmaperr.c')
         cfile.write(r'''
                 #include <errno.h>
+                #include  <stdio.h>
+                #ifdef __GNUC__
+                #define _dosmaperr mingw_dosmaperr
+                #endif
                 int main()
                 {
                     int i;
diff --git a/pypy/rlib/rzipfile.py b/pypy/rlib/rzipfile.py
--- a/pypy/rlib/rzipfile.py
+++ b/pypy/rlib/rzipfile.py
@@ -12,8 +12,7 @@
     rzlib = None
 
 # XXX hack to get crc32 to work
-from pypy.tool.lib_pypy import import_from_lib_pypy
-crc_32_tab = import_from_lib_pypy('binascii').crc_32_tab
+from pypy.module.binascii.interp_crc32 import crc_32_tab
 
 rcrc_32_tab = [r_uint(i) for i in crc_32_tab]
 
diff --git a/pypy/rlib/test/autopath.py b/pypy/rlib/test/autopath.py
new file mode 100644
--- /dev/null
+++ b/pypy/rlib/test/autopath.py
@@ -0,0 +1,131 @@
+"""
+self cloning, automatic path configuration 
+
+copy this into any subdirectory of pypy from which scripts need 
+to be run, typically all of the test subdirs. 
+The idea is that any such script simply issues
+
+    import autopath
+
+and this will make sure that the parent directory containing "pypy"
+is in sys.path. 
+
+If you modify the master "autopath.py" version (in pypy/tool/autopath.py) 
+you can directly run it which will copy itself on all autopath.py files
+it finds under the pypy root directory. 
+
+This module always provides these attributes:
+
+    pypydir    pypy root directory path 
+    this_dir   directory where this autopath.py resides 
+
+"""
+
+def __dirinfo(part):
+    """ return (partdir, this_dir) and insert parent of partdir
+    into sys.path.  If the parent directories don't have the part
+    an EnvironmentError is raised."""
+
+    import sys, os
+    try:
+        head = this_dir = os.path.realpath(os.path.dirname(__file__))
+    except NameError:
+        head = this_dir = os.path.realpath(os.path.dirname(sys.argv[0]))
+
+    error = None
+    while head:
+        partdir = head
+        head, tail = os.path.split(head)
+        if tail == part:
+            checkfile = os.path.join(partdir, os.pardir, 'pypy', '__init__.py')
+            if not os.path.exists(checkfile):
+                error = "Cannot find %r" % (os.path.normpath(checkfile),)
+            break
+    else:
+        error = "Cannot find the parent directory %r of the path %r" % (
+            partdir, this_dir)
+    if not error:
+        # check for bogus end-of-line style (e.g. files checked out on
+        # Windows and moved to Unix)
+        f = open(__file__.replace('.pyc', '.py'), 'r')
+        data = f.read()
+        f.close()
+        if data.endswith('\r\n') or data.endswith('\r'):
+            error = ("Bad end-of-line style in the .py files. Typically "
+                     "caused by a zip file or a checkout done on Windows and "
+                     "moved to Unix or vice-versa.")
+    if error:
+        raise EnvironmentError("Invalid source tree - bogus checkout! " +
+                               error)
+    
+    pypy_root = os.path.join(head, '')
+    try:
+        sys.path.remove(head)
+    except ValueError:
+        pass
+    sys.path.insert(0, head)
+
+    munged = {}
+    for name, mod in sys.modules.items():
+        if '.' in name:
+            continue
+        fn = getattr(mod, '__file__', None)
+        if not isinstance(fn, str):
+            continue
+        newname = os.path.splitext(os.path.basename(fn))[0]
+        if not newname.startswith(part + '.'):
+            continue
+        path = os.path.join(os.path.dirname(os.path.realpath(fn)), '')
+        if path.startswith(pypy_root) and newname != part:
+            modpaths = os.path.normpath(path[len(pypy_root):]).split(os.sep)
+            if newname != '__init__':
+                modpaths.append(newname)
+            modpath = '.'.join(modpaths)
+            if modpath not in sys.modules:
+                munged[modpath] = mod
+
+    for name, mod in munged.iteritems():
+        if name not in sys.modules:
+            sys.modules[name] = mod
+        if '.' in name:
+            prename = name[:name.rfind('.')]
+            postname = name[len(prename)+1:]
+            if prename not in sys.modules:
+                __import__(prename)
+                if not hasattr(sys.modules[prename], postname):
+                    setattr(sys.modules[prename], postname, mod)
+
+    return partdir, this_dir
+
+def __clone():
+    """ clone master version of autopath.py into all subdirs """
+    from os.path import join, walk
+    if not this_dir.endswith(join('pypy','tool')):
+        raise EnvironmentError("can only clone master version "
+                               "'%s'" % join(pypydir, 'tool',_myname))
+
+
+    def sync_walker(arg, dirname, fnames):
+        if _myname in fnames:
+            fn = join(dirname, _myname)
+            f = open(fn, 'rwb+')
+            try:
+                if f.read() == arg:
+                    print "checkok", fn
+                else:
+                    print "syncing", fn
+                    f = open(fn, 'w')
+                    f.write(arg)
+            finally:
+                f.close()
+    s = open(join(pypydir, 'tool', _myname), 'rb').read()
+    walk(pypydir, sync_walker, s)
+
+_myname = 'autopath.py'
+
+# set guaranteed attributes
+
+pypydir, this_dir = __dirinfo('pypy')
+
+if __name__ == '__main__':
+    __clone()
diff --git a/pypy/rlib/test/test_longlong2float.py b/pypy/rlib/test/test_longlong2float.py
--- a/pypy/rlib/test/test_longlong2float.py
+++ b/pypy/rlib/test/test_longlong2float.py
@@ -2,6 +2,7 @@
 from pypy.rlib.longlong2float import longlong2float, float2longlong
 from pypy.rlib.longlong2float import uint2singlefloat, singlefloat2uint
 from pypy.rlib.rarithmetic import r_singlefloat
+from pypy.rpython.test.test_llinterp import interpret
 
 
 def fn(f1):
@@ -31,6 +32,18 @@
         res = fn2(x)
         assert repr(res) == repr(x)
 
+def test_interpreted():
+    def f(f1):
+        try:
+            ll = float2longlong(f1)
+            return longlong2float(ll)
+        except Exception:
+            return 500
+
+    for x in enum_floats():
+        res = interpret(f, [x])
+        assert repr(res) == repr(x)
+
 # ____________________________________________________________
 
 def fnsingle(f1):
diff --git a/pypy/rpython/lltypesystem/lloperation.py b/pypy/rpython/lltypesystem/lloperation.py
--- a/pypy/rpython/lltypesystem/lloperation.py
+++ b/pypy/rpython/lltypesystem/lloperation.py
@@ -350,6 +350,7 @@
     'truncate_longlong_to_int':LLOp(canfold=True),
     'force_cast':           LLOp(sideeffects=False),    # only for rffi.cast()
     'convert_float_bytes_to_longlong': LLOp(canfold=True),
+    'convert_longlong_bytes_to_float': LLOp(canfold=True),
 
     # __________ pointer operations __________
 
diff --git a/pypy/rpython/lltypesystem/opimpl.py b/pypy/rpython/lltypesystem/opimpl.py
--- a/pypy/rpython/lltypesystem/opimpl.py
+++ b/pypy/rpython/lltypesystem/opimpl.py
@@ -427,6 +427,14 @@
 ##    assert type(x) is int
 ##    return llmemory.cast_int_to_adr(x)
 
+def op_convert_float_bytes_to_longlong(a):
+    from pypy.rlib.longlong2float import float2longlong
+    return float2longlong(a)
+
+def op_convert_longlong_bytes_to_float(a):
+    from pypy.rlib.longlong2float import longlong2float
+    return longlong2float(a)
+
 
 def op_unichar_eq(x, y):
     assert isinstance(x, unicode) and len(x) == 1
diff --git a/pypy/rpython/rstr.py b/pypy/rpython/rstr.py
--- a/pypy/rpython/rstr.py
+++ b/pypy/rpython/rstr.py
@@ -165,6 +165,7 @@
         v_char = hop.inputarg(rstr.char_repr, arg=1)
         v_left = hop.inputconst(Bool, left)
         v_right = hop.inputconst(Bool, right)
+        hop.exception_is_here()
         return hop.gendirectcall(self.ll.ll_strip, v_str, v_char, v_left, v_right)
 
     def rtype_method_lstrip(self, hop):
diff --git a/pypy/rpython/test/test_rstr.py b/pypy/rpython/test/test_rstr.py
--- a/pypy/rpython/test/test_rstr.py
+++ b/pypy/rpython/test/test_rstr.py
@@ -637,13 +637,16 @@
     def _make_split_test(self, split_fn):
         const = self.const
         def fn(i):
-            s = [const(''), const('0.1.2.4.8'), const('.1.2'), const('1.2.'), const('.1.2.4.')][i]
-            l = getattr(s, split_fn)(const('.'))
-            sum = 0
-            for num in l:
-                if len(num):
-                    sum += ord(num[0]) - ord(const('0')[0])
-            return sum + len(l) * 100
+            try:
+                s = [const(''), const('0.1.2.4.8'), const('.1.2'), const('1.2.'), const('.1.2.4.')][i]
+                l = getattr(s, split_fn)(const('.'))
+                sum = 0
+                for num in l:
+                    if len(num):
+                        sum += ord(num[0]) - ord(const('0')[0])
+                return sum + len(l) * 100
+            except MemoryError:
+                return 42
         return fn
 
     def test_split(self):
diff --git a/pypy/rpython/tool/rffi_platform.py b/pypy/rpython/tool/rffi_platform.py
--- a/pypy/rpython/tool/rffi_platform.py
+++ b/pypy/rpython/tool/rffi_platform.py
@@ -660,8 +660,8 @@
     if isinstance(fieldtype, lltype.FixedSizeArray):
         size, _ = expected_size_and_sign
         return lltype.FixedSizeArray(fieldtype.OF, size/_sizeof(fieldtype.OF))
-    raise TypeError("conflicting field type %r for %r" % (fieldtype,
-                                                          fieldname))
+    raise TypeError("conflict between translating python and compiler field"
+                    " type %r for %r" % (fieldtype, fieldname))
 
 def expose_value_as_rpython(value):
     if intmask(value) == value:
diff --git a/pypy/tool/release/package.py b/pypy/tool/release/package.py
--- a/pypy/tool/release/package.py
+++ b/pypy/tool/release/package.py
@@ -58,9 +58,13 @@
     binaries = [(pypy_c, rename_pypy_c)]
     #
     if sys.platform == 'win32':
+        #Don't include a mscvrXX.dll, users should get their own.
+        #Instructions are provided on the website.
+
         # Can't rename a DLL: it is always called 'libpypy-c.dll'
+        
         for extra in ['libpypy-c.dll',
-                      'libexpat.dll', 'sqlite3.dll', 'msvcr100.dll',
+                      'libexpat.dll', 'sqlite3.dll', 
                       'libeay32.dll', 'ssleay32.dll']:
             p = pypy_c.dirpath().join(extra)
             if not p.check():
diff --git a/pypy/tool/test/test_lib_pypy.py b/pypy/tool/test/test_lib_pypy.py
--- a/pypy/tool/test/test_lib_pypy.py
+++ b/pypy/tool/test/test_lib_pypy.py
@@ -11,7 +11,7 @@
     assert lib_pypy.LIB_PYTHON_MODIFIED.check(dir=1)
 
 def test_import_from_lib_pypy():
-    binascii = lib_pypy.import_from_lib_pypy('binascii')
-    assert type(binascii) is type(lib_pypy)
-    assert binascii.__name__ == 'lib_pypy.binascii'
-    assert hasattr(binascii, 'crc_32_tab')
+    _functools = lib_pypy.import_from_lib_pypy('_functools')
+    assert type(_functools) is type(lib_pypy)
+    assert _functools.__name__ == 'lib_pypy._functools'
+    assert hasattr(_functools, 'partial')
diff --git a/pypy/translator/c/gcc/test/test_asmgcroot.py b/pypy/translator/c/gcc/test/test_asmgcroot.py
--- a/pypy/translator/c/gcc/test/test_asmgcroot.py
+++ b/pypy/translator/c/gcc/test/test_asmgcroot.py
@@ -6,10 +6,18 @@
 from pypy.annotation.listdef import s_list_of_strings
 from pypy import conftest
 from pypy.translator.tool.cbuild import ExternalCompilationInfo
+from pypy.translator.platform import platform as compiler
+from pypy.rlib.rarithmetic import is_emulated_long
 from pypy.rpython.lltypesystem import lltype, rffi
 from pypy.rlib.entrypoint import entrypoint, secondary_entrypoints
 from pypy.rpython.lltypesystem.lloperation import llop
 
+_MSVC = compiler.name == "msvc"
+_MINGW = compiler.name == "mingw32"
+_WIN32 = _MSVC or _MINGW
+_WIN64 = _WIN32 and is_emulated_long
+# XXX get rid of 'is_emulated_long' and have a real config here.
+
 class AbstractTestAsmGCRoot:
     # the asmgcroot gc transformer doesn't generate gc_reload_possibly_moved
     # instructions:
@@ -17,6 +25,8 @@
 
     @classmethod
     def make_config(cls):
+        if _MSVC and _WIN64:
+            py.test.skip("all asmgcroot tests disabled for MSVC X64")
         from pypy.config.pypyoption import get_pypy_config
         config = get_pypy_config(translating=True)
         config.translation.gc = cls.gcpolicy
diff --git a/pypy/translator/c/gcc/trackgcroot.py b/pypy/translator/c/gcc/trackgcroot.py
--- a/pypy/translator/c/gcc/trackgcroot.py
+++ b/pypy/translator/c/gcc/trackgcroot.py
@@ -485,6 +485,8 @@
         'bswap', 'bt', 'rdtsc',
         'punpck', 'pshufd', 'pcmp', 'pand', 'psllw', 'pslld', 'psllq',
         'paddq', 'pinsr', 'pmul', 'psrl',
+        # all vectors don't produce pointers
+        'v',
         # sign-extending moves should not produce GC pointers
         'cbtw', 'cwtl', 'cwtd', 'cltd', 'cltq', 'cqto',
         # zero-extending moves should not produce GC pointers
diff --git a/pypy/translator/c/src/float.h b/pypy/translator/c/src/float.h
--- a/pypy/translator/c/src/float.h
+++ b/pypy/translator/c/src/float.h
@@ -43,5 +43,6 @@
 #define OP_CAST_FLOAT_TO_LONGLONG(x,r) r = (long long)(x)
 #define OP_CAST_FLOAT_TO_ULONGLONG(x,r) r = (unsigned long long)(x)
 #define OP_CONVERT_FLOAT_BYTES_TO_LONGLONG(x,r) memcpy(&r, &x, sizeof(double))
+#define OP_CONVERT_LONGLONG_BYTES_TO_FLOAT(x,r) memcpy(&r, &x, sizeof(long long))
 #endif
 
diff --git a/pypy/translator/c/src/libffi_msvc/win64.asm b/pypy/translator/c/src/libffi_msvc/win64.asm
new file mode 100644
--- /dev/null
+++ b/pypy/translator/c/src/libffi_msvc/win64.asm
@@ -0,0 +1,156 @@
+PUBLIC	ffi_call_AMD64
+
+EXTRN	__chkstk:NEAR
+EXTRN	ffi_closure_SYSV:NEAR
+
+_TEXT	SEGMENT
+
+;;; ffi_closure_OUTER will be called with these registers set:
+;;;    rax points to 'closure'
+;;;    r11 contains a bit mask that specifies which of the
+;;;    first four parameters are float or double
+;;;
+;;; It must move the parameters passed in registers to their stack location,
+;;; call ffi_closure_SYSV for the actual work, then return the result.
+;;; 
+ffi_closure_OUTER PROC FRAME
+	;; save actual arguments to their stack space.
+	test	r11, 1
+	jne	first_is_float	
+	mov	QWORD PTR [rsp+8], rcx
+	jmp	second
+first_is_float:
+	movlpd	QWORD PTR [rsp+8], xmm0
+
+second:
+	test	r11, 2
+	jne	second_is_float	
+	mov	QWORD PTR [rsp+16], rdx
+	jmp	third
+second_is_float:
+	movlpd	QWORD PTR [rsp+16], xmm1
+
+third:
+	test	r11, 4
+	jne	third_is_float	
+	mov	QWORD PTR [rsp+24], r8
+	jmp	forth
+third_is_float:
+	movlpd	QWORD PTR [rsp+24], xmm2
+
+forth:
+	test	r11, 8
+	jne	forth_is_float	
+	mov	QWORD PTR [rsp+32], r9
+	jmp	done
+forth_is_float:
+	movlpd	QWORD PTR [rsp+32], xmm3
+
+done:
+.ALLOCSTACK 40
+	sub	rsp, 40
+.ENDPROLOG
+	mov	rcx, rax	; context is first parameter
+	mov	rdx, rsp	; stack is second parameter
+	add	rdx, 40		; correct our own area
+	mov	rax, ffi_closure_SYSV
+	call	rax		; call the real closure function
+	;; Here, code is missing that handles float return values
+	add	rsp, 40
+	movd	xmm0, rax	; In case the closure returned a float.
+	ret	0
+ffi_closure_OUTER ENDP
+
+
+;;; ffi_call_AMD64
+
+stack$ = 0
+prepfunc$ = 32
+ecif$ = 40
+bytes$ = 48
+flags$ = 56
+rvalue$ = 64
+fn$ = 72
+
+ffi_call_AMD64 PROC FRAME
+
+	mov	QWORD PTR [rsp+32], r9
+	mov	QWORD PTR [rsp+24], r8
+	mov	QWORD PTR [rsp+16], rdx
+	mov	QWORD PTR [rsp+8], rcx
+.PUSHREG rbp
+	push	rbp
+.ALLOCSTACK 48
+	sub	rsp, 48					; 00000030H
+.SETFRAME rbp, 32
+	lea	rbp, QWORD PTR [rsp+32]
+.ENDPROLOG
+
+	mov	eax, DWORD PTR bytes$[rbp]
+	add	rax, 15
+	and	rax, -16
+	call	__chkstk
+	sub	rsp, rax
+	lea	rax, QWORD PTR [rsp+32]
+	mov	QWORD PTR stack$[rbp], rax
+
+	mov	rdx, QWORD PTR ecif$[rbp]
+	mov	rcx, QWORD PTR stack$[rbp]
+	call	QWORD PTR prepfunc$[rbp]
+
+	mov	rsp, QWORD PTR stack$[rbp]
+
+	movlpd	xmm3, QWORD PTR [rsp+24]
+	movd	r9, xmm3
+
+	movlpd	xmm2, QWORD PTR [rsp+16]
+	movd	r8, xmm2
+
+	movlpd	xmm1, QWORD PTR [rsp+8]
+	movd	rdx, xmm1
+
+	movlpd	xmm0, QWORD PTR [rsp]
+	movd	rcx, xmm0
+
+	call	QWORD PTR fn$[rbp]
+ret_int$:
+ 	cmp	DWORD PTR flags$[rbp], 1 ; FFI_TYPE_INT
+ 	jne	ret_float$
+
+	mov	rcx, QWORD PTR rvalue$[rbp]
+	mov	DWORD PTR [rcx], eax
+	jmp	SHORT ret_nothing$
+
+ret_float$:
+ 	cmp	DWORD PTR flags$[rbp], 2 ; FFI_TYPE_FLOAT
+ 	jne	SHORT ret_double$
+
+ 	mov	rax, QWORD PTR rvalue$[rbp]
+ 	movlpd	QWORD PTR [rax], xmm0
+ 	jmp	SHORT ret_nothing$
+
+ret_double$:
+ 	cmp	DWORD PTR flags$[rbp], 3 ; FFI_TYPE_DOUBLE
+ 	jne	SHORT ret_int64$
+
+ 	mov	rax, QWORD PTR rvalue$[rbp]
+ 	movlpd	QWORD PTR [rax], xmm0
+ 	jmp	SHORT ret_nothing$
+
+ret_int64$:
+  	cmp	DWORD PTR flags$[rbp], 12 ; FFI_TYPE_SINT64
+  	jne	ret_nothing$
+
+ 	mov	rcx, QWORD PTR rvalue$[rbp]
+ 	mov	QWORD PTR [rcx], rax
+ 	jmp	SHORT ret_nothing$
+	
+ret_nothing$:
+	xor	eax, eax
+
+	lea	rsp, QWORD PTR [rbp+16]
+	pop	rbp
+	ret	0
+ffi_call_AMD64 ENDP
+_TEXT	ENDS
+END
diff --git a/pypy/translator/driver.py b/pypy/translator/driver.py
--- a/pypy/translator/driver.py
+++ b/pypy/translator/driver.py
@@ -585,22 +585,6 @@
     #
     task_compile_c = taskdef(task_compile_c, ['source_c'], "Compiling c source")
 
-    def backend_run(self, backend):
-        c_entryp = self.c_entryp
-        standalone = self.standalone 
-        if standalone:
-            os.system(c_entryp)
-        else:
-            runner = self.extra.get('run', lambda f: f())
-            runner(c_entryp)
-
-    def task_run_c(self):
-        self.backend_run('c')
-    #
-    task_run_c = taskdef(task_run_c, ['compile_c'], 
-                         "Running compiled c source",
-                         idemp=True)
-
     def task_llinterpret_lltype(self):
         from pypy.rpython.llinterp import LLInterpreter
         py.log.setconsumer("llinterp operation", None)
@@ -710,11 +694,6 @@
         shutil.copy(main_exe, '.')
         self.log.info("Copied to %s" % os.path.join(os.getcwd(), dllname))
 
-    def task_run_cli(self):
-        pass
-    task_run_cli = taskdef(task_run_cli, ['compile_cli'],
-                              'XXX')
-    
     def task_source_jvm(self):
         from pypy.translator.jvm.genjvm import GenJvm
         from pypy.translator.jvm.node import EntryPoint
diff --git a/pypy/translator/goal/translate.py b/pypy/translator/goal/translate.py
--- a/pypy/translator/goal/translate.py
+++ b/pypy/translator/goal/translate.py
@@ -31,7 +31,6 @@
         ("backendopt", "do backend optimizations", "--backendopt", ""),
         ("source", "create source", "-s --source", ""),
         ("compile", "compile", "-c --compile", " (default goal)"),
-        ("run", "run the resulting binary", "--run", ""),
         ("llinterpret", "interpret the rtyped flow graphs", "--llinterpret", ""),
        ]
 def goal_options():
@@ -78,7 +77,7 @@
                     defaultfactory=list),
     # xxx default goals ['annotate', 'rtype', 'backendopt', 'source', 'compile']
     ArbitraryOption("skipped_goals", "XXX",
-                    defaultfactory=lambda: ['run']),
+                    defaultfactory=list),
     OptionDescription("goal_options",
                       "Goals that should be reached during translation", 
                       goal_options()),        
diff --git a/pypy/translator/jvm/opcodes.py b/pypy/translator/jvm/opcodes.py
--- a/pypy/translator/jvm/opcodes.py
+++ b/pypy/translator/jvm/opcodes.py
@@ -241,4 +241,7 @@
     'cast_ulonglong_to_float':  jvm.PYPYULONGTODOUBLE,
     'cast_primitive':           [PushAllArgs, CastPrimitive, StoreResult],
     'force_cast':               [PushAllArgs, CastPrimitive, StoreResult],
+
+    'convert_float_bytes_to_longlong': jvm.PYPYDOUBLEBYTESTOLONG,
+    'convert_longlong_bytes_to_float': jvm.PYPYLONGBYTESTODOUBLE,
 })
diff --git a/pypy/translator/jvm/typesystem.py b/pypy/translator/jvm/typesystem.py
--- a/pypy/translator/jvm/typesystem.py
+++ b/pypy/translator/jvm/typesystem.py
@@ -941,6 +941,8 @@
 PYPYDOUBLETOULONG =     Method.s(jPyPy, 'double_to_ulong', (jDouble,), jLong)
 PYPYULONGTODOUBLE =     Method.s(jPyPy, 'ulong_to_double', (jLong,), jDouble)
 PYPYLONGBITWISENEGATE = Method.v(jPyPy, 'long_bitwise_negate', (jLong,), jLong)
+PYPYDOUBLEBYTESTOLONG = Method.v(jPyPy, 'pypy__float2longlong', (jDouble,), jLong)
+PYPYLONGBYTESTODOUBLE = Method.v(jPyPy, 'pypy__longlong2float', (jLong,), jDouble)
 PYPYSTRTOINT =          Method.v(jPyPy, 'str_to_int', (jString,), jInt)
 PYPYSTRTOUINT =         Method.v(jPyPy, 'str_to_uint', (jString,), jInt)
 PYPYSTRTOLONG =         Method.v(jPyPy, 'str_to_long', (jString,), jLong)
diff --git a/pypy/translator/platform/__init__.py b/pypy/translator/platform/__init__.py
--- a/pypy/translator/platform/__init__.py
+++ b/pypy/translator/platform/__init__.py
@@ -301,6 +301,8 @@
     global platform
     log.msg("Setting platform to %r cc=%s" % (new_platform,cc))
     platform = pick_platform(new_platform, cc)
+    if not platform:
+        raise ValueError("pick_platform failed")
 
     if new_platform == 'host':
         global host
diff --git a/pypy/translator/platform/windows.py b/pypy/translator/platform/windows.py
--- a/pypy/translator/platform/windows.py
+++ b/pypy/translator/platform/windows.py
@@ -7,15 +7,27 @@
 from pypy.translator.platform import log, _run_subprocess
 from pypy.translator.platform import Platform, posix
 
+def _get_compiler_type(cc, x64_flag):
+    import subprocess
+    if not cc:
+        cc = os.environ.get('CC','')
+    if not cc:
+        return MsvcPlatform(cc=cc, x64=x64_flag)
+    elif cc.startswith('mingw'):
+        return MingwPlatform(cc)
+    try:
+        subprocess.check_output([cc, '--version'])
+    except:
+        raise ValueError,"Could not find compiler specified by cc option" + \
+                " '%s', it must be a valid exe file on your path"%cc
+    return MingwPlatform(cc)
+
 def Windows(cc=None):
-    if cc == 'mingw32':
-        return MingwPlatform(cc)
-    else:
-        return MsvcPlatform(cc, False)
+    return _get_compiler_type(cc, False)
+
+def Windows_x64(cc=None):
+    return _get_compiler_type(cc, True)
     
-def Windows_x64(cc=None):
-    return MsvcPlatform(cc, True)
-
 def _get_msvc_env(vsver, x64flag):
     try:
         toolsdir = os.environ['VS%sCOMNTOOLS' % vsver]
@@ -31,14 +43,16 @@
         vcvars = os.path.join(toolsdir, 'vsvars32.bat')
 
     import subprocess
-    popen = subprocess.Popen('"%s" & set' % (vcvars,),
+    try:
+        popen = subprocess.Popen('"%s" & set' % (vcvars,),
                              stdout=subprocess.PIPE,
                              stderr=subprocess.PIPE)
 
-    stdout, stderr = popen.communicate()
-    if popen.wait() != 0:
-        return
-
+        stdout, stderr = popen.communicate()
+        if popen.wait() != 0:
+            return None
+    except:
+        return None
     env = {}
 
     stdout = stdout.replace("\r\n", "\n")
@@ -395,7 +409,9 @@
     so_ext = 'dll'
 
     def __init__(self, cc=None):
-        Platform.__init__(self, 'gcc')
+        if not cc:
+            cc = 'gcc'
+        Platform.__init__(self, cc)
 
     def _args_for_shared(self, args):
         return ['-shared'] + args
diff --git a/pypy/translator/test/test_driver.py b/pypy/translator/test/test_driver.py
--- a/pypy/translator/test/test_driver.py
+++ b/pypy/translator/test/test_driver.py
@@ -6,7 +6,7 @@
 def test_ctr():
     td = TranslationDriver()
     expected = ['annotate', 'backendopt', 'llinterpret', 'rtype', 'source',
-                'compile', 'run', 'pyjitpl']
+                'compile', 'pyjitpl']
     assert set(td.exposed) == set(expected)
 
     assert td.backend_select_goals(['compile_c']) == ['compile_c']
@@ -33,7 +33,6 @@
                  'rtype_ootype', 'rtype_lltype',
                  'source_cli', 'source_c',
                  'compile_cli', 'compile_c',
-                 'run_c', 'run_cli',
                  'compile_jvm', 'source_jvm', 'run_jvm',
                  'pyjitpl_lltype',
                  'pyjitpl_ootype']
@@ -50,6 +49,6 @@
         'backendopt_lltype']
 
     expected = ['annotate', 'backendopt', 'llinterpret', 'rtype', 'source_c',
-                'compile_c', 'run_c', 'pyjitpl']
+                'compile_c', 'pyjitpl']
 
     assert set(td.exposed) == set(expected)
diff --git a/pypy/translator/test/test_unsimplify.py b/pypy/translator/test/test_unsimplify.py
--- a/pypy/translator/test/test_unsimplify.py
+++ b/pypy/translator/test/test_unsimplify.py
@@ -78,7 +78,7 @@
             return x * 6
         def hello_world():
             if we_are_translated():
-                fd = os.open(tmpfile, os.O_WRONLY | os.O_CREAT, 0)
+                fd = os.open(tmpfile, os.O_WRONLY | os.O_CREAT, 0644)
                 os.close(fd)
         graph, t = translate(f, [int], type_system)
         call_initial_function(t, hello_world)
@@ -97,7 +97,7 @@
             return x * 6
         def goodbye_world():
             if we_are_translated():
-                fd = os.open(tmpfile, os.O_WRONLY | os.O_CREAT, 0)
+                fd = os.open(tmpfile, os.O_WRONLY | os.O_CREAT, 0644)
                 os.close(fd)
         graph, t = translate(f, [int], type_system)
         call_final_function(t, goodbye_world)


More information about the pypy-commit mailing list