mirror of https://github.com/python/cpython
gh-113753: Clear finalized bit when putting PyAsyncGenASend back into free list (#113754)
This commit is contained in:
parent
901a971e16
commit
73ae2023a7
|
@ -122,6 +122,10 @@ static inline void _PyGC_SET_FINALIZED(PyObject *op) {
|
||||||
PyGC_Head *gc = _Py_AS_GC(op);
|
PyGC_Head *gc = _Py_AS_GC(op);
|
||||||
_PyGCHead_SET_FINALIZED(gc);
|
_PyGCHead_SET_FINALIZED(gc);
|
||||||
}
|
}
|
||||||
|
static inline void _PyGC_CLEAR_FINALIZED(PyObject *op) {
|
||||||
|
PyGC_Head *gc = _Py_AS_GC(op);
|
||||||
|
gc->_gc_prev &= ~_PyGC_PREV_MASK_FINALIZED;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* GC runtime state */
|
/* GC runtime state */
|
||||||
|
|
|
@ -1701,6 +1701,14 @@ class TestUnawaitedWarnings(unittest.TestCase):
|
||||||
async def gen():
|
async def gen():
|
||||||
yield 1
|
yield 1
|
||||||
|
|
||||||
|
# gh-113753: asend objects allocated from a free-list should warn.
|
||||||
|
# Ensure there is a finalized 'asend' object ready to be reused.
|
||||||
|
try:
|
||||||
|
g = gen()
|
||||||
|
g.asend(None).send(None)
|
||||||
|
except StopIteration:
|
||||||
|
pass
|
||||||
|
|
||||||
msg = f"coroutine method 'asend' of '{gen.__qualname__}' was never awaited"
|
msg = f"coroutine method 'asend' of '{gen.__qualname__}' was never awaited"
|
||||||
with self.assertWarnsRegex(RuntimeWarning, msg):
|
with self.assertWarnsRegex(RuntimeWarning, msg):
|
||||||
g = gen()
|
g = gen()
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
Fix an issue where the finalizer of ``PyAsyncGenASend`` objects might not be
|
||||||
|
called if they were allocated from a free list.
|
|
@ -6,6 +6,7 @@
|
||||||
#include "pycore_call.h" // _PyObject_CallNoArgs()
|
#include "pycore_call.h" // _PyObject_CallNoArgs()
|
||||||
#include "pycore_ceval.h" // _PyEval_EvalFrame()
|
#include "pycore_ceval.h" // _PyEval_EvalFrame()
|
||||||
#include "pycore_frame.h" // _PyInterpreterFrame
|
#include "pycore_frame.h" // _PyInterpreterFrame
|
||||||
|
#include "pycore_gc.h" // _PyGC_CLEAR_FINALIZED()
|
||||||
#include "pycore_genobject.h" // struct _Py_async_gen_state
|
#include "pycore_genobject.h" // struct _Py_async_gen_state
|
||||||
#include "pycore_modsupport.h" // _PyArg_CheckPositional()
|
#include "pycore_modsupport.h" // _PyArg_CheckPositional()
|
||||||
#include "pycore_object.h" // _PyObject_GC_UNTRACK()
|
#include "pycore_object.h" // _PyObject_GC_UNTRACK()
|
||||||
|
@ -1739,6 +1740,7 @@ async_gen_asend_dealloc(PyAsyncGenASend *o)
|
||||||
#endif
|
#endif
|
||||||
if (state->asend_numfree < _PyAsyncGen_MAXFREELIST) {
|
if (state->asend_numfree < _PyAsyncGen_MAXFREELIST) {
|
||||||
assert(PyAsyncGenASend_CheckExact(o));
|
assert(PyAsyncGenASend_CheckExact(o));
|
||||||
|
_PyGC_CLEAR_FINALIZED((PyObject *)o);
|
||||||
state->asend_freelist[state->asend_numfree++] = o;
|
state->asend_freelist[state->asend_numfree++] = o;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in New Issue