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

Reply via email to