Author: Wim Lavrijsen <wlavrij...@lbl.gov> Branch: cppyy-packaging Changeset: r94432:4f2df82b0b9f Date: 2018-04-23 15:52 -0700 http://bitbucket.org/pypy/pypy/changeset/4f2df82b0b9f/
Log: merge default into branch diff --git a/pypy/doc/release-v6.0.0.rst b/pypy/doc/release-v6.0.0.rst --- a/pypy/doc/release-v6.0.0.rst +++ b/pypy/doc/release-v6.0.0.rst @@ -18,6 +18,8 @@ getting started writing code. We have improved our parser to emit more friendly `syntax errors`_, making PyPy not only faster but more friendly. +The GC now has `hooks`_ to gain more insights into its performance + The Windows PyPy3.5 release is still considered beta-quality. There are open issues with unicode handling especially around system calls and c-extensions. @@ -53,6 +55,7 @@ .. _`blog post`: https://morepypy.blogspot.it/2017/10/cape-of-good-hope-for-pypy-hello-from.html .. _pygobject: https://lazka.github.io/posts/2018-04_pypy-pygobject/index.html .. _`syntax errors`: https://morepypy.blogspot.com/2018/04/improving-syntaxerror-in-pypy.html +.. _`hooks`: gc_info.html#gc-hooks What is PyPy? ============= @@ -101,8 +104,9 @@ * Added missing attributes to C-API ``instancemethod`` on pypy3 * Store error state in thread-local storage for C-API. * Fix JIT bugs exposed in the sre module -* Improve speed of Python parser, improve ParseError messages slightly +* Improve speed of Python parser, improve ParseError messages and SyntaxError * Handle JIT hooks more efficiently +* Fix a rare GC bug exposed by intensive use of cpyext `Buffer` s We also refactored many parts of the JIT bridge optimizations, as well as cpyext internals, and together with new contributors fixed issues, added new 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 @@ -3,18 +3,7 @@ ========================== .. this is a revision shortly after release-pypy-6.0.0 -.. startrev: f22145c34985 +.. startrev: ad79cc0ce9a8 -.. branch: issue2752 -Fix a rare GC bug that was introduced more than one year ago, but was -not diagnosed before issue #2752. - -.. branch: gc-hooks - -Introduce GC hooks, as documented in doc/gc_info.rst - -.. branch: gc-hook-better-timestamp - -Improve GC hooks diff --git a/pypy/doc/whatsnew-pypy2-6.0.0.rst b/pypy/doc/whatsnew-pypy2-6.0.0.rst --- a/pypy/doc/whatsnew-pypy2-6.0.0.rst +++ b/pypy/doc/whatsnew-pypy2-6.0.0.rst @@ -109,3 +109,16 @@ Improve line offsets that are reported by SyntaxError. Improve error messages for a few situations, including mismatched parenthesis. + +.. branch: issue2752 + +Fix a rare GC bug that was introduced more than one year ago, but was +not diagnosed before issue #2752. + +.. branch: gc-hooks + +Introduce GC hooks, as documented in doc/gc_info.rst + +.. branch: gc-hook-better-timestamp + +Improve GC hooksd diff --git a/pypy/interpreter/executioncontext.py b/pypy/interpreter/executioncontext.py --- a/pypy/interpreter/executioncontext.py +++ b/pypy/interpreter/executioncontext.py @@ -491,11 +491,17 @@ # 'action.fire()' happens to be called any time before # the corresponding perform(), the fire() has no # effect---which is the effect we want, because - # perform() will be called anyway. + # perform() will be called anyway. All such pending + # actions with _fired == True are still inside the old + # chained list. As soon as we reset _fired to False, + # we also reset _next to None and we are ready for + # another fire(). while action is not None: + next_action = action._next + action._next = None action._fired = False action.perform(ec, frame) - action._next, action = None, action._next + action = next_action self.action_dispatcher = action_dispatcher diff --git a/pypy/interpreter/test/test_executioncontext.py b/pypy/interpreter/test/test_executioncontext.py --- a/pypy/interpreter/test/test_executioncontext.py +++ b/pypy/interpreter/test/test_executioncontext.py @@ -67,6 +67,47 @@ """) assert events == ['one'] + def test_fire_inside_perform(self): + # test what happens if we call AsyncAction.fire() while we are in the + # middle of an AsyncAction.perform(). In particular, this happens when + # PyObjectDeallocAction.fire() is called by rawrefcount: see issue + # 2805 + events = [] + + class Action1(executioncontext.AsyncAction): + _count = 0 + + def perform(self, ec, frame): + events.append('one') + if self._count == 0: + # a1 is no longer in the queue, so it will be enqueued + a1.fire() + # + # a2 is still in the queue, so the fire() is ignored and + # it's performed in its normal order, i.e. BEFORE a3 + a2.fire() + self._count += 1 + + class Action2(executioncontext.AsyncAction): + def perform(self, ec, frame): + events.append('two') + + class Action3(executioncontext.AsyncAction): + def perform(self, ec, frame): + events.append('three') + + space = self.space + a1 = Action1(space) + a2 = Action2(space) + a3 = Action3(space) + a1.fire() + a2.fire() + a3.fire() + space.appexec([], """(): + pass + """) + assert events == ['one', 'two', 'three', 'one'] + def test_periodic_action(self): from pypy.interpreter.executioncontext import ActionFlag diff --git a/pypy/module/cpyext/test/test_arraymodule.py b/pypy/module/cpyext/test/test_arraymodule.py --- a/pypy/module/cpyext/test/test_arraymodule.py +++ b/pypy/module/cpyext/test/test_arraymodule.py @@ -194,7 +194,4 @@ self.attrib = True import gc module.subclass_with_attribute(Sub, "addattrib", "attrib", gc.collect) - if self.runappdirect: - assert Sub.__module__ == 'pypy.module.cpyext.test.test_arraymodule' - assert str(Sub) == "<class 'pypy.module.cpyext.test.test_arraymodule.Sub'>" - + assert Sub.__module__ == __name__ diff --git a/pypy/module/cpyext/test/test_datetime.py b/pypy/module/cpyext/test/test_datetime.py --- a/pypy/module/cpyext/test/test_datetime.py +++ b/pypy/module/cpyext/test/test_datetime.py @@ -1,3 +1,5 @@ +import pytest + from pypy.module.cpyext.test.test_cpyext import AppTestCpythonExtensionBase from pypy.module.cpyext.test.test_api import BaseApiTest from pypy.module.cpyext.cdatetime import * @@ -82,6 +84,14 @@ date = datetime.datetime.fromtimestamp(0) assert space.unwrap(space.str(w_date)) == str(date) + @pytest.mark.parametrize('name', ['Time', 'DateTime', 'Date', 'Delta']) + def test_basicsize(self, space, name): + datetime = _PyDateTime_Import(space) + py_size = getattr(datetime, "c_%sType" % name).c_tp_basicsize + c_size = rffi.sizeof(cts.gettype("PyDateTime_%s" % name)) + assert py_size == c_size + + class AppTestDatetime(AppTestCpythonExtensionBase): def test_CAPI(self): module = self.import_extension('foo', [ @@ -271,9 +281,9 @@ 6, 6, 6, 6, args, PyDateTimeAPI->TimeType); """), ("datetime_with_tzinfo", "METH_O", - """ + """ PyObject * obj; - int tzrefcnt = args->ob_refcnt; + int tzrefcnt = args->ob_refcnt; PyDateTime_IMPORT; obj = PyDateTimeAPI->DateTime_FromDateAndTime( 2000, 6, 6, 6, 6, 6, 6, args, @@ -291,7 +301,7 @@ return NULL; } return obj; - + """), ], prologue='#include "datetime.h"\n') from datetime import tzinfo, datetime, timedelta, time @@ -339,4 +349,4 @@ assert module.checks(o) == (True,) * 3 + (False,) * 7 # isinstance(datetime, date) o = tzinfo() assert module.checks(o) == (False,) * 8 + (True,) * 2 - + diff --git a/pypy/module/cpyext/test/test_unicodeobject.py b/pypy/module/cpyext/test/test_unicodeobject.py --- a/pypy/module/cpyext/test/test_unicodeobject.py +++ b/pypy/module/cpyext/test/test_unicodeobject.py @@ -26,11 +26,8 @@ if(PyUnicode_GetSize(s) != 11) { result = -PyUnicode_GetSize(s); } -#ifdef PYPY_VERSION - // Slightly silly test that tp_basicsize is reasonable. - if(s->ob_type->tp_basicsize != sizeof(void*)*7) + if(s->ob_type->tp_basicsize != sizeof(PyUnicodeObject)) result = s->ob_type->tp_basicsize; -#endif // PYPY_VERSION Py_DECREF(s); return PyLong_FromLong(result); """), diff --git a/pypy/objspace/std/listobject.py b/pypy/objspace/std/listobject.py --- a/pypy/objspace/std/listobject.py +++ b/pypy/objspace/std/listobject.py @@ -991,6 +991,14 @@ def setslice(self, w_list, start, step, slicelength, w_other): strategy = w_other.strategy + if step != 1: + len2 = strategy.length(w_other) + if len2 == 0: + return + else: + raise oefmt(self.space.w_ValueError, + "attempt to assign sequence of size %d to extended " + "slice of size %d", len2, 0) storage = strategy.getstorage_copy(w_other) w_list.strategy = strategy w_list.lstorage = storage diff --git a/pypy/objspace/std/test/test_listobject.py b/pypy/objspace/std/test/test_listobject.py --- a/pypy/objspace/std/test/test_listobject.py +++ b/pypy/objspace/std/test/test_listobject.py @@ -1080,6 +1080,15 @@ l[::3] = ('a', 'b') assert l == ['a', 1.1, 2.2, 'b', 4.4, 5.5] + l_int = [5]; l_int.pop() # IntListStrategy + l_empty = [] # EmptyListStrategy + raises(ValueError, "l_int[::-1] = [42]") + raises(ValueError, "l_int[::7] = [42]") + raises(ValueError, "l_empty[::-1] = [42]") + raises(ValueError, "l_empty[::7] = [42]") + l_int[::1] = [42]; assert l_int == [42] + l_empty[::1] = [42]; assert l_empty == [42] + def test_setslice_with_self(self): l = [1,2,3,4] l[:] = l _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit