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ä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
