Home - Summaries: (main) : (py3.11) : (py3.12) : Everything - Nightly builds - Benchmarks - RPython - Builders - About

pypy/module/cpyext/test/test_capsule.py::AppTestCapsule::()::test_capsule_destructor_via_gc_collect

self = <pypy.interpreter.typedef.W_ObjectObjectUserDictWeakrefable object at 0x0000021f2d73bef8>

    def test_capsule_destructor_via_gc_collect(self):
            # Like test_capsule_set but the C code calls PyGC_Collect() directly
            # instead of going through Python's gc.collect. This mirrors what
            # _testcapimodule.c does in its test_capsule() function.
            # On CPython, Py_DECREF immediately calls tp_dealloc so PyGC_Collect
            # is a no-op for refcounted objects. On PyPy, PyGC_Collect() must
            # trigger rawrefcount collection for the destructor to be called.
            module = self.import_extension('foo_cap_gc', [
                ("test_capsule_gc", "METH_NOARGS",
                """
                    PyObject *object;
                    const char *error = NULL;
                #define FAIL(x) { error = (x); goto exit; }
                #define CHECK_DESTRUCTOR                              \\
                    PyGC_Collect();                                   \\
                    PyGC_Collect();                                   \\
                    if (cap_error) {                                  \\
                        FAIL(cap_error);                              \\
                    }                                                 \\
                    else if (!cap_destructor_count) {                 \\
                        FAIL("destructor not called!");               \\
                    }                                                 \\
                    cap_destructor_count = 0;
    
                    object = PyCapsule_New(cap_pointer, cap_name, cap_destructor);
                    PyCapsule_SetContext(object, cap_context);
                    cap_destructor(object);
                    CHECK_DESTRUCTOR;
                    Py_DECREF(object);
                    CHECK_DESTRUCTOR;
    
                    object = PyCapsule_New(cap_pointer, "ignored", NULL);
                    PyCapsule_SetPointer(object, cap_pointer);
                    PyCapsule_SetName(object, cap_name);
                    PyCapsule_SetDestructor(object, cap_destructor);
                    PyCapsule_SetContext(object, cap_context);
                    cap_destructor(object);
                    CHECK_DESTRUCTOR;
                    PyCapsule_SetDestructor(object, NULL);
                    Py_DECREF(object);
                    if (cap_destructor_count) {
                        FAIL("destructor called when it should not have been!");
                    }
    
                  exit:
                    if (error) {
                        PyErr_Format(PyExc_RuntimeError, "test_capsule: %s", error);
                        return NULL;
                    }
                    Py_RETURN_NONE;
                #undef FAIL
                #undef CHECK_DESTRUCTOR
                """),
            ], prologue="""
                #include <Python.h>
                static const char *cap_name = "capsule name";
                static       char *cap_pointer = "capsule pointer";
                static       char *cap_context = "capsule context";
                static const char *cap_error = NULL;
                static int cap_destructor_count = 0;
    
                static void
                cap_destructor(PyObject *o) {
                    cap_destructor_count++;
                    if (PyCapsule_GetContext(o) != cap_context) {
                        cap_error = "context did not match in destructor!";
                    } else if (PyCapsule_GetDestructor(o) != cap_destructor) {
                        cap_error = "destructor did not match in destructor!  (woah!)";
                    } else if (PyCapsule_GetName(o) != cap_name) {
                        cap_error = "name did not match in destructor!";
                    } else if (PyCapsule_GetPointer(o, cap_name) != cap_pointer) {
                        cap_error = "pointer did not match in destructor!";
                    }
                }
            """)
>           module.test_capsule_gc()
E           (application-level) SystemError: <built-in function test_capsule_gc> returned a result with an exception set

[d:\pypy_stuff\buildbot64\slave\own-win-x86-64\build\pypy\module\cpyext\test\test_capsule.py:125]:76: SystemError
---------- Captured stdout call ----------
source_0.c
   Creating library d:\systemtemp\pytest\usession-py3.12-4636\foo_cap_gc-0\foo_cap_gc.lib and object d:\systemtemp\pytest\usession-py3.12-4636\foo_cap_gc-0\foo_cap_gc.exp
Generating code
Finished generating code
dealloc_trigger...
deallocating PyCapsule
dealloc_trigger DONE
dealloc_trigger...
deallocating PyCapsule
Error in cpyext, CPython compatibility layer:
The function capsule_dealloc was not supposed to fail
Fatal error in cpyext, CPython compatibility layer, calling capsule_dealloc
Either report a bug or consider not using this particular extension
---------- Captured stderr call ----------
<function PyModule_Create2 at 0x0000021f29b24a70>  DONE
<function PyCapsule_New at 0x0000021f2a834548>  DONE
<function PyCapsule_SetContext at 0x0000021f2a835178>  DONE
<function PyGC_Collect at 0x0000021f29840db8>  DONE
<function PyGC_Collect at 0x0000021f29840db8>  DONE
<function PyGC_Collect at 0x0000021f29840db8> <function capsule_dealloc at 0x0000021f2a834890>  DONE
 DONE
<function PyGC_Collect at 0x0000021f29840db8>  DONE
<function PyCapsule_New at 0x0000021f2a834548>  DONE
<function PyCapsule_SetPointer at 0x0000021f2a8349f8>  DONE
<function PyCapsule_SetName at 0x0000021f2a834ea8>  DONE
<function PyCapsule_SetDestructor at 0x0000021f2a834c50>  DONE
<function PyCapsule_SetContext at 0x0000021f2a835178>  DONE
<function PyGC_Collect at 0x0000021f29840db8> <function capsule_dealloc at 0x0000021f2a834890>  File "d:\pypy_stuff\pypy2.7-v7.3.18\lib_pypy\_ctypes\function.py", line 283, in f
    return to_call(*args)
  File "d:\pypy_stuff\buildbot64\slave\own-win-x86-64\build\rpython\rtyper\lltypesystem\ll2ctypes.py", line 895, in callback
    return callback_internal(*cargs)
  File "d:\pypy_stuff\buildbot64\slave\own-win-x86-64\build\rpython\rtyper\lltypesystem\ll2ctypes.py", line 872, in callback_internal
    llres = container._callable(*llargs)
  File "d:\pypy_stuff\buildbot64\slave\own-win-x86-64\build\pypy\module\cpyext\object.py", line 49, in _PyPy_Free
    pyobj_raw_free(ptr)
  File "d:\pypy_stuff\buildbot64\slave\own-win-x86-64\build\pypy\module\cpyext\pyobject.py", line 69, in pyobj_raw_free
    lltype.free(base, flavor='raw')
  File "d:\pypy_stuff\buildbot64\slave\own-win-x86-64\build\rpython\rtyper\lltypesystem\lltype.py", line 2253, in free
    leakfinder.remember_free(p._obj0)
  File "d:\pypy_stuff\buildbot64\slave\own-win-x86-64\build\rpython\tool\leakfinder.py", line 95, in remember_free
    raise KeyError(obj)
 KeyError: <C object Array of void {'nolength': True, 'render_as_void': True}  at 0x21f30150920>
Traceback (most recent call last):
  File "d:\pypy_stuff\buildbot64\slave\own-win-x86-64\build\pypy\module\cpyext\api.py", line 1185, in wrapper_second_level
    result = callable(space, *boxed_args)
  File "d:\pypy_stuff\buildbot64\slave\own-win-x86-64\build\pypy\module\cpyext\capsule.py", line 49, in capsule_dealloc
    _dealloc(space, py_obj)
  File "d:\pypy_stuff\buildbot64\slave\own-win-x86-64\build\pypy\module\cpyext\object.py", line 71, in _dealloc
    _tp_free(space, obj)
  File "d:\pypy_stuff\buildbot64\slave\own-win-x86-64\build\pypy\module\cpyext\object.py", line 63, in _tp_free
    generic_cpy_call(space, pto.c_tp_free, obj_voidp)
  File "d:\pypy_stuff\buildbot64\slave\own-win-x86-64\build\pypy\module\cpyext\api.py", line 2128, in generic_cpy_call
    return make_generic_cpy_call(FT, False, True)(space, func, *args)
  File "d:\pypy_stuff\buildbot64\slave\own-win-x86-64\build\pypy\module\cpyext\api.py", line 2188, in generic_cpy_call
    result = call_external_function(func, *boxed_args)
  File "<3674-codegen d:\pypy_stuff\buildbot64\slave\own-win-x86-64\build\pypy\module\cpyext\api.py:2160>", line 4, in cpy_call_external
    res = funcptr(a0)
  File "d:\pypy_stuff\buildbot64\slave\own-win-x86-64\build\rpython\rtyper\lltypesystem\lltype.py", line 1384, in __call__
    return callb(*args)
  File "d:\pypy_stuff\buildbot64\slave\own-win-x86-64\build\rpython\rtyper\lltypesystem\ll2ctypes.py", line 895, in callback
    return callback_internal(*cargs)
  File "d:\pypy_stuff\buildbot64\slave\own-win-x86-64\build\rpython\rtyper\lltypesystem\ll2ctypes.py", line 872, in callback_internal
    llres = container._callable(*llargs)
  File "d:\pypy_stuff\buildbot64\slave\own-win-x86-64\build\pypy\module\cpyext\object.py", line 49, in _PyPy_Free
    pyobj_raw_free(ptr)
  File "d:\pypy_stuff\buildbot64\slave\own-win-x86-64\build\pypy\module\cpyext\pyobject.py", line 69, in pyobj_raw_free
    lltype.free(base, flavor='raw')
  File "d:\pypy_stuff\buildbot64\slave\own-win-x86-64\build\rpython\rtyper\lltypesystem\lltype.py", line 2253, in free
    leakfinder.remember_free(p._obj0)
  File "d:\pypy_stuff\buildbot64\slave\own-win-x86-64\build\rpython\tool\leakfinder.py", line 95, in remember_free
    raise KeyError(obj)
KeyError: <C object Array of void {'nolength': True, 'render_as_void': True}  at 0x21f30150920>
Traceback (most recent call last):
  File "d:\pypy_stuff\buildbot64\slave\own-win-x86-64\build\pypy\module\cpyext\api.py", line 1225, in wrapper_second_level
    raise not_supposed_to_fail(pname)
  File "d:\pypy_stuff\buildbot64\slave\own-win-x86-64\build\pypy\module\cpyext\api.py", line 1066, in not_supposed_to_fail
    raise SystemError
SystemError
  File "d:\pypy_stuff\pypy2.7-v7.3.18\lib_pypy\_ctypes\function.py", line 283, in f
    return to_call(*args)
  File "d:\pypy_stuff\buildbot64\slave\own-win-x86-64\build\rpython\rtyper\lltypesystem\ll2ctypes.py", line 895, in callback
    return callback_internal(*cargs)
  File "d:\pypy_stuff\buildbot64\slave\own-win-x86-64\build\rpython\rtyper\lltypesystem\ll2ctypes.py", line 872, in callback_internal
    llres = container._callable(*llargs)
  File "d:\pypy_stuff\buildbot64\slave\own-win-x86-64\build\pypy\module\cpyext\api.py", line 1038, in wrapper
    return wrapper_second_level(callable, pname, *args)
  File "d:\pypy_stuff\buildbot64\slave\own-win-x86-64\build\pypy\module\cpyext\api.py", line 1247, in wrapper_second_level
    state.check_and_raise_exception(always=True)
  File "d:\pypy_stuff\buildbot64\slave\own-win-x86-64\build\pypy\module\cpyext\state.py", line 87, in check_and_raise_exception
    raise operror
OperationError: [<W_TypeObject 'SystemError' at 0x21f295d0d78>: W_BaseExceptionUserWeakrefable([W_UnicodeObject("KeyError(<C object Array of void {'nolength': True, 'render_as_void': True}  at 0x21f30150920>,)")])]
<function PyGC_Collect at 0x0000021f29840db8>  DONE
<function PyCapsule_SetDestructor at 0x0000021f2a834c50>  DONE
 (somefailed=True in module/cpyext/test/test_capsule.py)
builder: own-win-x86-64 build #2420+
test: pypy/module/cpyext/test/test_capsule.py::AppTestCapsule::()::test_capsule_destructor_via_gc_collect