aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Modules
diff options
context:
space:
mode:
Diffstat (limited to 'Modules')
-rw-r--r--Modules/_collectionsmodule.c5
-rw-r--r--Modules/_elementtree.c4
-rw-r--r--Modules/_functoolsmodule.c9
-rw-r--r--Modules/_io/bufferedio.c7
-rw-r--r--Modules/_io/bytesio.c4
-rw-r--r--Modules/_io/fileio.c5
-rw-r--r--Modules/_io/iobase.c4
-rw-r--r--Modules/_io/stringio.c5
-rw-r--r--Modules/_io/textio.c4
-rw-r--r--Modules/_io/winconsoleio.c4
-rw-r--r--Modules/_queuemodule.c5
-rw-r--r--Modules/_sqlite/blob.c5
-rw-r--r--Modules/_sqlite/cursor.c5
-rw-r--r--Modules/_sre/sre.c6
-rw-r--r--Modules/_struct.c5
-rw-r--r--Modules/_testinternalcapi.c2
-rw-r--r--Modules/_threadmodule.c22
-rw-r--r--Modules/_zoneinfo.c5
-rw-r--r--Modules/arraymodule.c5
-rw-r--r--Modules/itertoolsmodule.c38
-rw-r--r--Modules/mmapmodule.c4
-rw-r--r--Modules/pyexpat.c85
22 files changed, 167 insertions, 71 deletions
diff --git a/Modules/_collectionsmodule.c b/Modules/_collectionsmodule.c
index ad670293ec5..3ba48d5d9d3 100644
--- a/Modules/_collectionsmodule.c
+++ b/Modules/_collectionsmodule.c
@@ -5,6 +5,7 @@
#include "pycore_moduleobject.h" // _PyModule_GetState()
#include "pycore_pyatomic_ft_wrappers.h"
#include "pycore_typeobject.h" // _PyType_GetModuleState()
+#include "pycore_weakref.h" // FT_CLEAR_WEAKREFS()
#include <stddef.h>
@@ -1532,9 +1533,7 @@ deque_dealloc(PyObject *self)
Py_ssize_t i;
PyObject_GC_UnTrack(deque);
- if (deque->weakreflist != NULL) {
- PyObject_ClearWeakRefs(self);
- }
+ FT_CLEAR_WEAKREFS(self, deque->weakreflist);
if (deque->leftblock != NULL) {
(void)deque_clear(self);
assert(deque->leftblock != NULL);
diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c
index fe24629f9f6..b9e12ab2026 100644
--- a/Modules/_elementtree.c
+++ b/Modules/_elementtree.c
@@ -17,6 +17,7 @@
#include "Python.h"
#include "pycore_pyhash.h" // _Py_HashSecret
+#include "pycore_weakref.h" // FT_CLEAR_WEAKREFS()
#include <stddef.h> // offsetof()
#include "expat.h"
@@ -690,8 +691,7 @@ element_dealloc(PyObject *op)
/* bpo-31095: UnTrack is needed before calling any callbacks */
PyObject_GC_UnTrack(self);
- if (self->weakreflist != NULL)
- PyObject_ClearWeakRefs(op);
+ FT_CLEAR_WEAKREFS(op, self->weakreflist);
/* element_gc_clear clears all references and deallocates extra
*/
diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c
index 354dbad84b5..d3dabd58b89 100644
--- a/Modules/_functoolsmodule.c
+++ b/Modules/_functoolsmodule.c
@@ -7,6 +7,7 @@
#include "pycore_pyatomic_ft_wrappers.h"
#include "pycore_pystate.h" // _PyThreadState_GET()
#include "pycore_tuple.h" // _PyTuple_ITEMS()
+#include "pycore_weakref.h" // FT_CLEAR_WEAKREFS()
#include "clinic/_functoolsmodule.c.h"
@@ -351,9 +352,7 @@ partial_dealloc(PyObject *self)
PyTypeObject *tp = Py_TYPE(self);
/* bpo-31095: UnTrack is needed before calling any callbacks */
PyObject_GC_UnTrack(self);
- if (partialobject_CAST(self)->weakreflist != NULL) {
- PyObject_ClearWeakRefs(self);
- }
+ FT_CLEAR_WEAKREFS(self, partialobject_CAST(self)->weakreflist);
(void)partial_clear(self);
tp->tp_free(self);
Py_DECREF(tp);
@@ -1621,9 +1620,7 @@ lru_cache_dealloc(PyObject *op)
PyTypeObject *tp = Py_TYPE(obj);
/* bpo-31095: UnTrack is needed before calling any callbacks */
PyObject_GC_UnTrack(obj);
- if (obj->weakreflist != NULL) {
- PyObject_ClearWeakRefs(op);
- }
+ FT_CLEAR_WEAKREFS(op, obj->weakreflist);
(void)lru_cache_tp_clear(op);
tp->tp_free(obj);
diff --git a/Modules/_io/bufferedio.c b/Modules/_io/bufferedio.c
index 4724e97982f..25c8bf8b3d5 100644
--- a/Modules/_io/bufferedio.c
+++ b/Modules/_io/bufferedio.c
@@ -13,6 +13,7 @@
#include "pycore_object.h" // _PyObject_GC_UNTRACK()
#include "pycore_pyerrors.h" // _Py_FatalErrorFormat()
#include "pycore_pylifecycle.h" // _Py_IsInterpreterFinalizing()
+#include "pycore_weakref.h" // FT_CLEAR_WEAKREFS()
#include "_iomodule.h"
@@ -421,8 +422,7 @@ buffered_dealloc(PyObject *op)
return;
_PyObject_GC_UNTRACK(self);
self->ok = 0;
- if (self->weakreflist != NULL)
- PyObject_ClearWeakRefs(op);
+ FT_CLEAR_WEAKREFS(op, self->weakreflist);
if (self->buffer) {
PyMem_Free(self->buffer);
self->buffer = NULL;
@@ -2312,8 +2312,7 @@ bufferedrwpair_dealloc(PyObject *op)
rwpair *self = rwpair_CAST(op);
PyTypeObject *tp = Py_TYPE(self);
_PyObject_GC_UNTRACK(self);
- if (self->weakreflist != NULL)
- PyObject_ClearWeakRefs(op);
+ FT_CLEAR_WEAKREFS(op, self->weakreflist);
(void)bufferedrwpair_clear(op);
tp->tp_free(self);
Py_DECREF(tp);
diff --git a/Modules/_io/bytesio.c b/Modules/_io/bytesio.c
index 61cfec435fe..1c71bce4fbb 100644
--- a/Modules/_io/bytesio.c
+++ b/Modules/_io/bytesio.c
@@ -3,6 +3,7 @@
#include "pycore_object.h"
#include "pycore_pyatomic_ft_wrappers.h"
#include "pycore_sysmodule.h" // _PySys_GetSizeOf()
+#include "pycore_weakref.h" // FT_CLEAR_WEAKREFS()
#include <stddef.h> // offsetof()
#include "_iomodule.h"
@@ -979,8 +980,7 @@ bytesio_dealloc(PyObject *op)
}
Py_CLEAR(self->buf);
Py_CLEAR(self->dict);
- if (self->weakreflist != NULL)
- PyObject_ClearWeakRefs(op);
+ FT_CLEAR_WEAKREFS(op, self->weakreflist);
tp->tp_free(self);
Py_DECREF(tp);
}
diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c
index 8fcb27049d6..26537fc6395 100644
--- a/Modules/_io/fileio.c
+++ b/Modules/_io/fileio.c
@@ -4,6 +4,7 @@
#include "pycore_fileutils.h" // _Py_BEGIN_SUPPRESS_IPH
#include "pycore_object.h" // _PyObject_GC_UNTRACK()
#include "pycore_pyerrors.h" // _PyErr_ChainExceptions1()
+#include "pycore_weakref.h" // FT_CLEAR_WEAKREFS()
#include <stdbool.h> // bool
#ifdef HAVE_UNISTD_H
@@ -570,9 +571,7 @@ fileio_dealloc(PyObject *op)
PyMem_Free(self->stat_atopen);
self->stat_atopen = NULL;
}
- if (self->weakreflist != NULL) {
- PyObject_ClearWeakRefs(op);
- }
+ FT_CLEAR_WEAKREFS(op, self->weakreflist);
(void)fileio_clear(op);
PyTypeObject *tp = Py_TYPE(op);
diff --git a/Modules/_io/iobase.c b/Modules/_io/iobase.c
index cd4c7e7cead..044f6b7803c 100644
--- a/Modules/_io/iobase.c
+++ b/Modules/_io/iobase.c
@@ -14,6 +14,7 @@
#include "pycore_long.h" // _PyLong_GetOne()
#include "pycore_object.h" // _PyType_HasFeature()
#include "pycore_pyerrors.h" // _PyErr_ChainExceptions1()
+#include "pycore_weakref.h" // FT_CLEAR_WEAKREFS()
#include <stddef.h> // offsetof()
#include "_iomodule.h"
@@ -383,8 +384,7 @@ iobase_dealloc(PyObject *op)
}
PyTypeObject *tp = Py_TYPE(self);
_PyObject_GC_UNTRACK(self);
- if (self->weakreflist != NULL)
- PyObject_ClearWeakRefs(op);
+ FT_CLEAR_WEAKREFS(op, self->weakreflist);
Py_CLEAR(self->dict);
tp->tp_free(self);
Py_DECREF(tp);
diff --git a/Modules/_io/stringio.c b/Modules/_io/stringio.c
index 56913fafefb..20b7cfc0088 100644
--- a/Modules/_io/stringio.c
+++ b/Modules/_io/stringio.c
@@ -1,6 +1,7 @@
#include "Python.h"
#include <stddef.h> // offsetof()
#include "pycore_object.h"
+#include "pycore_weakref.h" // FT_CLEAR_WEAKREFS()
#include "_iomodule.h"
/* Implementation note: the buffer is always at least one character longer
@@ -638,9 +639,7 @@ stringio_dealloc(PyObject *op)
}
PyUnicodeWriter_Discard(self->writer);
(void)stringio_clear(op);
- if (self->weakreflist != NULL) {
- PyObject_ClearWeakRefs(op);
- }
+ FT_CLEAR_WEAKREFS(op, self->weakreflist);
tp->tp_free(self);
Py_DECREF(tp);
}
diff --git a/Modules/_io/textio.c b/Modules/_io/textio.c
index 3808ecdceb9..5354cf63442 100644
--- a/Modules/_io/textio.c
+++ b/Modules/_io/textio.c
@@ -16,6 +16,7 @@
#include "pycore_pyerrors.h" // _PyErr_ChainExceptions1()
#include "pycore_pystate.h" // _PyInterpreterState_GET()
#include "pycore_unicodeobject.h" // _PyUnicode_AsASCIIString()
+#include "pycore_weakref.h" // FT_CLEAR_WEAKREFS()
#include "_iomodule.h"
@@ -1469,8 +1470,7 @@ textiowrapper_dealloc(PyObject *op)
return;
self->ok = 0;
_PyObject_GC_UNTRACK(self);
- if (self->weakreflist != NULL)
- PyObject_ClearWeakRefs(op);
+ FT_CLEAR_WEAKREFS(op, self->weakreflist);
(void)textiowrapper_clear(op);
tp->tp_free(self);
Py_DECREF(tp);
diff --git a/Modules/_io/winconsoleio.c b/Modules/_io/winconsoleio.c
index 3e783b9da45..950b7fe241c 100644
--- a/Modules/_io/winconsoleio.c
+++ b/Modules/_io/winconsoleio.c
@@ -10,6 +10,7 @@
#include "pycore_fileutils.h" // _Py_BEGIN_SUPPRESS_IPH
#include "pycore_object.h" // _PyObject_GC_UNTRACK()
#include "pycore_pyerrors.h" // _PyErr_ChainExceptions1()
+#include "pycore_weakref.h" // FT_CLEAR_WEAKREFS()
#ifdef HAVE_WINDOWS_CONSOLE_IO
@@ -518,8 +519,7 @@ winconsoleio_dealloc(PyObject *op)
if (_PyIOBase_finalize(op) < 0)
return;
_PyObject_GC_UNTRACK(self);
- if (self->weakreflist != NULL)
- PyObject_ClearWeakRefs(op);
+ FT_CLEAR_WEAKREFS(op, self->weakreflist);
Py_CLEAR(self->dict);
tp->tp_free(self);
Py_DECREF(tp);
diff --git a/Modules/_queuemodule.c b/Modules/_queuemodule.c
index 3ee14b61b82..01235c77bd7 100644
--- a/Modules/_queuemodule.c
+++ b/Modules/_queuemodule.c
@@ -7,6 +7,7 @@
#include "pycore_moduleobject.h" // _PyModule_GetState()
#include "pycore_parking_lot.h"
#include "pycore_time.h" // _PyTime_FromSecondsObject()
+#include "pycore_weakref.h" // FT_CLEAR_WEAKREFS()
#include <stdbool.h>
#include <stddef.h> // offsetof()
@@ -221,9 +222,7 @@ simplequeue_dealloc(PyObject *op)
PyObject_GC_UnTrack(self);
(void)simplequeue_clear(op);
- if (self->weakreflist != NULL) {
- PyObject_ClearWeakRefs(op);
- }
+ FT_CLEAR_WEAKREFS(op, self->weakreflist);
tp->tp_free(self);
Py_DECREF(tp);
}
diff --git a/Modules/_sqlite/blob.c b/Modules/_sqlite/blob.c
index 35d090e3ca2..aafefbf316e 100644
--- a/Modules/_sqlite/blob.c
+++ b/Modules/_sqlite/blob.c
@@ -4,6 +4,7 @@
#include "blob.h"
#include "util.h"
+#include "pycore_weakref.h" // FT_CLEAR_WEAKREFS()
#define clinic_state() (pysqlite_get_state_by_type(Py_TYPE(self)))
#include "clinic/blob.c.h"
@@ -56,9 +57,7 @@ blob_dealloc(PyObject *op)
close_blob(self);
- if (self->in_weakreflist != NULL) {
- PyObject_ClearWeakRefs(op);
- }
+ FT_CLEAR_WEAKREFS(op, self->in_weakreflist);
(void)tp->tp_clear(op);
tp->tp_free(self);
Py_DECREF(tp);
diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c
index 7943bfcca36..0c3f43d0e50 100644
--- a/Modules/_sqlite/cursor.c
+++ b/Modules/_sqlite/cursor.c
@@ -31,6 +31,7 @@
#include "util.h"
#include "pycore_pyerrors.h" // _PyErr_FormatFromCause()
+#include "pycore_weakref.h" // FT_CLEAR_WEAKREFS()
typedef enum {
TYPE_LONG,
@@ -185,9 +186,7 @@ cursor_dealloc(PyObject *op)
pysqlite_Cursor *self = _pysqlite_Cursor_CAST(op);
PyTypeObject *tp = Py_TYPE(self);
PyObject_GC_UnTrack(self);
- if (self->in_weakreflist != NULL) {
- PyObject_ClearWeakRefs(op);
- }
+ FT_CLEAR_WEAKREFS(op, self->in_weakreflist);
(void)tp->tp_clear(op);
tp->tp_free(self);
Py_DECREF(tp);
diff --git a/Modules/_sre/sre.c b/Modules/_sre/sre.c
index 602d0ab8588..e8943920043 100644
--- a/Modules/_sre/sre.c
+++ b/Modules/_sre/sre.c
@@ -44,6 +44,7 @@ static const char copyright[] =
#include "pycore_long.h" // _PyLong_GetZero()
#include "pycore_moduleobject.h" // _PyModule_GetState()
#include "pycore_unicodeobject.h" // _PyUnicode_Copy
+#include "pycore_weakref.h" // FT_CLEAR_WEAKREFS()
#include "sre.h" // SRE_CODE
@@ -736,10 +737,7 @@ pattern_dealloc(PyObject *self)
{
PyTypeObject *tp = Py_TYPE(self);
PyObject_GC_UnTrack(self);
- PatternObject *obj = _PatternObject_CAST(self);
- if (obj->weakreflist != NULL) {
- PyObject_ClearWeakRefs(self);
- }
+ FT_CLEAR_WEAKREFS(self, _PatternObject_CAST(self)->weakreflist);
(void)pattern_clear(self);
tp->tp_free(self);
Py_DECREF(tp);
diff --git a/Modules/_struct.c b/Modules/_struct.c
index c36079f1eb8..3fad35a8c94 100644
--- a/Modules/_struct.c
+++ b/Modules/_struct.c
@@ -11,6 +11,7 @@
#include "pycore_bytesobject.h" // _PyBytesWriter
#include "pycore_long.h" // _PyLong_AsByteArray()
#include "pycore_moduleobject.h" // _PyModule_GetState()
+#include "pycore_weakref.h" // FT_CLEAR_WEAKREFS()
#include <stddef.h> // offsetof()
@@ -1794,9 +1795,7 @@ s_dealloc(PyObject *op)
PyStructObject *s = PyStructObject_CAST(op);
PyTypeObject *tp = Py_TYPE(s);
PyObject_GC_UnTrack(s);
- if (s->weakreflist != NULL) {
- PyObject_ClearWeakRefs(op);
- }
+ FT_CLEAR_WEAKREFS(op, s->weakreflist);
if (s->s_codes != NULL) {
PyMem_Free(s->s_codes);
}
diff --git a/Modules/_testinternalcapi.c b/Modules/_testinternalcapi.c
index fdf22a0c994..8027f0015c7 100644
--- a/Modules/_testinternalcapi.c
+++ b/Modules/_testinternalcapi.c
@@ -121,7 +121,7 @@ get_c_recursion_remaining(PyObject *self, PyObject *Py_UNUSED(args))
PyThreadState *tstate = _PyThreadState_GET();
uintptr_t here_addr = _Py_get_machine_stack_pointer();
_PyThreadStateImpl *_tstate = (_PyThreadStateImpl *)tstate;
- int remaining = (int)((here_addr - _tstate->c_stack_soft_limit)/PYOS_STACK_MARGIN_BYTES * 50);
+ int remaining = (int)((here_addr - _tstate->c_stack_soft_limit) / _PyOS_STACK_MARGIN_BYTES * 50);
return PyLong_FromLong(remaining);
}
diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c
index 150a266b521..8886a9d6bd0 100644
--- a/Modules/_threadmodule.c
+++ b/Modules/_threadmodule.c
@@ -834,9 +834,14 @@ lock_PyThread_acquire_lock(PyObject *op, PyObject *args, PyObject *kwds)
return NULL;
}
- PyLockStatus r = _PyMutex_LockTimed(&self->lock, timeout,
- _PY_LOCK_HANDLE_SIGNALS | _PY_LOCK_DETACH);
+ PyLockStatus r = _PyMutex_LockTimed(
+ &self->lock, timeout,
+ _PY_LOCK_PYTHONLOCK | _PY_LOCK_HANDLE_SIGNALS | _PY_LOCK_DETACH);
if (r == PY_LOCK_INTR) {
+ assert(PyErr_Occurred());
+ return NULL;
+ }
+ if (r == PY_LOCK_FAILURE && PyErr_Occurred()) {
return NULL;
}
@@ -1054,9 +1059,14 @@ rlock_acquire(PyObject *op, PyObject *args, PyObject *kwds)
return NULL;
}
- PyLockStatus r = _PyRecursiveMutex_LockTimed(&self->lock, timeout,
- _PY_LOCK_HANDLE_SIGNALS | _PY_LOCK_DETACH);
+ PyLockStatus r = _PyRecursiveMutex_LockTimed(
+ &self->lock, timeout,
+ _PY_LOCK_PYTHONLOCK | _PY_LOCK_HANDLE_SIGNALS | _PY_LOCK_DETACH);
if (r == PY_LOCK_INTR) {
+ assert(PyErr_Occurred());
+ return NULL;
+ }
+ if (r == PY_LOCK_FAILURE && PyErr_Occurred()) {
return NULL;
}
@@ -1365,9 +1375,7 @@ static void
localdummy_dealloc(PyObject *op)
{
localdummyobject *self = localdummyobject_CAST(op);
- if (self->weakreflist != NULL) {
- PyObject_ClearWeakRefs(op);
- }
+ FT_CLEAR_WEAKREFS(op, self->weakreflist);
PyTypeObject *tp = Py_TYPE(self);
tp->tp_free(self);
Py_DECREF(tp);
diff --git a/Modules/_zoneinfo.c b/Modules/_zoneinfo.c
index abd53436b21..5c5383d260a 100644
--- a/Modules/_zoneinfo.c
+++ b/Modules/_zoneinfo.c
@@ -7,6 +7,7 @@
#include "pycore_long.h" // _PyLong_GetOne()
#include "pycore_pyerrors.h" // _PyErr_ChainExceptions1()
#include "pycore_typeobject.h" // _PyType_GetModuleState()
+#include "pycore_weakref.h" // FT_CLEAR_WEAKREFS()
#include "datetime.h" // PyDateTime_TZInfo
@@ -375,9 +376,7 @@ zoneinfo_dealloc(PyObject *obj_self)
PyTypeObject *tp = Py_TYPE(self);
PyObject_GC_UnTrack(self);
- if (self->weakreflist != NULL) {
- PyObject_ClearWeakRefs(obj_self);
- }
+ FT_CLEAR_WEAKREFS(obj_self, self->weakreflist);
if (self->trans_list_utc != NULL) {
PyMem_Free(self->trans_list_utc);
diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c
index 401a3a7072b..5d07de2fba9 100644
--- a/Modules/arraymodule.c
+++ b/Modules/arraymodule.c
@@ -13,6 +13,7 @@
#include "pycore_ceval.h" // _PyEval_GetBuiltin()
#include "pycore_modsupport.h" // _PyArg_NoKeywords()
#include "pycore_moduleobject.h" // _PyModule_GetState()
+#include "pycore_weakref.h" // FT_CLEAR_WEAKREFS()
#include <stddef.h> // offsetof()
#include <stdbool.h>
@@ -728,9 +729,7 @@ array_dealloc(PyObject *op)
PyObject_GC_UnTrack(op);
arrayobject *self = arrayobject_CAST(op);
- if (self->weakreflist != NULL) {
- PyObject_ClearWeakRefs(op);
- }
+ FT_CLEAR_WEAKREFS(op, self->weakreflist);
if (self->ob_item != NULL) {
PyMem_Free(self->ob_item);
}
diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c
index 2003546ce84..cc1a5580015 100644
--- a/Modules/itertoolsmodule.c
+++ b/Modules/itertoolsmodule.c
@@ -1880,8 +1880,8 @@ chain_traverse(PyObject *op, visitproc visit, void *arg)
return 0;
}
-static PyObject *
-chain_next(PyObject *op)
+static inline PyObject *
+chain_next_lock_held(PyObject *op)
{
chainobject *lz = chainobject_CAST(op);
PyObject *item;
@@ -1919,6 +1919,16 @@ chain_next(PyObject *op)
return NULL;
}
+static PyObject *
+chain_next(PyObject *op)
+{
+ PyObject *result;
+ Py_BEGIN_CRITICAL_SECTION(op);
+ result = chain_next_lock_held(op);
+ Py_END_CRITICAL_SECTION()
+ return result;
+}
+
PyDoc_STRVAR(chain_doc,
"chain(*iterables)\n\
--\n\
@@ -2086,7 +2096,7 @@ product_traverse(PyObject *op, visitproc visit, void *arg)
}
static PyObject *
-product_next(PyObject *op)
+product_next_lock_held(PyObject *op)
{
productobject *lz = productobject_CAST(op);
PyObject *pool;
@@ -2172,6 +2182,16 @@ empty:
return NULL;
}
+static PyObject *
+product_next(PyObject *op)
+{
+ PyObject *result;
+ Py_BEGIN_CRITICAL_SECTION(op);
+ result = product_next_lock_held(op);
+ Py_END_CRITICAL_SECTION()
+ return result;
+}
+
static PyMethodDef product_methods[] = {
{"__sizeof__", product_sizeof, METH_NOARGS, sizeof_doc},
{NULL, NULL} /* sentinel */
@@ -2319,7 +2339,7 @@ combinations_traverse(PyObject *op, visitproc visit, void *arg)
}
static PyObject *
-combinations_next(PyObject *op)
+combinations_next_lock_held(PyObject *op)
{
combinationsobject *co = combinationsobject_CAST(op);
PyObject *elem;
@@ -2404,6 +2424,16 @@ empty:
return NULL;
}
+static PyObject *
+combinations_next(PyObject *op)
+{
+ PyObject *result;
+ Py_BEGIN_CRITICAL_SECTION(op);
+ result = combinations_next_lock_held(op);
+ Py_END_CRITICAL_SECTION()
+ return result;
+}
+
static PyMethodDef combinations_methods[] = {
{"__sizeof__", combinations_sizeof, METH_NOARGS, sizeof_doc},
{NULL, NULL} /* sentinel */
diff --git a/Modules/mmapmodule.c b/Modules/mmapmodule.c
index 7c4eb05488e..142ff1a2131 100644
--- a/Modules/mmapmodule.c
+++ b/Modules/mmapmodule.c
@@ -25,6 +25,7 @@
#include <Python.h>
#include "pycore_bytesobject.h" // _PyBytes_Find()
#include "pycore_fileutils.h" // _Py_stat_struct
+#include "pycore_weakref.h" // FT_CLEAR_WEAKREFS()
#include <stddef.h> // offsetof()
#ifndef MS_WINDOWS
@@ -163,8 +164,7 @@ mmap_object_dealloc(PyObject *op)
Py_END_ALLOW_THREADS
#endif /* UNIX */
- if (m_obj->weakreflist != NULL)
- PyObject_ClearWeakRefs(op);
+ FT_CLEAR_WEAKREFS(op, m_obj->weakreflist);
tp->tp_free(m_obj);
Py_DECREF(tp);
diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c
index fa153d86543..c449dd848d1 100644
--- a/Modules/pyexpat.c
+++ b/Modules/pyexpat.c
@@ -98,7 +98,11 @@ typedef struct {
#define CHARACTER_DATA_BUFFER_SIZE 8192
-typedef const void *xmlhandler;
+// A generic function type for storage.
+// To avoid undefined behaviors, a handler must be cast to the correct
+// function type before it's called; see SETTER_WRAPPER below.
+typedef void (*xmlhandler)(void);
+
typedef void (*xmlhandlersetter)(XML_Parser self, xmlhandler handler);
struct HandlerInfo {
@@ -110,9 +114,7 @@ struct HandlerInfo {
static struct HandlerInfo handler_info[64];
-// gh-111178: Use _Py_NO_SANITIZE_UNDEFINED, rather than using the exact
-// handler API for each handler.
-static inline void _Py_NO_SANITIZE_UNDEFINED
+static inline void
CALL_XML_HANDLER_SETTER(const struct HandlerInfo *handler_info,
XML_Parser xml_parser, xmlhandler xml_handler)
{
@@ -1365,7 +1367,7 @@ xmlparse_handler_setter(PyObject *op, PyObject *v, void *closure)
elaborate system of handlers and state could remove the
C handler more effectively. */
if (handlernum == CharacterData && self->in_callback) {
- c_handler = noop_character_data_handler;
+ c_handler = (xmlhandler)noop_character_data_handler;
}
v = NULL;
}
@@ -2222,13 +2224,84 @@ clear_handlers(xmlparseobject *self, int initial)
}
}
+/* To avoid undefined behaviors, a function must be *called* via a function
+ * pointer of the correct type.
+ * So, for each `XML_Set*` function, we define a wrapper that calls `XML_Set*`
+ * with its argument cast to the appropriate type.
+ */
+
+typedef void (*parser_only)(void *);
+typedef int (*not_standalone)(void *);
+typedef void (*parser_and_data)(void *, const XML_Char *);
+typedef void (*parser_and_data_and_int)(void *, const XML_Char *, int);
+typedef void (*parser_and_data_and_data)(
+ void *, const XML_Char *, const XML_Char *);
+typedef void (*start_element)(void *, const XML_Char *, const XML_Char **);
+typedef void (*element_decl)(void *, const XML_Char *, XML_Content *);
+typedef void (*xml_decl)(
+ void *, const XML_Char *, const XML_Char *, int);
+typedef void (*start_doctype_decl)(
+ void *, const XML_Char *, const XML_Char *, const XML_Char *, int);
+typedef void (*notation_decl)(
+ void *,
+ const XML_Char *, const XML_Char *, const XML_Char *, const XML_Char *);
+typedef void (*attlist_decl)(
+ void *,
+ const XML_Char *, const XML_Char *, const XML_Char *, const XML_Char *,
+ int);
+typedef void (*unparsed_entity_decl)(
+ void *,
+ const XML_Char *, const XML_Char *,
+ const XML_Char *, const XML_Char *, const XML_Char *);
+typedef void (*entity_decl)(
+ void *,
+ const XML_Char *, int,
+ const XML_Char *, int,
+ const XML_Char *, const XML_Char *, const XML_Char *, const XML_Char *);
+typedef int (*external_entity_ref)(
+ XML_Parser,
+ const XML_Char *, const XML_Char *, const XML_Char *, const XML_Char *);
+
+#define SETTER_WRAPPER(NAME, TYPE) \
+ static inline void \
+ pyexpat_Set ## NAME (XML_Parser parser, xmlhandler handler) \
+ { \
+ (void)XML_Set ## NAME (parser, (TYPE)handler); \
+ }
+
+SETTER_WRAPPER(StartElementHandler, start_element)
+SETTER_WRAPPER(EndElementHandler, parser_and_data)
+SETTER_WRAPPER(ProcessingInstructionHandler, parser_and_data_and_data)
+SETTER_WRAPPER(CharacterDataHandler, parser_and_data_and_int)
+SETTER_WRAPPER(UnparsedEntityDeclHandler, unparsed_entity_decl)
+SETTER_WRAPPER(NotationDeclHandler, notation_decl)
+SETTER_WRAPPER(StartNamespaceDeclHandler, parser_and_data_and_data)
+SETTER_WRAPPER(EndNamespaceDeclHandler, parser_and_data)
+SETTER_WRAPPER(CommentHandler, parser_and_data)
+SETTER_WRAPPER(StartCdataSectionHandler, parser_only)
+SETTER_WRAPPER(EndCdataSectionHandler, parser_only)
+SETTER_WRAPPER(DefaultHandler, parser_and_data_and_int)
+SETTER_WRAPPER(DefaultHandlerExpand, parser_and_data_and_int)
+SETTER_WRAPPER(NotStandaloneHandler, not_standalone)
+SETTER_WRAPPER(ExternalEntityRefHandler, external_entity_ref)
+SETTER_WRAPPER(StartDoctypeDeclHandler, start_doctype_decl)
+SETTER_WRAPPER(EndDoctypeDeclHandler, parser_only)
+SETTER_WRAPPER(EntityDeclHandler, entity_decl)
+SETTER_WRAPPER(XmlDeclHandler, xml_decl)
+SETTER_WRAPPER(ElementDeclHandler, element_decl)
+SETTER_WRAPPER(AttlistDeclHandler, attlist_decl)
+#if XML_COMBINED_VERSION >= 19504
+SETTER_WRAPPER(SkippedEntityHandler, parser_and_data_and_int)
+#endif
+#undef SETTER_WRAPPER
+
static struct HandlerInfo handler_info[] = {
// The cast to `xmlhandlersetter` is needed as the signature of XML
// handler functions is not compatible with `xmlhandlersetter` since
// their second parameter is narrower than a `const void *`.
#define HANDLER_INFO(name) \
- {#name, (xmlhandlersetter)XML_Set##name, my_##name},
+ {#name, (xmlhandlersetter)pyexpat_Set##name, (xmlhandler)my_##name},
HANDLER_INFO(StartElementHandler)
HANDLER_INFO(EndElementHandler)