Author: Antonio Cuni <anto.c...@gmail.com> Branch: faster-rstruct Changeset: r80815:a256226d8bce Date: 2015-11-21 15:48 +0100 http://bitbucket.org/pypy/pypy/changeset/a256226d8bce/
Log: hg merge default-at-the-latest-green-revision 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 t...@eistee.fritz.box 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/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 t...@eistee.fritz.box 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 @@ -2,34 +2,6 @@ What's new in PyPy 4.0.+ ========================= -.. 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 - -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/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/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/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 @@ -2238,6 +2238,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 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/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/rpython/rtyper/lltypesystem/lltype.py b/rpython/rtyper/lltypesystem/lltype.py --- a/rpython/rtyper/lltypesystem/lltype.py +++ b/rpython/rtyper/lltypesystem/lltype.py @@ -1469,7 +1469,10 @@ result = intmask(obj._getid()) # assume that id() returns an addressish value which is # not zero and aligned to at least a multiple of 4 - assert result != 0 and (result & 3) == 0 + # (at least for GC pointers; we can't really assume anything + # for raw addresses) + if self._T._gckind == 'gc': + assert result != 0 and (result & 3) == 0 return result def _cast_to_adr(self): diff --git a/rpython/translator/c/src/debug_print.c b/rpython/translator/c/src/debug_print.c --- a/rpython/translator/c/src/debug_print.c +++ b/rpython/translator/c/src/debug_print.c @@ -23,13 +23,14 @@ static char *debug_start_colors_2 = ""; static char *debug_stop_colors = ""; static char *debug_prefix = NULL; -static char *debug_filename = NULL; -static char *debug_filename_with_fork = NULL; -static void _pypy_debug_open(char *filename) +static void pypy_debug_open(void) { + char *filename = getenv("PYPYLOG"); + if (filename && filename[0]) { + char *newfilename = NULL, *escape; char *colon = strchr(filename, ':'); if (filename[0] == '+') { @@ -51,11 +52,38 @@ debug_prefix[n] = '\0'; filename = colon + 1; } + escape = strstr(filename, "%d"); + if (escape) /* a "%d" in the filename is replaced with the pid */ + { + newfilename = malloc(strlen(filename) + 32); + if (newfilename != NULL) + { + char *p = newfilename; + memcpy(p, filename, escape - filename); + p += escape - filename; + sprintf(p, "%ld", (long)getpid()); + strcat(p, escape + 2); + filename = newfilename; + } + } if (strcmp(filename, "-") != 0) { - debug_filename = strdup(filename); pypy_debug_file = fopen(filename, "w"); } + + if (escape) + { + free(newfilename); /* if not null */ + /* the env var is kept and passed to subprocesses */ + } + else + { +#ifndef _WIN32 + unsetenv("PYPYLOG"); +#else + putenv("PYPYLOG="); +#endif + } } if (!pypy_debug_file) { @@ -67,27 +95,21 @@ debug_stop_colors = "\033[0m"; } } - if (filename) -#ifndef _WIN32 - unsetenv("PYPYLOG"); /* don't pass it to subprocesses */ -#else - putenv("PYPYLOG="); /* don't pass it to subprocesses */ -#endif debug_ready = 1; } -static void pypy_debug_open(void) -{ - _pypy_debug_open(getenv("PYPYLOG")); -} - long pypy_debug_offset(void) { if (!debug_ready) return -1; + /* The following fflush() makes sure everything is written now, which + is just before a fork(). So we can fork() and close the file in + the subprocess without ending up with the content of the buffer + written twice. */ + fflush(pypy_debug_file); + // note that we deliberately ignore errno, since -1 is fine // in case this is not a real file - fflush(pypy_debug_file); return ftell(pypy_debug_file); } @@ -99,21 +121,20 @@ void pypy_debug_forked(long original_offset) { - if (debug_filename != NULL) + /* 'original_offset' ignored. It used to be that the forked log + files started with this offset printed out, so that we can + rebuild the tree structure. That's overkill... */ + (void)original_offset; + + if (pypy_debug_file) { - char *filename = malloc(strlen(debug_filename) + 32); - fclose(pypy_debug_file); + if (pypy_debug_file != stderr) + fclose(pypy_debug_file); pypy_debug_file = NULL; - if (filename == NULL) - return; /* bah */ - sprintf(filename, "%s.fork%ld", debug_filename, (long)getpid()); - pypy_debug_file = fopen(filename, "w"); - if (pypy_debug_file) - fprintf(pypy_debug_file, "FORKED: %ld %s\n", original_offset, - debug_filename_with_fork ? debug_filename_with_fork - : debug_filename); - free(debug_filename_with_fork); - debug_filename_with_fork = filename; + /* if PYPYLOG was set to a name with "%d" in it, it is still + alive, and will be reopened with the new subprocess' pid as + soon as it logs anything */ + debug_ready = 0; } } diff --git a/rpython/translator/c/src/debug_print.h b/rpython/translator/c/src/debug_print.h --- a/rpython/translator/c/src/debug_print.h +++ b/rpython/translator/c/src/debug_print.h @@ -21,6 +21,10 @@ subsections. Note that 'fname' can be '-' to send the logging data to stderr. + If 'fname' includes the substring '%d' it is replaced with the + current process id and you get the log for all subprocesses (and + forks) in different files. If 'fname' does not include '%d', it is + removed from the environment and not passed to subprocesses. */ /* macros used by the generated code */ diff --git a/rpython/translator/c/test/test_standalone.py b/rpython/translator/c/test/test_standalone.py --- a/rpython/translator/c/test/test_standalone.py +++ b/rpython/translator/c/test/test_standalone.py @@ -531,6 +531,7 @@ py.test.skip("requires fork()") def entry_point(argv): + print "parentpid =", os.getpid() debug_start("foo") debug_print("test line") childpid = os.fork() @@ -543,40 +544,46 @@ t, cbuilder = self.compile(entry_point) path = udir.join('test_debug_print_fork.log') out, err = cbuilder.cmdexec("", err=True, - env={'PYPYLOG': ':%s' % path}) + env={'PYPYLOG': ':%s.%%d' % path}) assert not err + import time + time.sleep(0.5) # time for the forked children to finish # - f = open(str(path), 'r') + lines = out.splitlines() + assert lines[-1].startswith('parentpid = ') + parentpid = int(lines[-1][12:]) + # + f = open('%s.%d' % (path, parentpid), 'r') lines = f.readlines() f.close() assert '{foo' in lines[0] assert lines[1] == "test line\n" - offset1 = len(lines[0]) + len(lines[1]) + #offset1 = len(lines[0]) + len(lines[1]) assert lines[2].startswith('childpid = ') childpid = int(lines[2][11:]) assert childpid != 0 assert 'foo}' in lines[3] assert len(lines) == 4 # - f = open('%s.fork%d' % (path, childpid), 'r') + f = open('%s.%d' % (path, childpid), 'r') lines = f.readlines() f.close() - assert lines[0] == 'FORKED: %d %s\n' % (offset1, path) - assert lines[1] == 'childpid = 0\n' - offset2 = len(lines[0]) + len(lines[1]) - assert lines[2].startswith('childpid2 = ') - childpid2 = int(lines[2][11:]) + #assert lines[0] == 'FORKED: %d %s\n' % (offset1, path) + assert lines[0] == 'childpid = 0\n' + #offset2 = len(lines[0]) + len(lines[1]) + assert lines[1].startswith('childpid2 = ') + childpid2 = int(lines[1][11:]) assert childpid2 != 0 - assert 'foo}' in lines[3] - assert len(lines) == 4 + assert 'foo}' in lines[2] + assert len(lines) == 3 # - f = open('%s.fork%d' % (path, childpid2), 'r') + f = open('%s.%d' % (path, childpid2), 'r') lines = f.readlines() f.close() - assert lines[0] == 'FORKED: %d %s.fork%d\n' % (offset2, path, childpid) - assert lines[1] == 'childpid2 = 0\n' - assert 'foo}' in lines[2] - assert len(lines) == 3 + #assert lines[0] == 'FORKED: %d %s.fork%d\n' % (offset2, path, childpid) + assert lines[0] == 'childpid2 = 0\n' + assert 'foo}' in lines[1] + assert len(lines) == 2 def test_debug_flush_at_exit(self): def entry_point(argv): diff --git a/rpython/translator/driver.py b/rpython/translator/driver.py --- a/rpython/translator/driver.py +++ b/rpython/translator/driver.py @@ -502,7 +502,6 @@ shutil.copyfile(str(name), str(newname.new(ext=ext))) self.log.info("copied: %s" % (newname,)) self.c_entryp = newexename - self.log.info('usession directory: %s' % (udir,)) self.log.info("created: %s" % (self.c_entryp,)) @taskdef(['source_c'], "Compiling c source") @@ -548,7 +547,9 @@ goals = [goals] goals.extend(self.extra_goals) goals = self.backend_select_goals(goals) - return self._execute(goals, task_skip = self._maybe_skip()) + result = self._execute(goals, task_skip = self._maybe_skip()) + self.log.info('usession directory: %s' % (udir,)) + return result @staticmethod def from_targetspec(targetspec_dic, config=None, args=None, diff --git a/rpython/translator/platform/posix.py b/rpython/translator/platform/posix.py --- a/rpython/translator/platform/posix.py +++ b/rpython/translator/platform/posix.py @@ -138,6 +138,13 @@ rel = lpath.relto(rpypath) if rel: return os.path.join('$(RPYDIR)', rel) + # Hack: also relativize from the path '$RPYDIR/..'. + # Otherwise, when translating pypy, we get the paths in + # pypy/module/* that are kept as absolute, which makes the + # whole purpose of $RPYDIR rather pointless. + rel = lpath.relto(rpypath.join('..')) + if rel: + return os.path.join('$(RPYDIR)', '..', rel) m_dir = m.makefile_dir if m_dir == lpath: return '.' _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit