Author: Stefan Beyer <h...@sbeyer.at>
Branch: cpyext-gc-cycle
Changeset: r95611:fa88e83164e0
Date: 2018-08-03 13:11 +0200
http://bitbucket.org/pypy/pypy/changeset/fa88e83164e0/

Log:    Fixed cpyext test

diff --git a/pypy/module/cpyext/test/test_cpyext.py 
b/pypy/module/cpyext/test/test_cpyext.py
--- a/pypy/module/cpyext/test/test_cpyext.py
+++ b/pypy/module/cpyext/test/test_cpyext.py
@@ -3,7 +3,7 @@
 import pytest
 
 from pypy.tool.cpyext.extbuild import SystemCompilationInfo, HERE
-from pypy.interpreter.gateway import unwrap_spec, interp2app
+from pypy.interpreter.gateway import unwrap_spec, interp2app, ObjSpace
 from pypy.interpreter.error import OperationError
 from rpython.rtyper.lltypesystem import lltype
 from pypy.module.cpyext import api
@@ -214,8 +214,8 @@
 def debug_collect(space):
     rawrefcount._collect()
 
-def print_pyobj_list(space):
-    rawrefcount._print_pyobj_list()
+def in_pygclist(space, int_addr):
+    return space.wrap(rawrefcount._in_pygclist(int_addr))
 
 class AppTestCpythonExtensionBase(LeakCheckingTest):
 
@@ -227,7 +227,8 @@
         if not cls.runappdirect:
             cls.sys_info = get_cpyext_info(space)
             cls.w_debug_collect = space.wrap(interp2app(debug_collect))
-            cls.w_print_pyobj_list = space.wrap(interp2app(print_pyobj_list))
+            cls.w_in_pygclist = space.wrap(
+                interp2app(in_pygclist, unwrap_spec=[ObjSpace, int]))
             cls.preload_builtins(space)
         else:
             def w_import_module(self, name, init=None, body='', filename=None,
@@ -929,7 +930,7 @@
              ),
         ])
 
-    def test_gc_pyobj_list(self):
+    def test_gc_track(self):
         """
         Test if Py_GC_Track and Py_GC_Untrack are adding and removing container
         objects from the list of all garbage-collected PyObjects.
@@ -937,17 +938,16 @@
         if self.runappdirect:
             skip('cannot import module with undefined functions')
 
-        # TODO: remove unnecessary stuff, add gc_(un)track asserts
         init = """
         if (Py_IsInitialized()) {
             PyObject* m;
-            if (PyType_Ready(&CycleType) < 0)
+            if (PyType_Ready(&FooType) < 0)
                 return;
-            m = Py_InitModule("cycle", module_methods);
+            m = Py_InitModule("foo", module_methods);
             if (m == NULL)
                 return;
-            Py_INCREF(&CycleType);
-            PyModule_AddObject(m, "Cycle", (PyObject *)&CycleType);
+            Py_INCREF(&FooType);
+            PyModule_AddObject(m, "Foo", (PyObject *)&FooType);
         }
         """
         body = """
@@ -955,85 +955,22 @@
         #include "structmember.h"
         typedef struct {
             PyObject_HEAD
-            PyObject *next;
-            PyObject *val;
-        } Cycle;
-        static PyTypeObject CycleType;
-        static int Cycle_traverse(Cycle *self, visitproc visit, void *arg)
-        {
-            int vret;
-            if (self->next) {
-                vret = visit(self->next, arg);
-                if (vret != 0)
-                    return vret;
-            }
-            if (self->val) {
-                vret = visit(self->val, arg);
-                if (vret != 0)
-                    return vret;
-            }
-            return 0;
-        }
-        static int Cycle_clear(Cycle *self)
-        {
-            PyObject *tmp;
-            tmp = self->next;
-            self->next = NULL;
-            Py_XDECREF(tmp);
-            tmp = self->val;
-            self->val = NULL;
-            Py_XDECREF(tmp);
-            return 0;
-        }
-        static void Cycle_dealloc(Cycle* self)
-        {
-            Cycle_clear(self);
-            Py_TYPE(self)->tp_free((PyObject*)self);
-        }
-        static PyObject* Cycle_new(PyTypeObject *type, PyObject *args,
+        } Foo;
+        static PyTypeObject FooType;
+        static PyObject* Foo_new(PyTypeObject *type, PyObject *args,
                                    PyObject *kwds)
         {
-            Cycle *self;
-            self = PyObject_GC_New(Cycle, type);
-            if (self != NULL) {
-                self->next = PyString_FromString("");
-                if (self->next == NULL) {
-                    Py_DECREF(self);
-                    return NULL;
-                }
-            }
+            Foo *self;
+            self = PyObject_GC_New(Foo, type);
             PyObject_GC_Track(self);
             return (PyObject *)self;
         }
-        static int Cycle_init(Cycle *self, PyObject *args, PyObject *kwds)
-        {
-            PyObject *next=NULL, *tmp;
-            static char *kwlist[] = {"next", NULL};
-            if (! PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwlist,
-                                              &next))
-                return -1;
-            if (next) {
-                tmp = self->next;
-                Py_INCREF(next);
-                self->next = next;
-                Py_XDECREF(tmp);
-            }
-            return 0;
-        }
-        static PyMemberDef Cycle_members[] = {
-            {"next", T_OBJECT_EX, offsetof(Cycle, next), 0, "next"},
-            {"val", T_OBJECT_EX, offsetof(Cycle, val), 0, "val"},
-            {NULL}  /* Sentinel */
-        };
-        static PyMethodDef Cycle_methods[] = {
-            {NULL}  /* Sentinel */
-        };
-        static PyTypeObject CycleType = {
+        static PyTypeObject FooType = {
             PyVarObject_HEAD_INIT(NULL, 0)
-            "Cycle.Cycle",             /* tp_name */
-            sizeof(Cycle),             /* tp_basicsize */
+            "foo.Foo",                 /* tp_name */
+            sizeof(Foo),               /* tp_basicsize */
             0,                         /* tp_itemsize */
-            (destructor)Cycle_dealloc, /* tp_dealloc */
+            0,                         /* tp_dealloc */
             0,                         /* tp_print */
             0,                         /* tp_getattr */
             0,                         /* tp_setattr */
@@ -1049,57 +986,57 @@
             0,                         /* tp_setattro */
             0,                         /* tp_as_buffer */
             Py_TPFLAGS_DEFAULT |
-                Py_TPFLAGS_BASETYPE |
                 Py_TPFLAGS_HAVE_GC,    /* tp_flags */
-            "Cycle objects",           /* tp_doc */
-            (traverseproc)Cycle_traverse,   /* tp_traverse */
-            (inquiry)Cycle_clear,           /* tp_clear */
+            "",                        /* tp_doc */
+            0,                         /* tp_traverse */
+            0,                         /* tp_clear */
             0,                         /* tp_richcompare */
             0,                         /* tp_weaklistoffset */
             0,                         /* tp_iter */
             0,                         /* tp_iternext */
-            Cycle_methods,             /* tp_methods */
-            Cycle_members,             /* tp_members */
+            0,                         /* tp_methods */
+            0,                         /* tp_members */
             0,                         /* tp_getset */
             0,                         /* tp_base */
             0,                         /* tp_dict */
             0,                         /* tp_descr_get */
             0,                         /* tp_descr_set */
             0,                         /* tp_dictoffset */
-            (initproc)Cycle_init,      /* tp_init */
+            0,                         /* tp_init */
             0,                         /* tp_alloc */
-            Cycle_new,                 /* tp_new */
+            Foo_new,                   /* tp_new */
             PyObject_GC_Del,           /* tp_free */
         };
+                
+        static PyObject * Foo_pygchead(PyObject *self, Foo *foo)
+        {
+            PyGC_Head * gc_head = _PyPy_pyobj_as_gc((GCHdr_PyObject *)foo);
+            PyObject *obj = PyObject_MALLOC(sizeof(PyIntObject));
+            obj = PyObject_Init(obj, &PyInt_Type);
+            if (obj != NULL)
+                ((PyIntObject *)obj)->ob_ival = (long)gc_head;
+            return obj;
+        }
         
-        extern PyGC_Head *_pypy_rawrefcount_pyobj_list;
-
-        static PyObject * Cycle_Create(Cycle *self, PyObject *val)
+        static PyObject * Foo_untrack(PyObject *self, Foo *foo)
         {
-            Cycle *c = (Cycle *)Cycle_new(&CycleType, NULL, NULL);
-            if (c == NULL)
-               return NULL;
-                
-            Py_INCREF(val);
-            c->next = val;
-
-            // TODO: check if _pypy_rawrefcount_pyobj_list contains c
-
-            return (PyObject *)c;
+           PyObject_GC_UnTrack(foo);
+           Py_RETURN_NONE;
         }
+        
         static PyMethodDef module_methods[] = {
-            {"create", (PyCFunction)Cycle_Create, METH_OLDARGS, ""},
+            {"pygchead", (PyCFunction)Foo_pygchead, METH_OLDARGS, ""},
+            {"untrack", (PyCFunction)Foo_untrack, METH_OLDARGS, ""},
             {NULL}  /* Sentinel */
         };
         """
-        module = self.import_module(name='cycle', init=init, body=body)
+        module = self.import_module(name='foo', init=init, body=body)
 
-        class Example(object):
-            def __init__(self, val):
-                self.val = val
+        f = module.Foo()
+        pygchead = module.pygchead(f)
+        result = self.in_pygclist(pygchead)
+        assert result
 
-        c = module.create(Example(41))
-
-        self.print_pyobj_list()
-        c = module.create(Example(42))
-        self.print_pyobj_list()
+        module.untrack(f)
+        result = self.in_pygclist(pygchead)
+        assert not result
diff --git a/rpython/rlib/rawrefcount.py b/rpython/rlib/rawrefcount.py
--- a/rpython/rlib/rawrefcount.py
+++ b/rpython/rlib/rawrefcount.py
@@ -221,16 +221,17 @@
     del _d_list[:]
 
 @not_rpython
-def _print_pyobj_list():
-    "for tests only"
-    # TODO: change to get_pyobj_list, that returns a list of PyObjects
-    #       or alternatively checks if a certain object is in the list
+def _in_pygclist(int_addr):
+    """For tests only. Checks if the address is in the gc list of pyobjects."""
     global _pyobj_list
-    print "_print_pyobj_list start!"
     curr = _pyobj_list.c_gc_next
     while curr != _pyobj_list:
-        print "_print_pyobj_list: ", curr
+        curr_addr = llmemory.cast_ptr_to_adr(curr)
+        curr_int_addr = llmemory.cast_adr_to_int(curr_addr)
+        if int_addr == curr_int_addr:
+            return True
         curr = curr.c_gc_next
+    return False
 
 # ____________________________________________________________
 
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to