Author: Ronan Lamy <[email protected]>
Branch: anntype
Changeset: r80812:84d086b4b9d8
Date: 2015-11-20 18:53 +0000
http://bitbucket.org/pypy/pypy/changeset/84d086b4b9d8/

Log:    hg merge default

diff too long, truncating to 2000 out of 2484 lines

diff --git a/.hgtags b/.hgtags
--- a/.hgtags
+++ b/.hgtags
@@ -17,3 +17,4 @@
 295ee98b69288471b0fcf2e0ede82ce5209eb90b release-2.6.0
 f3ad1e1e1d6215e20d34bb65ab85ff9188c9f559 release-2.6.1
 850edf14b2c75573720f59e95767335fb1affe55 release-4.0.0
+5f8302b8bf9f53056e40426f10c72151564e5b19 release-4.0.1
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -56,14 +56,15 @@
   Anders Chrigstrom
   Eric van Riet Paap
   Wim Lavrijsen
+  Richard Plangger
   Richard Emslie
   Alexander Schremmer
   Dan Villiom Podlaski Christiansen
   Lukas Diekmann
   Sven Hager
   Anders Lehmann
+  Remi Meier
   Aurelien Campeas
-  Remi Meier
   Niklaus Haldimann
   Camillo Bruni
   Laura Creighton
@@ -87,7 +88,6 @@
   Ludovic Aubry
   Jacob Hallen
   Jason Creighton
-  Richard Plangger
   Alex Martelli
   Michal Bendowski
   stian
@@ -200,9 +200,12 @@
   Alex Perry
   Vincent Legoll
   Alan McIntyre
+  Spenser Bauman
   Alexander Sedov
   Attila Gobi
   Christopher Pope
+  Devin Jeanpierre
+  Vaibhav Sood
   Christian Tismer 
   Marc Abramowitz
   Dan Stromberg
@@ -234,6 +237,7 @@
   Lutz Paelike
   Lucio Torre
   Lars Wassermann
+  Philipp Rustemeuer
   Henrik Vendelbo
   Dan Buch
   Miguel de Val Borro
@@ -244,6 +248,7 @@
   Martin Blais
   Lene Wagner
   Tomo Cocoa
+  Kim Jin Su
   Toni Mattis
   Lucas Stadler
   Julian Berman
@@ -253,6 +258,7 @@
   Anna Katrina Dominguez
   William Leslie
   Bobby Impollonia
+  Faye Zhao
   [email protected]
   Andrew Thompson
   Yusei Tahara
@@ -283,6 +289,7 @@
   shoma hosaka
   Daniel Neuh&#228;user
   Ben Mather
+  Niclas Olofsson
   halgari
   Boglarka Vezer
   Chris Pressey
@@ -309,13 +316,16 @@
   Stefan Marr
   jiaaro
   Mads Kiilerich
+  Richard Lancaster
   opassembler.py
   Antony Lee
+  Yaroslav Fedevych
   Jim Hunziker
   Markus Unterwaditzer
   Even Wiik Thomassen
   jbs
   squeaky
+  Zearin
   soareschen
   Kurt Griffiths
   Mike Bayer
@@ -327,6 +337,7 @@
   Anna Ravencroft
   Andrey Churin
   Dan Crosta
+  Tobias Diaz
   Julien Phalip
   Roman Podoliaka
   Dan Loewenherz
diff --git a/lib_pypy/cffi.egg-info/PKG-INFO b/lib_pypy/cffi.egg-info/PKG-INFO
--- a/lib_pypy/cffi.egg-info/PKG-INFO
+++ b/lib_pypy/cffi.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: cffi
-Version: 1.3.0
+Version: 1.3.1
 Summary: Foreign Function Interface for Python calling C code.
 Home-page: http://cffi.readthedocs.org
 Author: Armin Rigo, Maciej Fijalkowski
diff --git a/lib_pypy/cffi/__init__.py b/lib_pypy/cffi/__init__.py
--- a/lib_pypy/cffi/__init__.py
+++ b/lib_pypy/cffi/__init__.py
@@ -4,8 +4,8 @@
 from .api import FFI, CDefError, FFIError
 from .ffiplatform import VerificationError, VerificationMissing
 
-__version__ = "1.3.0"
-__version_info__ = (1, 3, 0)
+__version__ = "1.3.1"
+__version_info__ = (1, 3, 1)
 
 # The verifier module file names are based on the CRC32 of a string that
 # contains the following version number.  It may be older than __version__
diff --git a/lib_pypy/cffi/cparser.py b/lib_pypy/cffi/cparser.py
--- a/lib_pypy/cffi/cparser.py
+++ b/lib_pypy/cffi/cparser.py
@@ -62,7 +62,8 @@
         if csource.startswith('*', endpos):
             parts.append('('); closing += ')'
         level = 0
-        for i in xrange(endpos, len(csource)):
+        i = endpos
+        while i < len(csource):
             c = csource[i]
             if c == '(':
                 level += 1
@@ -73,6 +74,7 @@
             elif c in ',;=':
                 if level == 0:
                     break
+            i += 1
         csource = csource[endpos:i] + closing + csource[i:]
         #print repr(''.join(parts)+csource)
     parts.append(csource)
diff --git a/lib_pypy/cffi/model.py b/lib_pypy/cffi/model.py
--- a/lib_pypy/cffi/model.py
+++ b/lib_pypy/cffi/model.py
@@ -514,12 +514,17 @@
         if self.baseinttype is not None:
             return self.baseinttype.get_cached_btype(ffi, finishlist)
         #
+        from . import api
         if self.enumvalues:
             smallest_value = min(self.enumvalues)
             largest_value = max(self.enumvalues)
         else:
-            smallest_value = 0
-            largest_value = 0
+            import warnings
+            warnings.warn("%r has no values explicitly defined; next version "
+                          "will refuse to guess which integer type it is "
+                          "meant to be (unsigned/signed, int/long)"
+                          % self._get_c_name())
+            smallest_value = largest_value = 0
         if smallest_value < 0:   # needs a signed type
             sign = 1
             candidate1 = PrimitiveType("int")
diff --git a/lib_pypy/greenlet.py b/lib_pypy/greenlet.py
--- a/lib_pypy/greenlet.py
+++ b/lib_pypy/greenlet.py
@@ -88,9 +88,19 @@
         #
         try:
             unbound_method = getattr(_continulet, methodname)
+            _tls.leaving = current
             args, kwds = unbound_method(current, *baseargs, to=target)
-        finally:
             _tls.current = current
+        except:
+            _tls.current = current
+            if hasattr(_tls, 'trace'):
+                _run_trace_callback('throw')
+            _tls.leaving = None
+            raise
+        else:
+            if hasattr(_tls, 'trace'):
+                _run_trace_callback('switch')
+            _tls.leaving = None
         #
         if kwds:
             if args:
@@ -122,6 +132,34 @@
         return f.f_back.f_back.f_back   # go past start(), __switch(), switch()
 
 # ____________________________________________________________
+# Recent additions
+
+GREENLET_USE_GC = True
+GREENLET_USE_TRACING = True
+
+def gettrace():
+    return getattr(_tls, 'trace', None)
+
+def settrace(callback):
+    try:
+        prev = _tls.trace
+        del _tls.trace
+    except AttributeError:
+        prev = None
+    if callback is not None:
+        _tls.trace = callback
+    return prev
+
+def _run_trace_callback(event):
+    try:
+        _tls.trace(event, (_tls.leaving, _tls.current))
+    except:
+        # In case of exceptions trace function is removed
+        if hasattr(_tls, 'trace'):
+            del _tls.trace
+        raise
+
+# ____________________________________________________________
 # Internal stuff
 
 try:
@@ -143,22 +181,32 @@
     _tls.current = gmain
 
 def _greenlet_start(greenlet, args):
-    args, kwds = args
-    _tls.current = greenlet
     try:
-        res = greenlet.run(*args, **kwds)
-    except GreenletExit, e:
-        res = e
+        args, kwds = args
+        _tls.current = greenlet
+        try:
+            if hasattr(_tls, 'trace'):
+                _run_trace_callback('switch')
+            res = greenlet.run(*args, **kwds)
+        except GreenletExit, e:
+            res = e
+        finally:
+            _continuation.permute(greenlet, greenlet.parent)
+        return ((res,), None)
     finally:
-        _continuation.permute(greenlet, greenlet.parent)
-    return ((res,), None)
+        _tls.leaving = greenlet
 
 def _greenlet_throw(greenlet, exc, value, tb):
-    _tls.current = greenlet
     try:
-        raise exc, value, tb
-    except GreenletExit, e:
-        res = e
+        _tls.current = greenlet
+        try:
+            if hasattr(_tls, 'trace'):
+                _run_trace_callback('throw')
+            raise exc, value, tb
+        except GreenletExit, e:
+            res = e
+        finally:
+            _continuation.permute(greenlet, greenlet.parent)
+        return ((res,), None)
     finally:
-        _continuation.permute(greenlet, greenlet.parent)
-    return ((res,), None)
+        _tls.leaving = greenlet
diff --git a/pypy/doc/contributor.rst b/pypy/doc/contributor.rst
--- a/pypy/doc/contributor.rst
+++ b/pypy/doc/contributor.rst
@@ -26,15 +26,15 @@
   Anders Chrigstrom
   Eric van Riet Paap
   Wim Lavrijsen
+  Richard Plangger
   Richard Emslie
   Alexander Schremmer
   Dan Villiom Podlaski Christiansen
   Lukas Diekmann
   Sven Hager
   Anders Lehmann
-  Richard Plangger
+  Remi Meier
   Aurelien Campeas
-  Remi Meier
   Niklaus Haldimann
   Camillo Bruni
   Laura Creighton
@@ -170,9 +170,12 @@
   Alex Perry
   Vincent Legoll
   Alan McIntyre
+  Spenser Bauman
   Alexander Sedov
   Attila Gobi
   Christopher Pope
+  Devin Jeanpierre
+  Vaibhav Sood
   Christian Tismer 
   Marc Abramowitz
   Dan Stromberg
@@ -204,6 +207,7 @@
   Lutz Paelike
   Lucio Torre
   Lars Wassermann
+  Philipp Rustemeuer
   Henrik Vendelbo
   Dan Buch
   Miguel de Val Borro
@@ -214,6 +218,7 @@
   Martin Blais
   Lene Wagner
   Tomo Cocoa
+  Kim Jin Su
   Toni Mattis
   Lucas Stadler
   Julian Berman
@@ -223,6 +228,7 @@
   Anna Katrina Dominguez
   William Leslie
   Bobby Impollonia
+  Faye Zhao
   [email protected]
   Andrew Thompson
   Yusei Tahara
@@ -280,13 +286,16 @@
   Stefan Marr
   jiaaro
   Mads Kiilerich
+  Richard Lancaster
   opassembler.py
   Antony Lee
+  Yaroslav Fedevych
   Jim Hunziker
   Markus Unterwaditzer
   Even Wiik Thomassen
   jbs
   squeaky
+  Zearin
   soareschen
   Kurt Griffiths
   Mike Bayer
@@ -298,6 +307,7 @@
   Anna Ravencroft
   Andrey Churin
   Dan Crosta
+  Tobias Diaz
   Julien Phalip
   Roman Podoliaka
   Dan Loewenherz
diff --git a/pypy/doc/index-of-release-notes.rst 
b/pypy/doc/index-of-release-notes.rst
--- a/pypy/doc/index-of-release-notes.rst
+++ b/pypy/doc/index-of-release-notes.rst
@@ -6,6 +6,7 @@
 
 .. toctree::
 
+   release-4.0.1.rst
    release-4.0.0.rst
    release-2.6.1.rst
    release-2.6.0.rst
diff --git a/pypy/doc/index-of-whatsnew.rst b/pypy/doc/index-of-whatsnew.rst
--- a/pypy/doc/index-of-whatsnew.rst
+++ b/pypy/doc/index-of-whatsnew.rst
@@ -7,6 +7,7 @@
 .. toctree::
 
    whatsnew-head.rst
+   whatsnew-4.0.1.rst
    whatsnew-4.0.0.rst
    whatsnew-2.6.1.rst
    whatsnew-2.6.0.rst
diff --git a/pypy/doc/release-4.0.1.rst b/pypy/doc/release-4.0.1.rst
new file mode 100644
--- /dev/null
+++ b/pypy/doc/release-4.0.1.rst
@@ -0,0 +1,106 @@
+==========
+PyPy 4.0.1
+==========
+
+We have released PyPy 4.0.1, three weeks after PyPy 4.0.0. We have fixed
+a few critical bugs in the JIT compiled code, reported by users. We therefore
+encourage all users of PyPy to update to this version. There are a few minor
+enhancements in this version as well.
+
+You can download the PyPy 4.0.1 release here:
+
+    http://pypy.org/download.html
+
+We would like to thank our donors for the continued support of the PyPy
+project.
+
+We would also like to thank our contributors and 
+encourage new people to join the project. PyPy has many
+layers and we need help with all of them: `PyPy`_ and `RPython`_ documentation
+improvements, tweaking popular `modules`_ to run on pypy, or general `help`_ 
+with making RPython's JIT even better. 
+
+CFFI
+====
+
+While not applicable only to PyPy, `cffi`_ is arguably our most significant
+contribution to the python ecosystem. PyPy 4.0.1 ships with 
+`cffi-1.3.1`_ with the improvements it brings.
+
+.. _`PyPy`: http://doc.pypy.org 
+.. _`RPython`: https://rpython.readthedocs.org
+.. _`cffi`: https://cffi.readthedocs.org
+.. _`cffi-1.3.1`: http://cffi.readthedocs.org/en/latest/whatsnew.html#v1-3-1
+.. _`modules`: 
http://doc.pypy.org/en/latest/project-ideas.html#make-more-python-modules-pypy-friendly
+.. _`help`: http://doc.pypy.org/en/latest/project-ideas.html
+.. _`numpy`: https://bitbucket.org/pypy/numpy
+
+What is PyPy?
+=============
+
+PyPy is a very compliant Python interpreter, almost a drop-in replacement for
+CPython 2.7. It's fast (`pypy and cpython 2.7.x`_ performance comparison)
+due to its integrated tracing JIT compiler.
+
+We also welcome developers of other
+`dynamic languages`_ to see what RPython can do for them.
+
+This release supports **x86** machines on most common operating systems
+(Linux 32/64, Mac OS X 64, Windows 32, OpenBSD, freebsd),
+newer **ARM** hardware (ARMv6 or ARMv7, with VFPv3) running Linux, and the
+big- and little-endian variants of **ppc64** running Linux.
+
+.. _`pypy and cpython 2.7.x`: http://speed.pypy.org
+.. _`dynamic languages`: http://pypyjs.org
+
+Other Highlights (since 4.0.0 released three weeks ago)
+=======================================================
+
+* Bug Fixes
+
+  * Fix a bug when unrolling double loops in JITted code
+
+  * Fix multiple memory leaks in the ssl module, one of which affected
+    `cpython` as well (thanks to Alex Gaynor for pointing those out)
+
+  * Use pkg-config to find ssl headers on OS-X
+
+  * Issues reported with our previous release were resolved_ after reports 
from users on
+    our issue tracker at https://bitbucket.org/pypy/pypy/issues or on IRC at
+    #pypy
+
+* New features:
+
+  * Internal cleanup of RPython class handling
+
+  * Support stackless and greenlets on PPC machines
+
+  * Improve debug logging in subprocesses: use PYPYLOG=jit:log.%d
+    for example to have all subprocesses write the JIT log to a file
+    called 'log.%d', with '%d' replaced with the subprocess' PID.
+
+  * Support PyOS_double_to_string in our cpyext capi compatibility layer
+
+* Numpy:
+
+  * Improve support for __array_interface__
+
+  * Propagate NAN mantissas through float16-float32-float64 conversions
+
+
+* Performance improvements and refactorings:
+
+  * Improvements in slicing byte arrays
+
+  * Improvements in enumerate()
+
+  * Silence some warnings while translating
+
+.. _resolved: http://doc.pypy.org/en/latest/whatsnew-4.0.1.html
+
+Please update, and continue to help us make PyPy better.
+
+Cheers
+
+The PyPy Team
+
diff --git a/pypy/doc/tool/makecontributor.py b/pypy/doc/tool/makecontributor.py
--- a/pypy/doc/tool/makecontributor.py
+++ b/pypy/doc/tool/makecontributor.py
@@ -69,7 +69,9 @@
     'Rami Chowdhury': ['necaris'],
     'Stanislaw Halik':['w31rd0'],
     'Wenzhu Man':['wenzhu man', 'wenzhuman'],
-    'Anton Gulenko':['anton gulenko'],
+    'Anton Gulenko':['anton gulenko', 'anton_gulenko'],
+    'Richard Lancaster':['richardlancaster'],
+    'William Leslie':['William ML Leslie'],
     }
 
 alias_map = {}
diff --git a/pypy/doc/whatsnew-4.0.1.rst b/pypy/doc/whatsnew-4.0.1.rst
new file mode 100644
--- /dev/null
+++ b/pypy/doc/whatsnew-4.0.1.rst
@@ -0,0 +1,35 @@
+=========================
+What's new in PyPy 4.0.1
+=========================
+
+.. this is a revision shortly after release-4.0.0
+.. startrev: 57c9a47c70f6
+
+.. branch: 2174-fix-osx-10-11-translation
+
+Use pkg-config to find ssl headers on OS-X
+
+.. branch: Zearin/minor-whatsnewrst-markup-tweaks-edited-o-1446387512092
+
+.. branch: ppc-stacklet
+
+The PPC machines now support the _continuation module (stackless, greenlets)
+
+.. branch: int_0/i-need-this-library-to-build-on-ubuntu-1-1446717626227
+
+Document that libgdbm-dev is required for translation/packaging
+
+.. branch: propogate-nans
+
+Ensure that ndarray conversion from int16->float16->float32->float16->int16
+preserves all int16 values, even across nan conversions. Also fix argmax, 
argmin
+for nan comparisons
+
+.. branch: array_interface
+
+Support common use-cases for __array_interface__, passes upstream tests
+
+.. branch: no-class-specialize
+
+Some refactoring of class handling in the annotator. 
+Remove class specialisation and _settled_ flag.
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,35 +1,15 @@
 =========================
-What's new in PyPy 4.0.+
+What's new in PyPy 4.1.+
 =========================
 
-.. this is a revision shortly after release-4.0.0
-.. startrev: 57c9a47c70f6
+.. this is a revision shortly after release-4.0.1
+.. startrev: 4b5c840d0da2
 
-.. branch: 2174-fix-osx-10-11-translation
+.. branch: numpy-1.10
 
-Use pkg-config to find ssl headers on OS-X
+Fix tests to run cleanly with -A and start to fix micronumpy for upstream numpy
+which is now 1.10.2
 
-.. branch: Zearin/minor-whatsnewrst-markup-tweaks-edited-o-1446387512092
+.. branch: osx-flat-namespace
 
-.. branch: ppc-stacklet
-
-The PPC machines now support the _continuation module (stackless, greenlets)
-
-.. branch: int_0/i-need-this-library-to-build-on-ubuntu-1-1446717626227
-
-Document that libgdbm-dev is required for translation/packaging
-
-.. branch: propogate-nans
-
-Ensure that ndarray conversion from int16->float16->float32->float16->int16
-preserves all int16 values, even across nan conversions. Also fix argmax, 
argmin
-for nan comparisons
-
-.. branch: array_interface
-
-Support common use-cases for __array_interface__, passes upstream tests
-
-.. branch: no-class-specialize
-
-Some refactoring of class handling in the annotator. 
-Remove class specialisation and _settled_ flag.
+Fix the cpyext tests on OSX by linking with -flat_namespace
diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -391,7 +391,7 @@
         self.check_signal_action = None   # changed by the signal module
         self.user_del_action = UserDelAction(self)
         self._code_of_sys_exc_info = None
-
+        
         # can be overridden to a subclass
         self.initialize()
 
diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py
--- a/pypy/interpreter/pycode.py
+++ b/pypy/interpreter/pycode.py
@@ -50,6 +50,9 @@
     kwargname = varnames[argcount] if code.co_flags & CO_VARKEYWORDS else None
     return Signature(argnames, varargname, kwargname)
 
+class CodeHookCache(object):
+    def __init__(self, space):
+        self._code_hook = None
 
 class PyCode(eval.Code):
     "CPython-style code objects."
@@ -86,6 +89,15 @@
         self._signature = cpython_code_signature(self)
         self._initialize()
         self._init_ready()
+        self.new_code_hook()
+
+    def new_code_hook(self):
+        code_hook = self.space.fromcache(CodeHookCache)._code_hook
+        if code_hook is not None:
+            try:
+                self.space.call_function(code_hook, self)
+            except OperationError, e:
+                e.write_unraisable(self.space, "new_code_hook()")
 
     def _initialize(self):
         if self.co_cellvars:
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
@@ -86,6 +86,7 @@
         'specialized_zip_2_lists'   : 'interp_magic.specialized_zip_2_lists',
         'set_debug'                 : 'interp_magic.set_debug',
         'locals_to_fast'            : 'interp_magic.locals_to_fast',
+        'set_code_callback'         : 'interp_magic.set_code_callback',
         'save_module_content_for_future_reload':
                           'interp_magic.save_module_content_for_future_reload',
     }
diff --git a/pypy/module/__pypy__/interp_magic.py 
b/pypy/module/__pypy__/interp_magic.py
--- a/pypy/module/__pypy__/interp_magic.py
+++ b/pypy/module/__pypy__/interp_magic.py
@@ -1,5 +1,6 @@
 from pypy.interpreter.error import OperationError, wrap_oserror
 from pypy.interpreter.gateway import unwrap_spec
+from pypy.interpreter.pycode import CodeHookCache
 from pypy.interpreter.pyframe import PyFrame
 from pypy.interpreter.mixedmodule import MixedModule
 from rpython.rlib.objectmodel import we_are_translated
@@ -151,3 +152,10 @@
 def specialized_zip_2_lists(space, w_list1, w_list2):
     from pypy.objspace.std.specialisedtupleobject import 
specialized_zip_2_lists
     return specialized_zip_2_lists(space, w_list1, w_list2)
+
+def set_code_callback(space, w_callable):
+    cache = space.fromcache(CodeHookCache)
+    if space.is_none(w_callable):
+        cache._code_hook = None
+    else:
+        cache._code_hook = w_callable
\ No newline at end of file
diff --git a/pypy/module/__pypy__/test/test_magic.py 
b/pypy/module/__pypy__/test/test_magic.py
--- a/pypy/module/__pypy__/test/test_magic.py
+++ b/pypy/module/__pypy__/test/test_magic.py
@@ -13,3 +13,21 @@
         #
         sys.dont_write_bytecode = d
         __pypy__.save_module_content_for_future_reload(sys)
+
+    def test_new_code_hook(self):
+        l = []
+
+        def callable(code):
+            l.append(code)
+
+        import __pypy__
+        __pypy__.set_code_callback(callable)
+        d = {}
+        try:
+            exec """
+def f():
+    pass
+""" in d
+        finally:
+            __pypy__.set_code_callback(None)
+        assert d['f'].__code__ in l
\ No newline at end of file
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
@@ -2,7 +2,7 @@
 from pypy.interpreter.mixedmodule import MixedModule
 from rpython.rlib import rdynload, clibffi
 
-VERSION = "1.3.0"
+VERSION = "1.3.1"
 
 FFI_DEFAULT_ABI = clibffi.FFI_DEFAULT_ABI
 try:
diff --git a/pypy/module/_cffi_backend/ffi_obj.py 
b/pypy/module/_cffi_backend/ffi_obj.py
--- a/pypy/module/_cffi_backend/ffi_obj.py
+++ b/pypy/module/_cffi_backend/ffi_obj.py
@@ -448,7 +448,7 @@
 
 'alloc' is called with the size as argument.  If it returns NULL, a
 MemoryError is raised.  'free' is called with the result of 'alloc'
-as argument.  Both can be either Python function or directly C
+as argument.  Both can be either Python functions or directly C
 functions.  If 'free' is None, then no free function is called.
 If both 'alloc' and 'free' are None, the default is used.
 
diff --git a/pypy/module/_cffi_backend/src/parse_c_type.c 
b/pypy/module/_cffi_backend/src/parse_c_type.c
--- a/pypy/module/_cffi_backend/src/parse_c_type.c
+++ b/pypy/module/_cffi_backend/src/parse_c_type.c
@@ -4,6 +4,7 @@
 #include <errno.h>
 
 #if defined(_MSC_VER)
+# define MS_WIN32
 typedef size_t uintptr_t;
 #else
 # include <stdint.h>
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
@@ -1,7 +1,7 @@
 # ____________________________________________________________
 
 import sys
-assert __version__ == "1.3.0", ("This test_c.py file is for testing a version"
+assert __version__ == "1.3.1", ("This test_c.py file is for testing a version"
                                 " of cffi that differs from the one that we"
                                 " get from 'import _cffi_backend'")
 if sys.version_info < (3,):
diff --git a/pypy/module/_cffi_backend/test/test_recompiler.py 
b/pypy/module/_cffi_backend/test/test_recompiler.py
--- a/pypy/module/_cffi_backend/test/test_recompiler.py
+++ b/pypy/module/_cffi_backend/test/test_recompiler.py
@@ -16,8 +16,8 @@
         from cffi import ffiplatform
     except ImportError:
         py.test.skip("system cffi module not found or older than 1.0.0")
-    if cffi.__version_info__ < (1, 2, 0):
-        py.test.skip("system cffi module needs to be at least 1.2.0")
+    if cffi.__version_info__ < (1, 3, 0):
+        py.test.skip("system cffi module needs to be at least 1.3.0")
     space.appexec([], """():
         import _cffi_backend     # force it to be initialized
     """)
diff --git a/pypy/module/_multiprocessing/interp_win32.py 
b/pypy/module/_multiprocessing/interp_win32.py
--- a/pypy/module/_multiprocessing/interp_win32.py
+++ b/pypy/module/_multiprocessing/interp_win32.py
@@ -17,7 +17,7 @@
     NMPWAIT_WAIT_FOREVER
     ERROR_PIPE_CONNECTED ERROR_SEM_TIMEOUT ERROR_PIPE_BUSY
     ERROR_NO_SYSTEM_RESOURCES ERROR_BROKEN_PIPE ERROR_MORE_DATA
-    ERROR_ALREADY_EXISTS
+    ERROR_ALREADY_EXISTS ERROR_NO_DATA
 """.split()
 
 class CConfig:
diff --git a/pypy/module/cpyext/include/patchlevel.h 
b/pypy/module/cpyext/include/patchlevel.h
--- a/pypy/module/cpyext/include/patchlevel.h
+++ b/pypy/module/cpyext/include/patchlevel.h
@@ -29,7 +29,7 @@
 #define PY_VERSION             "2.7.10"
 
 /* PyPy version as a string */
-#define PYPY_VERSION "4.0.1-alpha0"
+#define PYPY_VERSION "4.1.0-alpha0"
 
 /* Subversion Revision number of this file (not of the repository).
  * Empty since Mercurial migration. */
diff --git a/pypy/module/cpyext/pystrtod.py b/pypy/module/cpyext/pystrtod.py
--- a/pypy/module/cpyext/pystrtod.py
+++ b/pypy/module/cpyext/pystrtod.py
@@ -5,10 +5,23 @@
 from rpython.rlib import rdtoa
 from rpython.rlib import rfloat
 from rpython.rlib import rposix, jit
+from rpython.rlib.rarithmetic import intmask
 from rpython.rtyper.lltypesystem import lltype
 from rpython.rtyper.lltypesystem import rffi
 
 
+# PyOS_double_to_string's "type", if non-NULL, will be set to one of:
+Py_DTST_FINITE = 0
+Py_DTST_INFINITE = 1
+Py_DTST_NAN = 2
+
+# Match the "type" back to values in CPython
+DOUBLE_TO_STRING_TYPES_MAP = {
+    rfloat.DIST_FINITE: Py_DTST_FINITE,
+    rfloat.DIST_INFINITY: Py_DTST_INFINITE,
+    rfloat.DIST_NAN: Py_DTST_NAN
+}
+
 @cpython_api([rffi.CCHARP, rffi.CCHARPP, PyObject], rffi.DOUBLE, error=-1.0)
 @jit.dont_look_inside       # direct use of _get_errno()
 def PyOS_string_to_double(space, s, endptr, w_overflow_exception):
@@ -68,3 +81,42 @@
     finally:
         if not user_endptr:
             lltype.free(endptr, flavor='raw')
+
+@cpython_api([rffi.DOUBLE, lltype.Char, rffi.INT_real, rffi.INT_real, 
rffi.INTP], rffi.CCHARP)
+def PyOS_double_to_string(space, val, format_code, precision, flags, ptype):
+    """Convert a double val to a string using supplied
+    format_code, precision, and flags.
+
+    format_code must be one of 'e', 'E', 'f', 'F',
+    'g', 'G' or 'r'.  For 'r', the supplied precision
+    must be 0 and is ignored.  The 'r' format code specifies the
+    standard repr() format.
+
+    flags can be zero or more of the values Py_DTSF_SIGN,
+    Py_DTSF_ADD_DOT_0, or Py_DTSF_ALT, or-ed together:
+
+    Py_DTSF_SIGN means to always precede the returned string with a sign
+    character, even if val is non-negative.
+
+    Py_DTSF_ADD_DOT_0 means to ensure that the returned string will not look
+    like an integer.
+
+    Py_DTSF_ALT means to apply "alternate" formatting rules.  See the
+    documentation for the PyOS_snprintf() '#' specifier for
+    details.
+
+    If ptype is non-NULL, then the value it points to will be set to one of
+    Py_DTST_FINITE, Py_DTST_INFINITE, or Py_DTST_NAN, signifying that
+    val is a finite number, an infinite number, or not a number, respectively.
+
+    The return value is a pointer to buffer with the converted string or
+    NULL if the conversion failed. The caller is responsible for freeing the
+    returned string by calling PyMem_Free().
+    """
+    buffer, rtype = rfloat.double_to_string(val, format_code,
+                                            intmask(precision),
+                                            intmask(flags))
+    if ptype != lltype.nullptr(rffi.INTP.TO):
+        ptype[0] = rffi.cast(rffi.INT, DOUBLE_TO_STRING_TYPES_MAP[rtype])
+    bufp = rffi.str2charp(buffer)
+    return bufp
diff --git a/pypy/module/cpyext/test/test_pystrtod.py 
b/pypy/module/cpyext/test/test_pystrtod.py
--- a/pypy/module/cpyext/test/test_pystrtod.py
+++ b/pypy/module/cpyext/test/test_pystrtod.py
@@ -1,5 +1,6 @@
 import math
 
+from pypy.module.cpyext import pystrtod
 from pypy.module.cpyext.test.test_api import BaseApiTest
 from rpython.rtyper.lltypesystem import rffi
 from rpython.rtyper.lltypesystem import lltype
@@ -91,3 +92,76 @@
         api.PyErr_Clear()
         rffi.free_charp(s)
         lltype.free(endp, flavor='raw')
+
+
+class TestPyOS_double_to_string(BaseApiTest):
+
+    def test_format_code(self, api):
+        ptype = lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
+        r = api.PyOS_double_to_string(150.0, 'e', 1, 0, ptype)
+        assert '1.5e+02' == rffi.charp2str(r)
+        type_value = rffi.cast(lltype.Signed, ptype[0])
+        assert pystrtod.Py_DTST_FINITE == type_value
+        rffi.free_charp(r)
+        lltype.free(ptype, flavor='raw')
+
+    def test_precision(self, api):
+        ptype = lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
+        r = api.PyOS_double_to_string(3.14159269397, 'g', 5, 0, ptype)
+        assert '3.1416' == rffi.charp2str(r)
+        type_value = rffi.cast(lltype.Signed, ptype[0])
+        assert pystrtod.Py_DTST_FINITE == type_value
+        rffi.free_charp(r)
+        lltype.free(ptype, flavor='raw')
+
+    def test_flags_sign(self, api):
+        ptype = lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
+        r = api.PyOS_double_to_string(-3.14, 'g', 3, 1, ptype)
+        assert '-3.14' == rffi.charp2str(r)
+        type_value = rffi.cast(lltype.Signed, ptype[0])
+        assert pystrtod.Py_DTST_FINITE == type_value
+        rffi.free_charp(r)
+        lltype.free(ptype, flavor='raw')
+
+    def test_flags_add_dot_0(self, api):
+        ptype = lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
+        r = api.PyOS_double_to_string(3, 'g', 5, 2, ptype)
+        assert '3.0' == rffi.charp2str(r)
+        type_value = rffi.cast(lltype.Signed, ptype[0])
+        assert pystrtod.Py_DTST_FINITE == type_value
+        rffi.free_charp(r)
+        lltype.free(ptype, flavor='raw')
+
+    def test_flags_alt(self, api):
+        ptype = lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
+        r = api.PyOS_double_to_string(314., 'g', 3, 4, ptype)
+        assert '314.' == rffi.charp2str(r)
+        type_value = rffi.cast(lltype.Signed, ptype[0])
+        assert pystrtod.Py_DTST_FINITE == type_value
+        rffi.free_charp(r)
+        lltype.free(ptype, flavor='raw')
+
+    def test_ptype_nan(self, api):
+        ptype = lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
+        r = api.PyOS_double_to_string(float('nan'), 'g', 3, 4, ptype)
+        assert 'nan' == rffi.charp2str(r)
+        type_value = rffi.cast(lltype.Signed, ptype[0])
+        assert pystrtod.Py_DTST_NAN == type_value
+        rffi.free_charp(r)
+        lltype.free(ptype, flavor='raw')
+
+    def test_ptype_infinity(self, api):
+        ptype = lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
+        r = api.PyOS_double_to_string(1e200 * 1e200, 'g', 0, 0, ptype)
+        assert 'inf' == rffi.charp2str(r)
+        type_value = rffi.cast(lltype.Signed, ptype[0])
+        assert pystrtod.Py_DTST_INFINITE == type_value
+        rffi.free_charp(r)
+        lltype.free(ptype, flavor='raw')
+
+    def test_ptype_null(self, api):
+        ptype = lltype.nullptr(rffi.INTP.TO)
+        r = api.PyOS_double_to_string(3.14, 'g', 3, 0, ptype)
+        assert '3.14' == rffi.charp2str(r)
+        assert ptype == lltype.nullptr(rffi.INTP.TO)
+        rffi.free_charp(r)
\ No newline at end of file
diff --git a/pypy/module/micronumpy/__init__.py 
b/pypy/module/micronumpy/__init__.py
--- a/pypy/module/micronumpy/__init__.py
+++ b/pypy/module/micronumpy/__init__.py
@@ -34,6 +34,7 @@
         'nditer': 'nditer.W_NDIter',
 
         'set_docstring': 'support.descr_set_docstring',
+        'VisibleDeprecationWarning': 'support.W_VisibleDeprecationWarning',
     }
     for c in ['MAXDIMS', 'CLIP', 'WRAP', 'RAISE']:
         interpleveldefs[c] = 'space.wrap(constants.%s)' % c
@@ -42,6 +43,7 @@
         from pypy.module.micronumpy.concrete import _setup
         _setup()
 
+
 class UMathModule(MixedModule):
     appleveldefs = {}
     interpleveldefs = {
@@ -138,3 +140,9 @@
         'multiarray': MultiArrayModule,
         'umath': UMathModule,
     }
+
+    def setup_after_space_initialization(self):
+        from pypy.module.micronumpy.support import W_VisibleDeprecationWarning
+        for name, w_type in {'VisibleDeprecationWarning': 
W_VisibleDeprecationWarning}.items():
+            setattr(self.space, 'w_' + name, self.space.gettypefor(w_type))
+
diff --git a/pypy/module/micronumpy/base.py b/pypy/module/micronumpy/base.py
--- a/pypy/module/micronumpy/base.py
+++ b/pypy/module/micronumpy/base.py
@@ -44,7 +44,7 @@
         from pypy.module.micronumpy.strides import calc_strides
         if len(shape) > NPY.MAXDIMS:
             raise oefmt(space.w_ValueError,
-                "sequence too large; must be smaller than %d", NPY.MAXDIMS)
+                "sequence too large; cannot be greater than %d", NPY.MAXDIMS)
         try:
             ovfcheck(support.product_check(shape) * dtype.elsize)
         except OverflowError as e:
@@ -69,7 +69,7 @@
         isize = dtype.elsize
         if len(shape) > NPY.MAXDIMS:
             raise oefmt(space.w_ValueError,
-                "sequence too large; must be smaller than %d", NPY.MAXDIMS)
+                "sequence too large; cannot be greater than %d", NPY.MAXDIMS)
         try:
             totalsize = ovfcheck(support.product_check(shape) * isize)
         except OverflowError as e:
diff --git a/pypy/module/micronumpy/boxes.py b/pypy/module/micronumpy/boxes.py
--- a/pypy/module/micronumpy/boxes.py
+++ b/pypy/module/micronumpy/boxes.py
@@ -444,7 +444,7 @@
 
     @unwrap_spec(axis1=int, axis2=int)
     def descr_swapaxes(self, space, axis1, axis2):
-        return self
+        raise oefmt(space.w_ValueError, 'bad axis1 argument to swapaxes')
 
     def descr_fill(self, space, w_value):
         self.get_dtype(space).coerce(space, w_value)
@@ -573,7 +573,7 @@
         try:
             ofs, dtype = self.dtype.fields[item]
         except KeyError:
-            raise oefmt(space.w_IndexError, "invalid index")
+            raise oefmt(space.w_ValueError, "no field of name %s", item)
 
         from pypy.module.micronumpy.types import VoidType
         if isinstance(dtype.itemtype, VoidType):
diff --git a/pypy/module/micronumpy/compile.py 
b/pypy/module/micronumpy/compile.py
--- a/pypy/module/micronumpy/compile.py
+++ b/pypy/module/micronumpy/compile.py
@@ -65,6 +65,7 @@
     w_KeyError = W_TypeObject("KeyError")
     w_SystemExit = W_TypeObject("SystemExit")
     w_KeyboardInterrupt = W_TypeObject("KeyboardInterrupt")
+    w_VisibleDeprecationWarning = W_TypeObject("VisibleDeprecationWarning")
     w_None = None
 
     w_bool = W_TypeObject("bool")
@@ -402,6 +403,9 @@
         assert isinstance(w_check_class, W_TypeObject)
         return w_exc_type.name == w_check_class.name
 
+    def warn(self, w_msg, w_warn_type):
+        pass
+
 class FloatObject(W_Root):
     tp = FakeSpace.w_float
     def __init__(self, floatval):
diff --git a/pypy/module/micronumpy/concrete.py 
b/pypy/module/micronumpy/concrete.py
--- a/pypy/module/micronumpy/concrete.py
+++ b/pypy/module/micronumpy/concrete.py
@@ -457,7 +457,7 @@
     def set_shape(self, space, orig_array, new_shape):
         if len(new_shape) > NPY.MAXDIMS:
             raise oefmt(space.w_ValueError,
-                "sequence too large; must be smaller than %d", NPY.MAXDIMS)
+                "sequence too large; cannot be greater than %d", NPY.MAXDIMS)
         try:
             ovfcheck(support.product_check(new_shape) * self.dtype.elsize)
         except OverflowError as e:
@@ -601,7 +601,7 @@
     def set_shape(self, space, orig_array, new_shape):
         if len(new_shape) > NPY.MAXDIMS:
             raise oefmt(space.w_ValueError,
-                "sequence too large; must be smaller than %d", NPY.MAXDIMS)
+                "sequence too large; cannot be greater than %d", NPY.MAXDIMS)
         try:
             ovfcheck(support.product_check(new_shape) * self.dtype.elsize)
         except OverflowError as e:
diff --git a/pypy/module/micronumpy/ctors.py b/pypy/module/micronumpy/ctors.py
--- a/pypy/module/micronumpy/ctors.py
+++ b/pypy/module/micronumpy/ctors.py
@@ -18,7 +18,7 @@
         raise oefmt(space.w_TypeError,
                     "argument 1 must be numpy.dtype, not %T", w_dtype)
     if w_dtype.elsize == 0:
-        raise oefmt(space.w_ValueError, "itemsize cannot be zero")
+        raise oefmt(space.w_TypeError, "Empty data-type")
     if not space.isinstance_w(w_state, space.w_str):
         raise oefmt(space.w_TypeError, "initializing object must be a string")
     if space.len_w(w_state) != w_dtype.elsize:
diff --git a/pypy/module/micronumpy/descriptor.py 
b/pypy/module/micronumpy/descriptor.py
--- a/pypy/module/micronumpy/descriptor.py
+++ b/pypy/module/micronumpy/descriptor.py
@@ -217,6 +217,8 @@
             endian = ignore
         if self.num == NPY.UNICODE:
             size >>= 2
+        if self.num == NPY.OBJECT:
+            return "%s%s" %(endian, basic)
         return "%s%s%s" % (endian, basic, size)
 
     def descr_get_descr(self, space, style='descr', force_dict=False):
@@ -485,7 +487,12 @@
 
     def descr_str(self, space):
         if self.fields:
-            return space.str(self.descr_get_descr(space, style='str'))
+            r = self.descr_get_descr(space, style='str')
+            name = space.str_w(space.str(self.w_box_type))
+            if name != "<type 'numpy.void'>":
+                boxname = space.str(self.w_box_type)
+                r = space.newtuple([self.w_box_type, r])
+            return space.str(r)
         elif self.subdtype is not None:
             return space.str(space.newtuple([
                 self.subdtype.descr_get_str(space),
@@ -497,8 +504,13 @@
                 return self.descr_get_name(space)
 
     def descr_repr(self, space):
+        if isinstance(self.itemtype, types.CharType):
+            return space.wrap("dtype('S1')")
         if self.fields:
             r = self.descr_get_descr(space, style='repr')
+            name = space.str_w(space.str(self.w_box_type))
+            if name != "<type 'numpy.void'>":
+                r = space.newtuple([space.wrap(self.w_box_type), r])
         elif self.subdtype is not None:
             r = space.newtuple([self.subdtype.descr_get_str(space),
                                 self.descr_get_shape(space)])
@@ -942,7 +954,7 @@
     shape_w = space.fixedview(w_shape)
     if len(shape_w) < 1:
         return None
-    elif len(shape_w) == 1 and space.isinstance_w(shape_w[0], space.w_tuple):
+    elif space.isinstance_w(shape_w[0], space.w_tuple):
         # (base_dtype, new_dtype) dtype spectification
         return None
     shape = []
@@ -997,12 +1009,16 @@
         if len(spec) > 0:
             # this is (base_dtype, new_dtype) so just make it a union by 
setting both
             # parts' offset to 0
-            try:
-                dtype1 = make_new_dtype(space, w_subtype, w_shape, alignment)
-            except:
-                raise
-            raise oefmt(space.w_NotImplementedError, 
-                "(base_dtype, new_dtype) dtype spectification discouraged, not 
implemented")
+            w_dtype1 = make_new_dtype(space, w_subtype, w_shape, alignment)
+            assert isinstance(w_dtype, W_Dtype)
+            assert isinstance(w_dtype1, W_Dtype)
+            if (w_dtype.elsize != 0 and w_dtype1.elsize != 0 and 
+                    w_dtype1.elsize != w_dtype.elsize):
+                raise oefmt(space.w_ValueError,
+                    'mismatch in size of old and new data-descriptor')
+            retval = W_Dtype(w_dtype.itemtype, w_dtype.w_box_type,
+                    names=w_dtype1.names[:], fields=w_dtype1.fields.copy())
+            return retval
     if space.is_none(w_dtype):
         return cache.w_float64dtype
     if space.isinstance_w(w_dtype, w_subtype):
@@ -1032,19 +1048,22 @@
     elif space.isinstance_w(w_dtype, space.w_tuple):
         w_dtype0 = space.getitem(w_dtype, space.wrap(0))
         w_dtype1 = space.getitem(w_dtype, space.wrap(1))
-        if space.isinstance_w(w_dtype0, space.w_type) and \
-           space.isinstance_w(w_dtype1, space.w_list):
-            #obscure api - (subclass, spec). Ignore the subclass
-            return make_new_dtype(space, w_subtype, w_dtype1, alignment, 
-                        copy=copy, w_shape=w_shape, w_metadata=w_metadata)
-        subdtype = make_new_dtype(space, w_subtype, w_dtype0, alignment, copy)
-        assert isinstance(subdtype, W_Dtype)
-        if subdtype.elsize == 0:
-            name = "%s%d" % (subdtype.kind, space.int_w(w_dtype1))
+        # create a new dtype object
+        l_side = make_new_dtype(space, w_subtype, w_dtype0, alignment, copy)
+        assert isinstance(l_side, W_Dtype)
+        if l_side.elsize == 0 and space.isinstance_w(w_dtype1, space.w_int):
+            #(flexible_dtype, itemsize)
+            name = "%s%d" % (l_side.kind, space.int_w(w_dtype1))
             retval = make_new_dtype(space, w_subtype, space.wrap(name), 
alignment, copy)
-        else:
-            retval = make_new_dtype(space, w_subtype, w_dtype0, alignment, 
copy, w_shape=w_dtype1)
-        return _set_metadata_and_copy(space, w_metadata, retval, copy)
+            return _set_metadata_and_copy(space, w_metadata, retval, copy)
+        elif (space.isinstance_w(w_dtype1, space.w_int) or
+                space.isinstance_w(w_dtype1, space.w_tuple) or 
+                space.isinstance_w(w_dtype1, space.w_list) or 
+                isinstance(w_dtype1, W_NDimArray)):
+            #(fixed_dtype, shape) or (base_dtype, new_dtype)
+            retval = make_new_dtype(space, w_subtype, l_side, alignment,
+                                    copy, w_shape=w_dtype1)
+            return _set_metadata_and_copy(space, w_metadata, retval, copy)
     elif space.isinstance_w(w_dtype, space.w_dict):
         return _set_metadata_and_copy(space, w_metadata,
                 dtype_from_dict(space, w_dtype, alignment), copy)
@@ -1122,7 +1141,7 @@
             size = int(name[1:])
         except ValueError:
             raise oefmt(space.w_TypeError, "data type not understood")
-    if char == NPY.CHARLTR:
+    if char == NPY.CHARLTR and size == 0:
         return W_Dtype(
             types.CharType(space),
             elsize=1,
@@ -1133,7 +1152,7 @@
         return new_unicode_dtype(space, size)
     elif char == NPY.VOIDLTR:
         return new_void_dtype(space, size)
-    assert False
+    raise oefmt(space.w_TypeError, 'data type "%s" not understood', name)
 
 
 def new_string_dtype(space, size):
diff --git a/pypy/module/micronumpy/loop.py b/pypy/module/micronumpy/loop.py
--- a/pypy/module/micronumpy/loop.py
+++ b/pypy/module/micronumpy/loop.py
@@ -684,8 +684,9 @@
     arr_iter, arr_state = arr.create_iter()
     arr_dtype = arr.get_dtype()
     index_dtype = index.get_dtype()
-    # XXX length of shape of index as well?
-    while not index_iter.done(index_state):
+    # support the deprecated form where arr([True]) will return arr[0, ...]
+    # by iterating over res_iter, not index_iter
+    while not res_iter.done(res_state):
         getitem_filter_driver.jit_merge_point(shapelen=shapelen,
                                               index_dtype=index_dtype,
                                               arr_dtype=arr_dtype,
diff --git a/pypy/module/micronumpy/ndarray.py 
b/pypy/module/micronumpy/ndarray.py
--- a/pypy/module/micronumpy/ndarray.py
+++ b/pypy/module/micronumpy/ndarray.py
@@ -75,7 +75,7 @@
         dtype = space.interp_w(descriptor.W_Dtype, space.call_function(
             space.gettypefor(descriptor.W_Dtype), w_dtype))
         if (dtype.elsize != self.get_dtype().elsize or
-                dtype.is_flexible() or self.get_dtype().is_flexible()):
+                (not dtype.is_record() and self.get_dtype().is_flexible())):
             raise OperationError(space.w_ValueError, space.wrap(
                 "new type not compatible with array."))
         self.implementation.set_dtype(space, dtype)
@@ -116,6 +116,13 @@
                 "index out of range for array"))
         size = loop.count_all_true(arr)
         if arr.ndims() == 1:
+            if self.ndims() > 1 and arr.get_shape()[0] != self.get_shape()[0]:
+                msg = ("boolean index did not match indexed array along"
+                      " dimension 0; dimension is %d but corresponding"
+                      " boolean dimension is %d" % (self.get_shape()[0],
+                      arr.get_shape()[0]))
+                #warning = 
space.gettypefor(support.W_VisibleDeprecationWarning)
+                space.warn(space.wrap(msg), space.w_VisibleDeprecationWarning)
             res_shape = [size] + self.get_shape()[1:]
         else:
             res_shape = [size]
@@ -278,7 +285,7 @@
     def getfield(self, space, field):
         dtype = self.get_dtype()
         if field not in dtype.fields:
-            raise oefmt(space.w_ValueError, "field named %s not found", field)
+            raise oefmt(space.w_ValueError, "no field of name %s", field)
         arr = self.implementation
         ofs, subdtype = arr.dtype.fields[field][:2]
         # ofs only changes start
@@ -489,10 +496,8 @@
         numpy.swapaxes : equivalent function
         """
         if axis1 == axis2:
-            return self
+            return self.descr_view(space)
         n = self.ndims()
-        if n <= 1:
-            return self
         if axis1 < 0:
             axis1 += n
         if axis2 < 0:
@@ -501,6 +506,8 @@
             raise oefmt(space.w_ValueError, "bad axis1 argument to swapaxes")
         if axis2 < 0 or axis2 >= n:
             raise oefmt(space.w_ValueError, "bad axis2 argument to swapaxes")
+        if n <= 1:
+            return self
         return self.implementation.swapaxes(space, self, axis1, axis2)
 
     def descr_nonzero(self, space):
@@ -899,7 +906,7 @@
                     if cur_shape[i] != 1:
                         raise OperationError(space.w_ValueError, space.wrap(
                             "cannot select an axis to squeeze out "
-                            "which has size greater than one"))
+                            "which has size not equal to one"))
                 else:
                     new_shape.append(cur_shape[i])
         else:
@@ -1374,7 +1381,7 @@
     shape = shape_converter(space, w_shape, dtype)
     if len(shape) > NPY.MAXDIMS:
         raise oefmt(space.w_ValueError,
-            "sequence too large; must be smaller than %d", NPY.MAXDIMS)
+            "sequence too large; cannot be greater than %d", NPY.MAXDIMS)
     if not space.is_none(w_buffer):
         if (not space.is_none(w_strides)):
             strides = [space.int_w(w_i) for w_i in
diff --git a/pypy/module/micronumpy/support.py 
b/pypy/module/micronumpy/support.py
--- a/pypy/module/micronumpy/support.py
+++ b/pypy/module/micronumpy/support.py
@@ -8,6 +8,17 @@
 from pypy.objspace.std.typeobject import W_TypeObject
 from pypy.objspace.std.objspace import StdObjSpace
 from pypy.module.micronumpy import constants as NPY
+from pypy.module.exceptions.interp_exceptions import _new_exception, 
W_UserWarning
+
+W_VisibleDeprecationWarning = _new_exception('VisibleDeprecationWarning', 
W_UserWarning,
+    """Visible deprecation warning.
+
+    By default, python will not show deprecation warnings, so this class
+    can be used when a very visible warning is helpful, for example because
+    the usage is most likely a user bug.
+
+    """)
+
 
 def issequence_w(space, w_obj):
     from pypy.module.micronumpy.base import W_NDimArray
diff --git a/pypy/module/micronumpy/test/test_deprecations.py 
b/pypy/module/micronumpy/test/test_deprecations.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/micronumpy/test/test_deprecations.py
@@ -0,0 +1,33 @@
+import py
+import sys
+
+from pypy.module.micronumpy.test.test_base import BaseNumpyAppTest
+
+
+class AppTestDeprecations(BaseNumpyAppTest):
+    spaceconfig = dict(usemodules=["micronumpy", "struct", "binascii"])
+
+    def test_getitem(self):
+        import numpy as np
+        import warnings, sys
+        warnings.simplefilter('error', np.VisibleDeprecationWarning)
+        try:
+            arr = np.ones((5, 4, 3))
+            index = np.array([True])
+            raises(np.VisibleDeprecationWarning, arr.__getitem__, index)
+
+            index = np.array([False] * 6)
+            raises(np.VisibleDeprecationWarning, arr.__getitem__, index)
+
+            index = np.zeros((4, 4), dtype=bool)
+            if '__pypy__' in sys.builtin_module_names:
+                # boolean indexing matches the dims in index
+                # to the first index.ndims in arr, not implemented in pypy yet
+                raises(IndexError, arr.__getitem__, index)
+                raises(TypeError, arr.__getitem__, (slice(None), index))
+            else:
+                raises(np.VisibleDeprecationWarning, arr.__getitem__, index)
+                raises(np.VisibleDeprecationWarning, arr.__getitem__, 
(slice(None), index))
+        finally:
+            warnings.simplefilter('default', np.VisibleDeprecationWarning)
+
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
@@ -345,13 +345,22 @@
 
     def test_can_subclass(self):
         import numpy as np
+        import sys
         class xyz(np.void):
             pass
         assert np.dtype(xyz).name == 'xyz'
         # another obscure API, used in numpy record.py
-        # it seems numpy throws away the subclass type and parses the spec
         a = np.dtype((xyz, [('x', 'int32'), ('y', 'float32')]))
-        assert repr(a) == "dtype([('x', '<i4'), ('y', '<f4')])"
+        assert "[('x', '<i4'), ('y', '<f4')]" in repr(a)
+        assert 'xyz' in repr(a)
+        data = [(1, 'a'), (2, 'bbb')]
+        b = np.dtype((xyz, [('a', int), ('b', object)]))
+        if '__pypy__' in sys.builtin_module_names:
+            raises(NotImplemented, np.array, data, dtype=b)
+        else:
+            arr = np.array(data, dtype=b)
+            assert arr[0][0] == 1
+            assert arr[0][1] == 'a'
 
     def test_index(self):
         import numpy as np
@@ -486,20 +495,11 @@
         class O(object):
             pass
         for o in [object, O]:
-            if self.ptr_size == 4:
-                assert np.dtype(o).str == '|O4'
-            elif self.ptr_size == 8:
-                assert np.dtype(o).str == '|O8'
-            else:
-                assert False,'self._ptr_size unknown'
+            assert np.dtype(o).str == '|O'
         # Issue gh-2798
-        if '__pypy__' in sys.builtin_module_names:
-            a = np.array(['a'], dtype="O")
-            raises(NotImplementedError, a.astype, ("O", [("name", "O")]))
-            skip("(base_dtype, new_dtype) dtype specification discouraged")
         a = np.array(['a'], dtype="O").astype(("O", [("name", "O")]))
         assert a[0] == 'a'
-        assert a == 'a'
+        assert a != 'a'
         assert a['name'].dtype == a.dtype
 
 class AppTestTypes(BaseAppTestDtypes):
@@ -1038,13 +1038,7 @@
             assert d.name == "string64"
             assert d.num == 18
         for i in [1, 2, 3]:
-            d = dtype('c%d' % i)
-            assert d.itemsize == 1
-            assert d.kind == 'S'
-            assert d.type is str_
-            assert d.name == 'string8'
-            assert d.num == 18
-            assert d.str == '|S1'
+            raises(TypeError, dtype, 'c%d' % i)
 
     def test_unicode_dtype(self):
         from numpy import dtype, unicode_
@@ -1068,6 +1062,7 @@
         assert d.char == 'c'
         assert d.kind == 'S'
         assert d.str == '|S1'
+        assert repr(d) == "dtype('S1')"
 
 class AppTestRecordDtypes(BaseNumpyAppTest):
     spaceconfig = dict(usemodules=["micronumpy", "struct", "binascii"])
diff --git a/pypy/module/micronumpy/test/test_ndarray.py 
b/pypy/module/micronumpy/test/test_ndarray.py
--- a/pypy/module/micronumpy/test/test_ndarray.py
+++ b/pypy/module/micronumpy/test/test_ndarray.py
@@ -269,7 +269,7 @@
         assert (y == x.T).all()
 
         exc = raises(ValueError, ndarray, [1,2,256]*10000)
-        assert exc.value[0] == 'sequence too large; must be smaller than 32'
+        assert exc.value[0] == 'sequence too large; cannot be greater than 32'
         exc = raises(ValueError, ndarray, [1,2,256]*10)
         assert exc.value[0] == 'array is too big.'
 
@@ -838,14 +838,19 @@
 
     def test_build_scalar(self):
         from numpy import dtype
+        import sys
         try:
             from numpy.core.multiarray import scalar
         except ImportError:
             from numpy import scalar
         exc = raises(TypeError, scalar, int, 2)
         assert exc.value[0] == 'argument 1 must be numpy.dtype, not type'
-        exc = raises(ValueError, scalar, dtype('void'), 'abc')
-        assert exc.value[0] == 'itemsize cannot be zero'
+        if '__pypy__' in sys.builtin_module_names:
+            exc = raises(TypeError, scalar, dtype('void'), 'abc')
+        else:
+            a = scalar(dtype('void'), 'abc')
+            exc = raises(TypeError, str, a)
+        assert exc.value[0] == 'Empty data-type'
         exc = raises(TypeError, scalar, dtype(float), 2.5)
         assert exc.value[0] == 'initializing object must be a string'
         exc = raises(ValueError, scalar, dtype(float), 'abc')
@@ -1081,14 +1086,6 @@
             for i in range(5):
                 assert a[i] == getattr(c[i], reg_op).__call__(d[i])
 
-    def test_inplace_cast(self):
-        import numpy as np
-        a = np.zeros(5, dtype=np.float64)
-        b = np.zeros(5, dtype=np.complex64)
-        a += b
-        assert a.sum() == 0
-        assert a.dtype is np.dtype(np.float64)
-
     def test_add_list(self):
         from numpy import array, ndarray
         a = array(range(5))
@@ -1965,7 +1962,7 @@
         assert len(a) == 6
         assert (a == [0,1,2,3,4,5]).all()
         assert a.dtype is dtype(int)
-        a = concatenate((a1, a2), axis=1)
+        a = concatenate((a1, a2), axis=0)
         assert (a == [0,1,2,3,4,5]).all()
         a = concatenate((a1, a2), axis=-1)
         assert (a == [0,1,2,3,4,5]).all()
@@ -2013,7 +2010,7 @@
 
         g1 = array([0,1,2])
         g2 = array([[3,4,5]])
-        exc = raises(ValueError, concatenate, (g1, g2), axis=2)
+        exc = raises(ValueError, concatenate, (g1, g2), axis=0)
         assert str(exc.value) == \
                 "all the input arrays must have same number of dimensions"
 
@@ -2129,16 +2126,16 @@
         assert exc.value.message == "'axis' entry 5 is out of bounds [-4, 4)"
         exc = raises(ValueError, a.squeeze, 0)
         assert exc.value.message == "cannot select an axis to squeeze out " \
-                                    "which has size greater than one"
+                                    "which has size not equal to one"
         exc = raises(ValueError, a.squeeze, (1, 1))
         assert exc.value.message == "duplicate value in 'axis'"
 
     def test_swapaxes(self):
         from numpy import array
         x = array([])
-        assert x.swapaxes(0, 2) is x
+        raises(ValueError, x.swapaxes,0, 2)
         x = array([[1, 2]])
-        assert x.swapaxes(0, 0) is x
+        assert x.swapaxes(0, 0) is not x
         exc = raises(ValueError, x.swapaxes, -3, 0)
         assert exc.value.message == "bad axis1 argument to swapaxes"
         exc = raises(ValueError, x.swapaxes, 0, 3)
@@ -2169,7 +2166,7 @@
         # test virtual
         assert ((x + x).swapaxes(0,1) == array([[[ 2,  4,  6], [14, 16, 18]],
                                          [[ 8, 10, 12], [20, 22, 24]]])).all()
-        assert array(1).swapaxes(10, 12) == 1
+        raises(ValueError, array(1).swapaxes, 10, 12)
 
     def test_filter_bug(self):
         from numpy import array
@@ -2238,6 +2235,9 @@
         c = array([True,False,True],bool)
         b = a[c]
         assert (a[c] == [[1, 2, 3], [7, 8, 9]]).all()
+        c = array([True])
+        b = a[c]
+        assert b.shape == (1, 3)
 
     def test_bool_array_index_setitem(self):
         from numpy import arange, array
@@ -2407,6 +2407,7 @@
 
     def test_data(self):
         from numpy import array
+        import sys
         a = array([1, 2, 3, 4], dtype='i4')
         assert a.data[0] == '\x01'
         assert a.data[1] == '\x00'
@@ -2415,7 +2416,8 @@
         assert a[1] == 0xff
         assert len(a.data) == 16
         assert type(a.data) is buffer
-        assert a[1:].data._pypy_raw_address() - a.data._pypy_raw_address() == 
a.strides[0]
+        if '__pypy__' in sys.builtin_module_names:
+            assert a[1:].data._pypy_raw_address() - a.data._pypy_raw_address() 
== a.strides[0]
 
     def test_explicit_dtype_conversion(self):
         from numpy import array
@@ -2502,7 +2504,7 @@
 
     def test_string_filling(self):
         import numpy
-        a = numpy.empty((10,10), dtype='c1')
+        a = numpy.empty((10,10), dtype='S1')
         a.fill(12)
         assert (a == '1').all()
 
@@ -3070,7 +3072,8 @@
         assert (b == zeros(10)).all()
 
     def test_array_interface(self):
-        from numpy import array, ones
+        from numpy import array
+        import numpy as np
         a = array(2.5)
         i = a.__array_interface__
         assert isinstance(i['data'][0], int)
@@ -3092,9 +3095,10 @@
         assert b_data + 3 * b.dtype.itemsize == c_data
 
         class Dummy(object):
-            def __init__(self, aif=None):
+            def __init__(self, aif=None, base=None):
                 if aif is not None:
                     self.__array_interface__ = aif
+                self.base = base
 
         a = array(Dummy())
         assert a.dtype == object
@@ -3122,12 +3126,22 @@
         assert b.dtype == 'uint8'
         assert b.shape == (50,)
 
-        a = ones((1,), dtype='float16')
+        a = np.ones((1,), dtype='float16')
         b = Dummy(a.__array_interface__)
         c = array(b)
         assert c.dtype == 'float16'
         assert (a == c).all()
 
+        t = np.dtype([("a", np.float64), ("b", np.float64)], align=True)
+        a = np.zeros(10, dtype=t)
+        a['a'] = range(10, 20)
+        a['b'] = range(20, 30)
+        interface = dict(a.__array_interface__)
+        array = np.array(Dummy(interface))
+        assert array.dtype.kind == 'V'
+        array.dtype = a.dtype
+        assert array[5]['b'] == 25
+
     def test_array_indexing_one_elem(self):
         from numpy import array, arange
         raises(IndexError, 'arange(3)[array([3.5])]')
@@ -3723,7 +3737,7 @@
         assert a[()]['y'] == 0
         assert a.shape == ()
         a = zeros(2, dtype=[('x', int), ('y', float)])
-        raises(IndexError, 'a[0]["xyz"]')
+        raises(ValueError, 'a[0]["xyz"]')
         assert a[0]['x'] == 0
         assert a[0]['y'] == 0
         exc = raises(ValueError, "a[0] = (1, 2, 3)")
@@ -3791,7 +3805,7 @@
         exc = raises(IndexError, "arr[3L]")
         assert exc.value.message == "too many indices for array"
         exc = raises(ValueError, "arr['xx'] = 2")
-        assert exc.value.message == "field named xx not found"
+        assert exc.value.message == "no field of name xx"
         assert arr['y'].dtype == a
         assert arr['y'].shape == ()
         assert arr['y'][()]['x'] == 0
@@ -3966,8 +3980,8 @@
             exc = raises(IndexError, "a[0][%d]" % v)
             assert exc.value.message == "invalid index (%d)" % \
                                         (v + 2 if v < 0 else v)
-        exc = raises(IndexError, "a[0]['z']")
-        assert exc.value.message == "invalid index"
+        exc = raises(ValueError, "a[0]['z']")
+        assert exc.value.message == "no field of name z"
         exc = raises(IndexError, "a[0][None]")
         assert exc.value.message == "invalid index"
 
@@ -4150,7 +4164,7 @@
         d = np.ones(3, dtype=[('a', 'i8'), ('b', 'i8')])
         e = np.ones(3, dtype=[('a', 'i8'), ('b', 'i8'), ('c', 'i8')])
         exc = raises(TypeError, abs, a)
-        assert exc.value[0] == 'Not implemented for this type'
+        assert exc.value[0].startswith("ufunc 'absolute' did not contain a 
loop")
         assert (a == a).all()
         assert not (a != a).any()
         assert (a == b).all()
diff --git a/pypy/module/micronumpy/test/test_scalar.py 
b/pypy/module/micronumpy/test/test_scalar.py
--- a/pypy/module/micronumpy/test/test_scalar.py
+++ b/pypy/module/micronumpy/test/test_scalar.py
@@ -142,7 +142,7 @@
         assert f.round() == 13.
         assert f.round(decimals=-1) == 10.
         assert f.round(decimals=1) == 13.4
-        assert b.round(decimals=5) is b
+        raises(TypeError, b.round, decimals=5)
         assert f.round(decimals=1, out=None) == 13.4
         assert b.round() == 1.0
 
@@ -404,8 +404,8 @@
         def _do_test(np_type, orig_val, exp_val):
             val = np_type(orig_val)
             assert val == orig_val
-            assert val.swapaxes(10, 20) == exp_val
-            assert type(val.swapaxes(0, 1)) is np_type
+            raises(ValueError, val.swapaxes, 10, 20)
+            raises(ValueError, val.swapaxes, 0, 1)
             raises(TypeError, val.swapaxes, 0, ())
 
         for t in int8, int16, int32, int64:
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
@@ -123,7 +123,7 @@
         res = int_func12(a)
         assert len(res) == 2
         assert isinstance(res, tuple)
-        assert (res[0] == a).all()
+        assert all([r is None for r in res[0]]) # ??? no warning or error, 
just a fail?
         res = sumdiff(2 * a, a)
         assert (res[0] == 3 * a).all()
         assert (res[1] == a).all()
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
@@ -450,10 +450,12 @@
 
     @specialize.argtype(1)
     def round(self, v, decimals=0):
-        if decimals != 0:
-            # numpy 1.9.0 compatible
-            return v
-        return Float64(self.space).box(self.unbox(v))
+        if decimals == 0:
+            return Float64(self.space).box(self.unbox(v))
+        # numpy 1.10 compatibility
+        raise oefmt(self.space.w_TypeError, "ufunc casting failure")
+            
+            
 
 class Integer(Primitive):
     _mixin_ = True
@@ -2412,18 +2414,20 @@
                 ofs += size
 
     def coerce(self, space, dtype, w_items):
+        if dtype.is_record():
+            # the dtype is a union of a void and a record,
+            return record_coerce(self, space, dtype, w_items)
         arr = VoidBoxStorage(dtype.elsize, dtype)
         self._coerce(space, arr, 0, dtype, w_items, dtype.shape)
         return boxes.W_VoidBox(arr, 0, dtype)
 
     @jit.unroll_safe
     def store(self, arr, i, offset, box, native):
-        assert i == 0
         assert isinstance(box, boxes.W_VoidBox)
         assert box.dtype is box.arr.dtype
         with arr as arr_storage, box.arr as box_storage:
             for k in range(box.arr.dtype.elsize):
-                arr_storage[k + offset] = box_storage[k + box.ofs]
+                arr_storage[i + k + offset] = box_storage[k + box.ofs]
 
     def readarray(self, arr, i, offset, dtype=None):
         from pypy.module.micronumpy.base import W_NDimArray
@@ -2472,17 +2476,7 @@
 class CharType(StringType):
     char = NPY.CHARLTR
 
-class RecordType(FlexibleType):
-    T = lltype.Char
-    num = NPY.VOID
-    kind = NPY.VOIDLTR
-    char = NPY.VOIDLTR
-
-    def read(self, arr, i, offset, dtype):
-        return boxes.W_VoidBox(arr, i + offset, dtype)
-
-    @jit.unroll_safe
-    def coerce(self, space, dtype, w_item):
+def record_coerce(typ, space, dtype, w_item):
         from pypy.module.micronumpy.base import W_NDimArray
         if isinstance(w_item, boxes.W_VoidBox):
             if dtype == w_item.dtype:
@@ -2520,6 +2514,19 @@
             subdtype.store(arr, 0, ofs, w_box)
         return boxes.W_VoidBox(arr, 0, dtype)
 
+class RecordType(FlexibleType):
+    T = lltype.Char
+    num = NPY.VOID
+    kind = NPY.VOIDLTR
+    char = NPY.VOIDLTR
+
+    def read(self, arr, i, offset, dtype):
+        return boxes.W_VoidBox(arr, i + offset, dtype)
+
+    @jit.unroll_safe
+    def coerce(self, space, dtype, w_item):
+        return record_coerce(self, space, dtype, w_item)
+
     def runpack_str(self, space, s, native):
         raise oefmt(space.w_NotImplementedError,
                     "fromstring not implemented for record types")
diff --git a/pypy/module/sys/version.py b/pypy/module/sys/version.py
--- a/pypy/module/sys/version.py
+++ b/pypy/module/sys/version.py
@@ -10,7 +10,7 @@
 #XXX # sync CPYTHON_VERSION with patchlevel.h, package.py
 CPYTHON_API_VERSION        = 1013   #XXX # sync with include/modsupport.h
 
-PYPY_VERSION               = (4, 0, 1, "alpha", 0)    #XXX # sync patchlevel.h
+PYPY_VERSION               = (4, 1, 0, "alpha", 0)    #XXX # sync patchlevel.h
 
 
 import pypy
diff --git a/pypy/module/test_lib_pypy/cffi_tests/cffi0/backend_tests.py 
b/pypy/module/test_lib_pypy/cffi_tests/cffi0/backend_tests.py
--- a/pypy/module/test_lib_pypy/cffi_tests/cffi0/backend_tests.py
+++ b/pypy/module/test_lib_pypy/cffi_tests/cffi0/backend_tests.py
@@ -1336,7 +1336,8 @@
         # these depend on user-defined data, so should not be shared
         assert ffi1.typeof("struct foo") is not ffi2.typeof("struct foo")
         assert ffi1.typeof("union foo *") is not ffi2.typeof("union foo*")
-        assert ffi1.typeof("enum foo") is not ffi2.typeof("enum foo")
+        # the following test is an opaque enum, which we no longer support
+        #assert ffi1.typeof("enum foo") is not ffi2.typeof("enum foo")
         # sanity check: twice 'ffi1'
         assert ffi1.typeof("struct foo*") is ffi1.typeof("struct foo *")
 
@@ -1348,6 +1349,17 @@
         assert ffi.getctype("pe") == 'e *'
         assert ffi.getctype("e1*") == 'e1 *'
 
+    def test_opaque_enum(self):
+        ffi = FFI(backend=self.Backend())
+        ffi.cdef("enum foo;")
+        from cffi import __version_info__
+        if __version_info__ < (1, 4):
+            py.test.skip("re-enable me in version 1.4")
+        e = py.test.raises(CDefError, ffi.cast, "enum foo", -1)
+        assert str(e.value) == (
+            "'enum foo' has no values explicitly defined: refusing to guess "
+            "which integer type it is meant to be (unsigned/signed, int/long)")
+
     def test_new_ctype(self):
         ffi = FFI(backend=self.Backend())
         p = ffi.new("int *")
diff --git a/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_commontypes.py 
b/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_commontypes.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/test_lib_pypy/cffi_tests/cffi1/test_commontypes.py
@@ -0,0 +1,35 @@
+# Generated by pypy/tool/import_cffi.py
+import py, os, cffi, re
+import _cffi_backend
+
+
+def getlines():
+    try:
+        f = open(os.path.join(os.path.dirname(cffi.__file__),
+                              '..', 'c', 'commontypes.c'))
+    except IOError:
+        py.test.skip("cannot find ../c/commontypes.c")
+    lines = [line for line in f.readlines() if line.strip().startswith('EQ(')]
+    f.close()
+    return lines
+
+def test_alphabetical_order():
+    lines = getlines()
+    assert lines == sorted(lines)
+
+def test_dependencies():
+    r = re.compile(r'EQ[(]"([^"]+)",(?:\s*"([A-Z0-9_]+)\s*[*]*"[)])?')
+    lines = getlines()
+    d = {}
+    for line in lines:
+        match = r.search(line)
+        if match is not None:
+            d[match.group(1)] = match.group(2)
+    for value in d.values():
+        if value:
+            assert value in d
+
+def test_get_common_types():
+    d = {}
+    _cffi_backend._get_common_types(d)
+    assert d["bool"] == "_Bool"
diff --git a/pypy/module/test_lib_pypy/test_greenlet_tracing.py 
b/pypy/module/test_lib_pypy/test_greenlet_tracing.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/test_lib_pypy/test_greenlet_tracing.py
@@ -0,0 +1,53 @@
+import py
+try:
+    from lib_pypy import greenlet
+except ImportError, e:
+    py.test.skip(e)
+
+class SomeError(Exception):
+    pass
+
+class TestTracing:
+    def test_greenlet_tracing(self):
+        main = greenlet.getcurrent()
+        actions = []
+        def trace(*args):
+            actions.append(args)
+        def dummy():
+            pass
+        def dummyexc():
+            raise SomeError()
+        oldtrace = greenlet.settrace(trace)
+        try:
+            g1 = greenlet.greenlet(dummy)
+            g1.switch()
+            g2 = greenlet.greenlet(dummyexc)
+            py.test.raises(SomeError, g2.switch)
+        finally:
+            greenlet.settrace(oldtrace)
+        assert actions == [
+            ('switch', (main, g1)),
+            ('switch', (g1, main)),
+            ('switch', (main, g2)),
+            ('throw', (g2, main)),
+        ]
+
+    def test_exception_disables_tracing(self):
+        main = greenlet.getcurrent()
+        actions = []
+        def trace(*args):
+            actions.append(args)
+            raise SomeError()
+        def dummy():
+            main.switch()
+        g = greenlet.greenlet(dummy)
+        g.switch()
+        oldtrace = greenlet.settrace(trace)
+        try:
+            py.test.raises(SomeError, g.switch)
+            assert greenlet.gettrace() is None
+        finally:
+            greenlet.settrace(oldtrace)
+        assert actions == [
+            ('switch', (main, g)),
+        ]
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
@@ -1231,6 +1231,21 @@
     def setitem(self, index, char):
         self.data[index] = char
 
+    def getslice(self, start, stop, step, size):
+        if size == 0:
+            return ""
+        if step == 1:
+            assert 0 <= start <= stop
+            if start == 0 and stop == len(self.data):
+                return "".join(self.data)
+            return "".join(self.data[start:stop])
+        return Buffer.getslice(self, start, stop, step, size)
+
+    def setslice(self, start, string):
+        # No bounds checks.
+        for i in range(len(string)):
+            self.data[start + i] = string[i]
+
 
 @specialize.argtype(1)
 def _memcmp(selfvalue, buffer, length):
diff --git a/pypy/objspace/std/test/test_tupleobject.py 
b/pypy/objspace/std/test/test_tupleobject.py
--- a/pypy/objspace/std/test/test_tupleobject.py
+++ b/pypy/objspace/std/test/test_tupleobject.py
@@ -413,8 +413,9 @@
             from __pypy__ import specialized_zip_2_lists
         except ImportError:
             specialized_zip_2_lists = zip
-        raises(TypeError, specialized_zip_2_lists, [], ())
-        raises(TypeError, specialized_zip_2_lists, (), [])
+        else:
+            raises(TypeError, specialized_zip_2_lists, [], ())
+            raises(TypeError, specialized_zip_2_lists, (), [])
         assert specialized_zip_2_lists([], []) == [
             ]
         assert specialized_zip_2_lists([2, 3], []) == [
diff --git a/pypy/tool/release/repackage.sh b/pypy/tool/release/repackage.sh
--- a/pypy/tool/release/repackage.sh
+++ b/pypy/tool/release/repackage.sh
@@ -1,10 +1,11 @@
 # Edit these appropriately before running this script
-maj=2
-min=6
+maj=4
+min=0
 rev=1
 # This script will download latest builds from the buildmaster, rename the top
 # level directory, and repackage ready to be uploaded to bitbucket. It will 
also
 # download source, assuming a tag for the release already exists, and 
repackage them.
+# The script should be run in an empty directory, i.e. /tmp/release_xxx
 
 for plat in linux linux64 linux-armhf-raspbian linux-armhf-raring linux-armel 
osx64 freebsd64
   do
diff --git a/rpython/jit/backend/arm/opassembler.py 
b/rpython/jit/backend/arm/opassembler.py
--- a/rpython/jit/backend/arm/opassembler.py
+++ b/rpython/jit/backend/arm/opassembler.py
@@ -1169,7 +1169,6 @@
         self._emit_call(op, arglocs, is_call_release_gil=True)
         return fcond
     emit_op_call_release_gil_i = _genop_call_release_gil
-    emit_op_call_release_gil_r = _genop_call_release_gil
     emit_op_call_release_gil_f = _genop_call_release_gil
     emit_op_call_release_gil_n = _genop_call_release_gil
 
diff --git a/rpython/jit/backend/arm/regalloc.py 
b/rpython/jit/backend/arm/regalloc.py
--- a/rpython/jit/backend/arm/regalloc.py
+++ b/rpython/jit/backend/arm/regalloc.py
@@ -1234,7 +1234,6 @@
         return self._prepare_call(op, save_all_regs=True, first_arg_index=2)
 
     prepare_op_call_release_gil_i = _prepare_op_call_release_gil
-    prepare_op_call_release_gil_r = _prepare_op_call_release_gil
     prepare_op_call_release_gil_f = _prepare_op_call_release_gil
     prepare_op_call_release_gil_n = _prepare_op_call_release_gil
 
diff --git a/rpython/jit/backend/llgraph/runner.py 
b/rpython/jit/backend/llgraph/runner.py
--- a/rpython/jit/backend/llgraph/runner.py
+++ b/rpython/jit/backend/llgraph/runner.py
@@ -1365,7 +1365,6 @@
 
     execute_call_release_gil_n = _execute_call_release_gil
     execute_call_release_gil_i = _execute_call_release_gil
-    execute_call_release_gil_r = _execute_call_release_gil
     execute_call_release_gil_f = _execute_call_release_gil
 
     def _new_execute_call_assembler(def_val):
diff --git a/rpython/jit/backend/llsupport/rewrite.py 
b/rpython/jit/backend/llsupport/rewrite.py
--- a/rpython/jit/backend/llsupport/rewrite.py
+++ b/rpython/jit/backend/llsupport/rewrite.py
@@ -120,11 +120,14 @@
         # this case means between CALLs or unknown-size mallocs.
         #
         operations = self.remove_bridge_exception(operations)
+        self._changed_op = None
         for i in range(len(operations)):
             op = operations[i]
             assert op.get_forwarded() is None
             if op.getopnum() == rop.DEBUG_MERGE_POINT:
                 continue
+            if op is self._changed_op:
+                op = self._changed_op_to
             # ---------- GETFIELD_GC ----------
             if op.getopnum() in (rop.GETFIELD_GC_I, rop.GETFIELD_GC_F,
                                  rop.GETFIELD_GC_R):
@@ -211,7 +214,10 @@
         self.emit_op(op1)
         lst = op.getfailargs()[:]
         lst[i] = op1
-        op.setfailargs(lst)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to