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