Author: Stefan Beyer <[email protected]>
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
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit