https://github.com/python/cpython/commit/73ae2023a76f199ff854f8da14bd9ff8e93ee7fd
commit: 73ae2023a76f199ff854f8da14bd9ff8e93ee7fd
branch: main
author: Sam Gross <colesb...@gmail.com>
committer: gvanrossum <gvanros...@gmail.com>
date: 2024-01-10T10:18:38-08:00
summary:

gh-113753: Clear finalized bit when putting PyAsyncGenASend back into free list 
(#113754)

files:
A Misc/NEWS.d/next/Core and 
Builtins/2024-01-05-21-28-48.gh-issue-113753.2HNiuq.rst
M Include/internal/pycore_gc.h
M Lib/test/test_asyncgen.py
M Objects/genobject.c

diff --git a/Include/internal/pycore_gc.h b/Include/internal/pycore_gc.h
index 2a0730eebb8db7..753763a5a50220 100644
--- a/Include/internal/pycore_gc.h
+++ b/Include/internal/pycore_gc.h
@@ -122,6 +122,10 @@ static inline void _PyGC_SET_FINALIZED(PyObject *op) {
     PyGC_Head *gc = _Py_AS_GC(op);
     _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 */
diff --git a/Lib/test/test_asyncgen.py b/Lib/test/test_asyncgen.py
index a49630112af510..7fa0a85100a581 100644
--- a/Lib/test/test_asyncgen.py
+++ b/Lib/test/test_asyncgen.py
@@ -1701,6 +1701,14 @@ def test_asend(self):
         async def gen():
             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"
         with self.assertWarnsRegex(RuntimeWarning, msg):
             g = gen()
diff --git a/Misc/NEWS.d/next/Core and 
Builtins/2024-01-05-21-28-48.gh-issue-113753.2HNiuq.rst b/Misc/NEWS.d/next/Core 
and Builtins/2024-01-05-21-28-48.gh-issue-113753.2HNiuq.rst
new file mode 100644
index 00000000000000..32cf2cb2a4ae56
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and 
Builtins/2024-01-05-21-28-48.gh-issue-113753.2HNiuq.rst 
@@ -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.
diff --git a/Objects/genobject.c b/Objects/genobject.c
index 9614713883741c..f03919c75d70a5 100644
--- a/Objects/genobject.c
+++ b/Objects/genobject.c
@@ -6,6 +6,7 @@
 #include "pycore_call.h"          // _PyObject_CallNoArgs()
 #include "pycore_ceval.h"         // _PyEval_EvalFrame()
 #include "pycore_frame.h"         // _PyInterpreterFrame
+#include "pycore_gc.h"            // _PyGC_CLEAR_FINALIZED()
 #include "pycore_genobject.h"     // struct _Py_async_gen_state
 #include "pycore_modsupport.h"    // _PyArg_CheckPositional()
 #include "pycore_object.h"        // _PyObject_GC_UNTRACK()
@@ -1739,6 +1740,7 @@ async_gen_asend_dealloc(PyAsyncGenASend *o)
 #endif
     if (state->asend_numfree < _PyAsyncGen_MAXFREELIST) {
         assert(PyAsyncGenASend_CheckExact(o));
+        _PyGC_CLEAR_FINALIZED((PyObject *)o);
         state->asend_freelist[state->asend_numfree++] = o;
     }
     else

_______________________________________________
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: arch...@mail-archive.com

Reply via email to