Skip to content

Commit 4f05fc0

Browse files
carljmmiss-islington
authored andcommitted
pythongh-91051: fix segfault when using all 8 type watchers (pythonGH-107853)
(cherry picked from commit 66e4edd) Co-authored-by: Carl Meyer <[email protected]>
1 parent 98dd9d9 commit 4f05fc0

File tree

5 files changed

+18
-4
lines changed

5 files changed

+18
-4
lines changed

Doc/c-api/typeobj.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ Quick Reference
147147
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
148148
| :c:member:`~PyTypeObject.tp_vectorcall` | :c:type:`vectorcallfunc` | | | | | |
149149
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
150-
| [:c:member:`~PyTypeObject.tp_watched`] | char | | | | | |
150+
| [:c:member:`~PyTypeObject.tp_watched`] | unsigned char | | | | | |
151151
+------------------------------------------------+-----------------------------------+-------------------+---+---+---+---+
152152

153153
.. [#slots]
@@ -2141,7 +2141,7 @@ and :c:data:`PyType_Type` effectively act as defaults.)
21412141
.. versionadded:: 3.9 (the field exists since 3.8 but it's only used since 3.9)
21422142

21432143

2144-
.. c:member:: char PyTypeObject.tp_watched
2144+
.. c:member:: unsigned char PyTypeObject.tp_watched
21452145
21462146
Internal. Do not use.
21472147

Doc/includes/typestruct.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,5 +82,5 @@ typedef struct _typeobject {
8282
vectorcallfunc tp_vectorcall;
8383

8484
/* bitset of which type-watchers care about this type */
85-
char tp_watched;
85+
unsigned char tp_watched;
8686
} PyTypeObject;

Include/cpython/object.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ struct _typeobject {
227227
vectorcallfunc tp_vectorcall;
228228

229229
/* bitset of which type-watchers care about this type */
230-
char tp_watched;
230+
unsigned char tp_watched;
231231
};
232232

233233
/* This struct is used by the specializer

Lib/test/test_capi/test_watchers.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,18 @@ class C2: pass
294294
C2.hmm = "baz"
295295
self.assert_events([C1, [C2]])
296296

297+
def test_all_watchers(self):
298+
class C: pass
299+
with ExitStack() as stack:
300+
last_wid = -1
301+
# don't make assumptions about how many watchers are already
302+
# registered, just go until we reach the max ID
303+
while last_wid < self.TYPE_MAX_WATCHERS - 1:
304+
last_wid = stack.enter_context(self.watcher())
305+
self.watch(last_wid, C)
306+
C.foo = "bar"
307+
self.assert_events([C])
308+
297309
def test_watch_non_type(self):
298310
with self.watcher() as wid:
299311
with self.assertRaisesRegex(ValueError, r"Cannot watch non-type"):
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix abort / segfault when using all eight type watcher slots, on platforms
2+
where ``char`` is signed by default.

0 commit comments

Comments
 (0)