[pypy-commit] pypy cpyext-obj-stealing: rework test as per irc discussion, passes with -A and untranslated

mattip pypy.commits at gmail.com
Fri Apr 28 09:14:00 EDT 2017


Author: Matti Picus <matti.picus at gmail.com>
Branch: cpyext-obj-stealing
Changeset: r91143:2bf4323abb8e
Date: 2017-04-28 13:38 +0300
http://bitbucket.org/pypy/pypy/changeset/2bf4323abb8e/

Log:	rework test as per irc discussion, passes with -A and untranslated

diff --git a/pypy/module/cpyext/test/test_listobject.py b/pypy/module/cpyext/test/test_listobject.py
--- a/pypy/module/cpyext/test/test_listobject.py
+++ b/pypy/module/cpyext/test/test_listobject.py
@@ -194,35 +194,60 @@
              """)])
         assert module.test_get_item() == 0
 
-    def test_set_item_macro(self):
+    def test_item_refcounts(self):
         """PyList_SET_ITEM leaks a reference to the target."""
         module = self.import_extension('foo', [
-             ("test_refcount_diff_after_setitem", "METH_NOARGS",
+             ("test_refcount_diff", "METH_NOARGS",
              """
-                PyObject* o = PyList_New(0);
-                PyObject* o2 = PyLong_FromLong(0);
-                Py_INCREF(o2);
-                Py_ssize_t refcount, new_refcount;
+                #define CHECKCOUNT(diff1, diff2, action) \
+                    new_count1 = Py_REFCNT(i1); \
+                    new_count2 = Py_REFCNT(i2); \
+                    diff = new_count1 - old_count1; \
+                    if (diff != diff1) {\
+                        sprintf(errbuffer, action \
+                            " i1 expected diff of %ld got %ld", (long)diff1, (long)diff); \
+                    PyErr_SetString(PyExc_AssertionError, errbuffer); \
+                    return NULL; } \
+                    diff = new_count2 - old_count2; \
+                    if (diff != diff2) {\
+                        sprintf(errbuffer, action \
+                            " i2 expected diff of %ld got %ld", (long)diff2, (long)diff); \
+                    PyErr_SetString(PyExc_AssertionError, errbuffer); \
+                    return NULL; } \
+                    old_count1 = new_count1; \
+                    old_count2 = new_count2;
 
-                refcount = Py_REFCNT(o2); // 1
+                PyObject* tmp, *o = PyList_New(0);
+                char errbuffer[1024];
+                PyObject* i1 = PyBytes_FromString("random string 1");
+                PyObject* i2 = PyBytes_FromString("random string 2");
+                Py_ssize_t old_count1, new_count1;
+                Py_ssize_t old_count2, new_count2;
+                Py_ssize_t diff;
 
-                PyList_Append(o, o2); 
+                old_count1 = Py_REFCNT(i1); // 1
+                old_count2 = Py_REFCNT(i2); // 1
 
-                new_refcount = Py_REFCNT(o2);
+                PyList_Append(o, i1);
+                CHECKCOUNT(1, 0, "PyList_Append");
 
-                if (new_refcount != refcount + 1)
-                    return PyLong_FromSsize_t(-10);
-                refcount = new_refcount;
+                PyList_SET_ITEM(o, 0, i2);
+                CHECKCOUNT(0, 0, "PyList_SET_ITEM");
 
-                // Steal a reference to o2, leak the old reference to o2.
-                // The net result should be no change in refcount.
-                PyList_SET_ITEM(o, 0, o2);
+                tmp = PyList_GET_ITEM(o, 0);
+                // XXX should tmp be the original i2?
+                //     use CPyListStrategy?
+                if (strcmp(PyString_AsString(tmp), PyString_AsString(i2))) 
+                {
+                    sprintf(errbuffer, "GETITEM did not return i2");
+                    PyErr_SetString(PyExc_AssertionError, errbuffer); 
+                    return NULL;
+                }
+                CHECKCOUNT(0, 0, "PyList_GET_ITEM");
 
-                new_refcount = Py_REFCNT(o2);
-
-                Py_DECREF(o2); // append incref'd.
-                Py_DECREF(o);
-                Py_DECREF(o2);
-                return PyLong_FromSsize_t(new_refcount - refcount);
+                Py_DECREF(i1); // append incref'd.
+                Py_DECREF(o); // decref's stolen reference to i2
+                Py_DECREF(i1); 
+                return PyLong_FromSsize_t(0);
              """)])
-        assert module.test_refcount_diff_after_setitem() == 0
+        assert module.test_refcount_diff() == 0


More information about the pypy-commit mailing list