Author: Armin Rigo <ar...@tunes.org>
Branch: 
Changeset: r68023:f997b57170d5
Date: 2013-11-14 09:42 +0100
http://bitbucket.org/pypy/pypy/changeset/f997b57170d5/

Log:    hg merge release-2.2.x

diff --git a/README.rst b/README.rst
--- a/README.rst
+++ b/README.rst
@@ -33,7 +33,7 @@
     $ rpython/bin/rpython -Ojit pypy/goal/targetpypystandalone.py
 
 This ends up with ``pypy-c`` binary in the main pypy directory. We suggest
-to use virtualenv with the resulting pypy-c as the interpreter, you can
+to use virtualenv with the resulting pypy-c as the interpreter; you can
 find more details about various installation schemes here:
 
 http://doc.pypy.org/en/latest/getting-started.html#installing-pypy
diff --git a/lib_pypy/cffi/api.py b/lib_pypy/cffi/api.py
--- a/lib_pypy/cffi/api.py
+++ b/lib_pypy/cffi/api.py
@@ -347,6 +347,9 @@
     errno = property(_get_errno, _set_errno, None,
                      "the value of 'errno' from/to the C calls")
 
+    def getwinerror(self, code=-1):
+        return self._backend.getwinerror(code)
+
     def _pointer_to(self, ctype):
         from . import model
         with self._lock:
diff --git a/pypy/doc/conf.py b/pypy/doc/conf.py
--- a/pypy/doc/conf.py
+++ b/pypy/doc/conf.py
@@ -45,9 +45,9 @@
 # built documents.
 #
 # The short X.Y version.
-version = '2.1'
+version = '2.2'
 # The full version, including alpha/beta/rc tags.
-release = '2.1.0'
+release = '2.2.0'
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.
diff --git a/pypy/doc/how-to-release.rst b/pypy/doc/how-to-release.rst
--- a/pypy/doc/how-to-release.rst
+++ b/pypy/doc/how-to-release.rst
@@ -48,6 +48,6 @@
 * send announcements to pypy-dev, python-list,
   python-announce, python-dev ...
 
-* add a tag on jitviewer that corresponds to pypy release
-* add a tag on codespeed that corresponds to pypy release
+* add a tag on the pypy/jitviewer repo that corresponds to pypy release
+* add a tag on the codespeed web site that corresponds to pypy release
 
diff --git a/pypy/doc/index.rst b/pypy/doc/index.rst
--- a/pypy/doc/index.rst
+++ b/pypy/doc/index.rst
@@ -40,7 +40,7 @@
 
 * `FAQ`_: some frequently asked questions.
 
-* `Release 2.1.0`_: the latest official release
+* `Release 2.2.0`_: the latest official release
 
 * `PyPy Blog`_: news and status info about PyPy 
 
@@ -110,7 +110,7 @@
 .. _`Getting Started`: getting-started.html
 .. _`Papers`: extradoc.html
 .. _`Videos`: video-index.html
-.. _`Release 2.1.0`: http://pypy.org/download.html
+.. _`Release 2.2.0`: http://pypy.org/download.html
 .. _`speed.pypy.org`: http://speed.pypy.org
 .. _`RPython toolchain`: translation.html
 .. _`potential project ideas`: project-ideas.html
diff --git a/pypy/doc/release-2.2.0.rst b/pypy/doc/release-2.2.0.rst
new file mode 100644
--- /dev/null
+++ b/pypy/doc/release-2.2.0.rst
@@ -0,0 +1,89 @@
+=======================================
+PyPy 2.2 - Incrementalism
+=======================================
+
+We're pleased to announce PyPy 2.2, which targets version 2.7.3 of the Python
+language. This release main highlight is the introduction of the incremental
+garbage collector, sponsored by the `Raspberry Pi Foundation`_.
+
+This release also contains several bugfixes and performance improvements. 
+
+You can download the PyPy 2.2 release here:
+
+    http://pypy.org/download.html
+
+We would like to thank our donors for the continued support of the PyPy
+project. We showed quite a bit of progress on all three projects (see below)
+and we're slowly running out of funds.
+Please consider donating more so we can finish those projects!  The three
+projects are:
+
+* Py3k (supporting Python 3.x): the release PyPy3 2.2 is imminent.
+
+* STM (software transactional memory): a preview will be released very soon,
+  as soon as we fix a few bugs
+
+* NumPy: the work done is included in the PyPy 2.2 release. More details below.
+
+.. _`Raspberry Pi Foundation`: http://www.raspberrypi.org
+
+What is PyPy?
+=============
+
+PyPy is a very compliant Python interpreter, almost a drop-in replacement for
+CPython 2.7. It's fast (`pypy 2.2 and cpython 2.7.2`_ performance comparison)
+due to its integrated tracing JIT compiler.
+
+This release supports x86 machines running Linux 32/64, Mac OS X 64, Windows
+32, or ARM (ARMv6 or ARMv7, with VFPv3).
+
+Work on the native Windows 64 is still stalling, we would welcome a volunteer
+to handle that.
+
+.. _`pypy 2.2 and cpython 2.7.2`: http://speed.pypy.org
+
+Highlights
+==========
+
+* Our Garbage Collector is now "incremental".  It should avoid almost
+  all pauses due to a major collection taking place.  Previously, it
+  would pause the program (rarely) to walk all live objects, which
+  could take arbitrarily long if your process is using a whole lot of
+  RAM.  Now the same work is done in steps.  This should make PyPy
+  more responsive, e.g. in games.  There are still other pauses, from
+  the GC and the JIT, but they should be on the order of 5
+  milliseconds each.
+
+* The JIT counters for hot code were never reset, which meant that a
+  process running for long enough would eventually JIT-compile more
+  and more rarely executed code.  Not only is it useless to compile
+  such code, but as more compiled code means more memory used, this
+  gives the impression of a memory leak.  This has been tentatively
+  fixed by decreasing the counters from time to time.
+
+* NumPy has been split: now PyPy only contains the core module, called
+  ``_numpypy``.  The ``numpy`` module itself has been moved to
+  ``https://bitbucket.org/pypy/numpy`` and ``numpypy`` disappeared.
+  You need to install NumPy separately with a virtualenv:
+  ``pip install git+https://bitbucket.org/pypy/numpy.git``;
+  or by directly doing
+  ``git clone https://bitbucket.org/pypy/numpy.git``,
+  ``cd numpy``, ``python setup.py install``.
+
+* non-inlined calls have less overhead
+
+* Things that use ``sys.set_trace`` are now JITted (like coverage)
+
+* JSON encoding used to be very fast, now decoding is as well
+
+* various buffer copying methods experience speedups (like list-of-ints to
+  ``int[]`` buffer from cffi)
+
+* We finally wrote (hopefully) all the missing ``os.xxx()`` functions,
+  including ``os.startfile()`` on Windows and a handful of rare ones
+  on Posix.
+
+* numpy has a rudimentary C API that cooperates with ``cpyext``
+
+Cheers,
+Armin Rigo and Maciej Fijalkowski
diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-2.2.rst
copy from pypy/doc/whatsnew-head.rst
copy to pypy/doc/whatsnew-2.2.rst
--- a/pypy/doc/whatsnew-head.rst
+++ b/pypy/doc/whatsnew-2.2.rst
@@ -1,5 +1,5 @@
 ======================
-What's new in PyPy 2.1
+What's new in PyPy 2.2
 ======================
 
 .. this is a revision shortly after release-2.1-beta
diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst
--- a/pypy/doc/whatsnew-head.rst
+++ b/pypy/doc/whatsnew-head.rst
@@ -1,140 +1,7 @@
-======================
-What's new in PyPy 2.1
-======================
+=======================
+What's new in PyPy 2.2+
+=======================
 
-.. this is a revision shortly after release-2.1-beta
-.. startrev: 4eb52818e7c0
+.. this is a revision shortly after release-2.2.x
+.. startrev: 4cd1bc8b3111
 
-.. branch: sanitise_bytecode_dispatch
-Make PyPy's bytecode dispatcher easy to read, and less reliant on RPython
-magic. There is no functional change, though the removal of dead code leads
-to many fewer tests to execute.
-
-.. branch: fastjson
-Fast json decoder written in RPython, about 3-4x faster than the pure Python
-decoder which comes with the stdlib
-
-.. branch: improve-str2charp
-Improve the performance of I/O writing up to 15% by using memcpy instead of
-copying char-by-char in str2charp and get_nonmovingbuffer
-
-.. branch: flowoperators
-Simplify rpython/flowspace/ code by using more metaprogramming.  Create
-SpaceOperator class to gather static information about flow graph operations.
-
-.. branch: package-tk
-Adapt package.py script to compile CFFI tk extension. Add a --without-tk switch
-to optionally skip it.
-
-.. branch: distutils-cppldflags
-Copy CPython's implementation of customize_compiler, dont call split on
-environment variables, honour CFLAGS, CPPFLAGS, LDSHARED and LDFLAGS on Unices.
-
-.. branch: precise-instantiate
-When an RPython class is instantiated via an indirect call (that is, which
-class is being instantiated isn't known precisely) allow the optimizer to have
-more precise information about which functions can be called. Needed for Topaz.
-
-.. branch: ssl_moving_write_buffer
-
-.. branch: pythoninspect-fix
-Make PyPy respect PYTHONINSPECT variable set via os.putenv in the same process
-to start interactive prompt when the script execution finishes. This adds
-new __pypy__.os.real_getenv call that bypasses Python cache and looksup env
-in the underlying OS. Translatorshell now works on PyPy.
-
-.. branch: add-statvfs
-Added os.statvfs and os.fstatvfs
-
-.. branch: statvfs_tests
-Added some addition tests for statvfs.
-
-.. branch: ndarray-subtype
-Allow subclassing ndarray, i.e. matrix
-
-.. branch: ndarray-sort
-Implement ndarray in-place sorting (for numeric types, no non-native byte 
order)
-
-.. branch: pypy-pyarray
-Implement much of numpy's c api in cpyext, allows (slow) access to ndarray
-from c
-
-.. branch: kill-ootype
-
-.. branch: fast-slowpath
-Added an abstraction for functions with a fast and slow path in the JIT. This
-speeds up list.append() and list.pop().
-
-.. branch: curses_fixes
-
-.. branch: foldable-getarrayitem-indexerror
-Constant-fold reading out of constant tuples in PyPy.
-
-.. branch: mro-reorder-numpypy-str
-No longer delegate numpy string_ methods to space.StringObject, in numpy
-this works by kind of by accident. Support for merging the refactor-str-types
-branch
-
-.. branch: kill-typesystem
-Remove the "type system" abstraction, now that there is only ever one kind of
-type system used.
-
-.. branch: kill-gen-store-back-in
-Kills gen_store_back_in_virtualizable - should improve non-inlined calls by
-a bit
-
-.. branch: dotviewer-linewidth
-.. branch: reflex-support
-.. branch: numpypy-inplace-op
-.. branch: rewritten-loop-logging
-.. branch: no-release-gil
-.. branch: safe-win-mmap
-.. branch: boolean-indexing-cleanup
-.. branch: cpyext-best_base
-.. branch: cpyext-int
-.. branch: fileops2
-
-.. branch: nobold-backtrace
-Work on improving UnionError messages and stack trace displays.
-
-.. branch: improve-errors-again
-More improvements and refactorings of error messages.
-
-.. branch: improve-errors-again2
-Unbreak tests in rlib.
-
-.. branch: less-stringly-ops
-Use subclasses of SpaceOperation instead of SpaceOperator objects.
-Random cleanups in flowspace.
-
-.. branch: file-support-in-rpython
-make open() and friends rpython
-
-.. branch: incremental-gc
-Added the new incminimark GC which performs GC in incremental steps
-
-.. branch: fast_cffi_list_init
-fastpath for cffi.new("long[]")
-
-.. branch: remove-eval-frame
-remove a pointless abstraction
-
-.. branch: jit-settrace
-Allow the jit to continue running when sys.settrace() is active, necessary to
-make coverage.py fast
-
-.. branch: remove-numpypy
-Remove lib_pypy/numpypy in favor of external numpy fork
-
-.. branch: jit-counter
-Tweak the jit counters: decay them at minor collection (actually
-only every 32 minor collection is enough). Should avoid the "memory
-leaks" observed in long-running processes, actually created by the
-jit compiling more and more rarely executed paths.
-
-.. branch: fix-trace-jit
-Fixed the usage of sys.settrace() with the JIT. Also made it so using
-sys.settrace() doesn't cause the GIL to be released on every single iteration.
-
-.. branch: rordereddict
-Implement OrderedDict in RPython
diff --git a/pypy/module/_cffi_backend/__init__.py 
b/pypy/module/_cffi_backend/__init__.py
--- a/pypy/module/_cffi_backend/__init__.py
+++ b/pypy/module/_cffi_backend/__init__.py
@@ -1,3 +1,4 @@
+import sys
 from pypy.interpreter.mixedmodule import MixedModule
 from rpython.rlib import rdynload
 
@@ -43,6 +44,8 @@
         'FFI_DEFAULT_ABI': 'ctypefunc._get_abi(space, "FFI_DEFAULT_ABI")',
         'FFI_CDECL': 'ctypefunc._get_abi(space,"FFI_DEFAULT_ABI")',#win32 name
         }
+    if sys.platform == 'win32':
+        interpleveldefs['getwinerror'] = 'cerrno.getwinerror'
 
 for _name in ["RTLD_LAZY", "RTLD_NOW", "RTLD_GLOBAL", "RTLD_LOCAL",
               "RTLD_NODELETE", "RTLD_NOLOAD", "RTLD_DEEPBIND"]:
diff --git a/pypy/module/_cffi_backend/cerrno.py 
b/pypy/module/_cffi_backend/cerrno.py
--- a/pypy/module/_cffi_backend/cerrno.py
+++ b/pypy/module/_cffi_backend/cerrno.py
@@ -39,3 +39,14 @@
 def set_errno(space, errno):
     ec = get_errno_container(space)
     ec._cffi_saved_errno = errno
+
+# ____________________________________________________________
+
+@unwrap_spec(code=int)
+def getwinerror(space, code=-1):
+    from rpython.rlib.rwin32 import FormatError
+    if code == -1:
+        ec = get_errno_container(space)
+        code = ec._cffi_saved_LastError
+    message = FormatError(code)
+    return space.newtuple([space.wrap(code), space.wrap(message)])
diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py 
b/pypy/module/_cffi_backend/test/_backend_test_c.py
--- a/pypy/module/_cffi_backend/test/_backend_test_c.py
+++ b/pypy/module/_cffi_backend/test/_backend_test_c.py
@@ -2687,6 +2687,16 @@
     #
     res = GetLastError()
     assert res == 42
+    #
+    SetLastError(2)
+    code, message = getwinerror()
+    assert code == 2
+    assert message == "The system cannot find the file specified"
+    #
+    code, message = getwinerror(1155)
+    assert code == 1155
+    assert message == ("No application is associated with the "
+                       "specified file for this operation")
 
 def test_nonstandard_integer_types():
     for typename in ['int8_t', 'uint8_t', 'int16_t', 'uint16_t', 'int32_t',
diff --git a/pypy/module/posix/__init__.py b/pypy/module/posix/__init__.py
--- a/pypy/module/posix/__init__.py
+++ b/pypy/module/posix/__init__.py
@@ -27,6 +27,7 @@
             'popen2': 'app_posix.popen2',
             'popen3': 'app_posix.popen3',
             'popen4': 'app_posix.popen4',
+            'startfile': 'app_startfile.startfile',
         })
 
     if hasattr(os, 'wait'):
diff --git a/pypy/module/posix/app_startfile.py 
b/pypy/module/posix/app_startfile.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/posix/app_startfile.py
@@ -0,0 +1,44 @@
+# NOT_RPYTHON
+
+class CFFIWrapper(object):
+    def __init__(self):
+        import cffi
+        ffi = cffi.FFI()
+        ffi.cdef("""
+        HINSTANCE ShellExecuteA(HWND, LPCSTR, LPCSTR, LPCSTR, LPCSTR, INT);
+        HINSTANCE ShellExecuteW(HWND, LPCWSTR, LPCWSTR, LPCWSTR, LPCWSTR, INT);
+        DWORD GetLastError(void);
+        """)
+        self.NULL = ffi.NULL
+        self.cast = ffi.cast
+        self.lib = ffi.dlopen("Shell32.dll")
+        self.SW_SHOWNORMAL = 1
+        self.getwinerror = ffi.getwinerror
+
+_cffi_wrapper = None
+
+
+def startfile(filepath, operation=None):
+    global _cffi_wrapper
+    if _cffi_wrapper is None:
+        _cffi_wrapper = CFFIWrapper()
+    w = _cffi_wrapper
+    #
+    if operation is None:
+        operation = w.NULL
+    if isinstance(filepath, str):
+        if isinstance(operation, unicode):
+            operation = operation.encode("ascii")
+        rc = w.lib.ShellExecuteA(w.NULL, operation, filepath,
+                                 w.NULL, w.NULL, w.SW_SHOWNORMAL)
+    elif isinstance(filepath, unicode):
+        if isinstance(operation, str):
+            operation = operation.decode("ascii")
+        rc = w.lib.ShellExecuteW(w.NULL, operation, filepath,
+                                 w.NULL, w.NULL, w.SW_SHOWNORMAL)
+    else:
+        raise TypeError("argument 1 must be str or unicode")
+    rc = int(w.cast("uintptr_t", rc))
+    if rc <= 32:
+        code, msg = w.getwinerror()
+        raise WindowsError(code, msg, filepath)
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
@@ -52,6 +52,7 @@
 
     def setup_class(cls):
         cls.space = space
+        cls.w_runappdirect = space.wrap(cls.runappdirect)
         cls.w_posix = space.appexec([], GET_POSIX)
         cls.w_path = space.wrap(str(path))
         cls.w_path2 = space.wrap(str(path2))
@@ -1108,6 +1109,28 @@
             assert False, "urandom() always returns the same string"
             # Or very unlucky
 
+    if hasattr(os, 'startfile'):
+        def test_startfile(self):
+            if not self.runappdirect:
+                skip("should not try to import cffi at app-level")
+            startfile = self.posix.startfile
+            for t1 in [str, unicode]:
+                for t2 in [str, unicode]:
+                    e = raises(WindowsError, startfile, t1("\\"), t2("close"))
+                    assert e.value.args[0] == 1155
+                    assert e.value.args[1] == (
+                        "No application is associated with the "
+                        "specified file for this operation")
+                    if len(e.value.args) > 2:
+                        assert e.value.args[2] == t1("\\")
+            #
+            e = raises(WindowsError, startfile, "\\foo\\bar\\baz")
+            assert e.value.args[0] == 2
+            assert e.value.args[1] == (
+                "The system cannot find the file specified")
+            if len(e.value.args) > 2:
+                assert e.value.args[2] == "\\foo\\bar\\baz"
+
 
 class AppTestEnvironment(object):
     def setup_class(cls):
diff --git a/pypy/module/test_lib_pypy/cffi_tests/test_ffi_backend.py 
b/pypy/module/test_lib_pypy/cffi_tests/test_ffi_backend.py
--- a/pypy/module/test_lib_pypy/cffi_tests/test_ffi_backend.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/test_ffi_backend.py
@@ -195,3 +195,20 @@
         assert p.a[0] == 200
         assert p.a[1] == 300
         assert p.a[2] == 400
+
+    @pytest.mark.skipif("sys.platform != 'win32'")
+    def test_getwinerror(self):
+        ffi = FFI()
+        code, message = ffi.getwinerror(1155)
+        assert code == 1155
+        assert message == ("No application is associated with the "
+                           "specified file for this operation")
+        ffi.cdef("void SetLastError(int);")
+        lib = ffi.dlopen("Kernel32.dll")
+        lib.SetLastError(2)
+        code, message = ffi.getwinerror()
+        assert code == 2
+        assert message == "The system cannot find the file specified"
+        code, message = ffi.getwinerror(-1)
+        assert code == 2
+        assert message == "The system cannot find the file specified"
diff --git a/pypy/module/test_lib_pypy/cffi_tests/test_verify.py 
b/pypy/module/test_lib_pypy/cffi_tests/test_verify.py
--- a/pypy/module/test_lib_pypy/cffi_tests/test_verify.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/test_verify.py
@@ -712,7 +712,7 @@
              "#define BAZ ...\n")
     lib = ffi.verify("#define FOO 42\n"
                      "#define BAR (-44)\n"
-                     "#define BAZ 0xffffffffffffffffLL\n")
+                     "#define BAZ 0xffffffffffffffffULL\n")
     assert lib.FOO == 42
     assert lib.BAR == -44
     assert lib.BAZ == 0xffffffffffffffff
@@ -1602,6 +1602,8 @@
                         (maxulong, -1, ''),
                         (-1, 0xffffffff, 'U'),
                         (-1, maxulong, 'UL')]:
+        if c2c and sys.platform == 'win32':
+            continue     # enums may always be signed with MSVC
         ffi = FFI()
         ffi.cdef("enum foo_e { AA=%s };" % c1)
         e = py.test.raises(VerificationError, ffi.verify,
diff --git a/rpython/annotator/bookkeeper.py b/rpython/annotator/bookkeeper.py
--- a/rpython/annotator/bookkeeper.py
+++ b/rpython/annotator/bookkeeper.py
@@ -5,7 +5,6 @@
 from __future__ import absolute_import
 
 import sys, types, inspect, weakref
-from collections import OrderedDict
 
 from rpython.flowspace.model import Constant
 from rpython.annotator.model import (SomeOrderedDict,
@@ -371,7 +370,7 @@
                 for e in x:
                     listdef.generalize(self.immutablevalue(e, False))
                 result = SomeList(listdef)
-        elif tp is dict or tp is r_dict or tp is OrderedDict:
+        elif tp is dict or tp is r_dict or tp is SomeOrderedDict.knowntype:
             if need_const:
                 key = Constant(x)
                 try:
@@ -413,7 +412,7 @@
                     dictdef.generalize_key(self.immutablevalue(ek, False))
                     dictdef.generalize_value(self.immutablevalue(ev, False))
                     dictdef.seen_prebuilt_key(ek)
-                if tp is OrderedDict:
+                if tp is SomeOrderedDict.knowntype:
                     result = SomeOrderedDict(dictdef)
                 else:
                     result = SomeDict(dictdef)
diff --git a/rpython/annotator/builtin.py b/rpython/annotator/builtin.py
--- a/rpython/annotator/builtin.py
+++ b/rpython/annotator/builtin.py
@@ -2,7 +2,6 @@
 Built-in functions.
 """
 import sys
-from collections import OrderedDict
 
 from rpython.annotator.model import (
     SomeInteger, SomeObject, SomeChar, SomeBool, SomeString, SomeTuple, s_Bool,
@@ -364,7 +363,7 @@
 BUILTIN_ANALYZERS[rpython.rlib.objectmodel.instantiate] = robjmodel_instantiate
 BUILTIN_ANALYZERS[rpython.rlib.objectmodel.r_dict] = robjmodel_r_dict
 BUILTIN_ANALYZERS[rpython.rlib.objectmodel.r_ordereddict] = 
robjmodel_r_ordereddict
-BUILTIN_ANALYZERS[OrderedDict] = lambda : 
SomeOrderedDict(getbookkeeper().getdictdef())
+BUILTIN_ANALYZERS[SomeOrderedDict.knowntype] = lambda : 
SomeOrderedDict(getbookkeeper().getdictdef())
 BUILTIN_ANALYZERS[rpython.rlib.objectmodel.hlinvoke] = robjmodel_hlinvoke
 BUILTIN_ANALYZERS[rpython.rlib.objectmodel.keepalive_until_here] = 
robjmodel_keepalive_until_here
 BUILTIN_ANALYZERS[rpython.rtyper.lltypesystem.llmemory.cast_ptr_to_adr] = 
llmemory_cast_ptr_to_adr
diff --git a/rpython/annotator/model.py b/rpython/annotator/model.py
--- a/rpython/annotator/model.py
+++ b/rpython/annotator/model.py
@@ -32,7 +32,6 @@
 import inspect
 import weakref
 from types import BuiltinFunctionType, MethodType
-from collections import OrderedDict
 
 import rpython
 from rpython.tool import descriptor
@@ -357,7 +356,11 @@
             return '{...%s...}' % (len(const),)
 
 class SomeOrderedDict(SomeDict):
-    knowntype = OrderedDict
+    try:
+        from collections import OrderedDict as knowntype
+    except ImportError:    # Python 2.6
+        class PseudoOrderedDict(dict): pass
+        knowntype = PseudoOrderedDict
 
     def method_copy(dct):
         return SomeOrderedDict(dct.dictdef)
diff --git a/rpython/rlib/rwin32.py b/rpython/rlib/rwin32.py
--- a/rpython/rlib/rwin32.py
+++ b/rpython/rlib/rwin32.py
@@ -216,7 +216,7 @@
     def llimpl_FormatError(code):
         "Return a message corresponding to the given Windows error code."
         buf = lltype.malloc(rffi.CCHARPP.TO, 1, flavor='raw')
-
+        buf[0] = lltype.nullptr(rffi.CCHARP.TO)
         try:
             msglen = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
                                    FORMAT_MESSAGE_FROM_SYSTEM,
@@ -225,17 +225,20 @@
                                    DEFAULT_LANGUAGE,
                                    rffi.cast(rffi.CCHARP, buf),
                                    0, None)
+            buflen = intmask(msglen)
 
-            if msglen <= 2:   # includes the case msglen < 0
-                return fake_FormatError(code)
+            # remove trailing cr/lf and dots
+            s_buf = buf[0]
+            while buflen > 0 and (s_buf[buflen - 1] <= ' ' or
+                                  s_buf[buflen - 1] == '.'):
+                buflen -= 1
 
-            # FormatMessage always appends \r\n.
-            buflen = intmask(msglen - 2)
-            assert buflen > 0
-
-            result = rffi.charpsize2str(buf[0], buflen)
+            if buflen <= 0:
+                result = fake_FormatError(code)
+            else:
+                result = rffi.charpsize2str(s_buf, buflen)
+        finally:
             LocalFree(rffi.cast(rffi.VOIDP, buf[0]))
-        finally:
             lltype.free(buf, flavor='raw')
 
         return result
diff --git a/rpython/rtyper/rbuiltin.py b/rpython/rtyper/rbuiltin.py
--- a/rpython/rtyper/rbuiltin.py
+++ b/rpython/rtyper/rbuiltin.py
@@ -1,4 +1,3 @@
-from collections import OrderedDict
 
 from rpython.annotator import model as annmodel
 from rpython.flowspace.model import Constant
@@ -750,7 +749,7 @@
 BUILTIN_TYPER[isinstance] = rtype_builtin_isinstance
 BUILTIN_TYPER[hasattr] = rtype_builtin_hasattr
 BUILTIN_TYPER[objectmodel.r_dict] = rtype_r_dict
-BUILTIN_TYPER[OrderedDict] = rtype_ordered_dict
+BUILTIN_TYPER[annmodel.SomeOrderedDict.knowntype] = rtype_ordered_dict
 BUILTIN_TYPER[objectmodel.r_ordereddict] = rtype_ordered_dict
 
 # _________________________________________________________________
diff --git a/rpython/rtyper/test/test_rordereddict.py 
b/rpython/rtyper/test/test_rordereddict.py
--- a/rpython/rtyper/test/test_rordereddict.py
+++ b/rpython/rtyper/test/test_rordereddict.py
@@ -1,6 +1,9 @@
 
 import py
-from collections import OrderedDict
+try:
+    from collections import OrderedDict
+except ImportError:     # Python 2.6
+    py.test.skip("requires collections.OrderedDict")
 from rpython.rtyper.lltypesystem import lltype, rffi
 from rpython.rtyper.lltypesystem import rordereddict, rstr
 from rpython.rlib.rarithmetic import intmask
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to