1 #ifndef Py_CPYTHON_OBJECT_H
2 # error "this header file must not be included directly"
3 #endif
4
5 PyAPI_FUNC(void) _Py_NewReference(PyObject *op);
6 PyAPI_FUNC(void) _Py_NewReferenceNoTotal(PyObject *op);
7
8 #ifdef Py_TRACE_REFS
9 /* Py_TRACE_REFS is such major surgery that we call external routines. */
10 PyAPI_FUNC(void) _Py_ForgetReference(PyObject *);
11 #endif
12
13 #ifdef Py_REF_DEBUG
14 /* These are useful as debugging aids when chasing down refleaks. */
15 PyAPI_FUNC(Py_ssize_t) _Py_GetGlobalRefTotal(void);
16 # define _Py_GetRefTotal() _Py_GetGlobalRefTotal()
17 PyAPI_FUNC(Py_ssize_t) _Py_GetLegacyRefTotal(void);
18 PyAPI_FUNC(Py_ssize_t) _PyInterpreterState_GetRefTotal(PyInterpreterState *);
19 #endif
20
21
22 /********************* String Literals ****************************************/
23 /* This structure helps managing static strings. The basic usage goes like this:
24 Instead of doing
25
26 r = PyObject_CallMethod(o, "foo", "args", ...);
27
28 do
29
30 _Py_IDENTIFIER(foo);
31 ...
32 r = _PyObject_CallMethodId(o, &PyId_foo, "args", ...);
33
34 PyId_foo is a static variable, either on block level or file level. On first
35 usage, the string "foo" is interned, and the structures are linked. On interpreter
36 shutdown, all strings are released.
37
38 Alternatively, _Py_static_string allows choosing the variable name.
39 _PyUnicode_FromId returns a borrowed reference to the interned string.
40 _PyObject_{Get,Set,Has}AttrId are __getattr__ versions using _Py_Identifier*.
41 */
42 typedef struct _Py_Identifier {
43 const char* string;
44 // Index in PyInterpreterState.unicode.ids.array. It is process-wide
45 // unique and must be initialized to -1.
46 Py_ssize_t index;
47 } _Py_Identifier;
48
49 #ifndef Py_BUILD_CORE
50 // For now we are keeping _Py_IDENTIFIER for continued use
51 // in non-builtin extensions (and naughty PyPI modules).
52
53 #define _Py_static_string_init(value) { .string = (value), .index = -1 }
54 #define _Py_static_string(varname, value) static _Py_Identifier varname = _Py_static_string_init(value)
55 #define _Py_IDENTIFIER(varname) _Py_static_string(PyId_##varname, #varname)
56
57 #endif /* !Py_BUILD_CORE */
58
59 typedef struct {
60 /* Number implementations must check *both*
61 arguments for proper type and implement the necessary conversions
62 in the slot functions themselves. */
63
64 binaryfunc nb_add;
65 binaryfunc nb_subtract;
66 binaryfunc nb_multiply;
67 binaryfunc nb_remainder;
68 binaryfunc nb_divmod;
69 ternaryfunc nb_power;
70 unaryfunc nb_negative;
71 unaryfunc nb_positive;
72 unaryfunc nb_absolute;
73 inquiry nb_bool;
74 unaryfunc nb_invert;
75 binaryfunc nb_lshift;
76 binaryfunc nb_rshift;
77 binaryfunc nb_and;
78 binaryfunc nb_xor;
79 binaryfunc nb_or;
80 unaryfunc nb_int;
81 void *nb_reserved; /* the slot formerly known as nb_long */
82 unaryfunc nb_float;
83
84 binaryfunc nb_inplace_add;
85 binaryfunc nb_inplace_subtract;
86 binaryfunc nb_inplace_multiply;
87 binaryfunc nb_inplace_remainder;
88 ternaryfunc nb_inplace_power;
89 binaryfunc nb_inplace_lshift;
90 binaryfunc nb_inplace_rshift;
91 binaryfunc nb_inplace_and;
92 binaryfunc nb_inplace_xor;
93 binaryfunc nb_inplace_or;
94
95 binaryfunc nb_floor_divide;
96 binaryfunc nb_true_divide;
97 binaryfunc nb_inplace_floor_divide;
98 binaryfunc nb_inplace_true_divide;
99
100 unaryfunc nb_index;
101
102 binaryfunc nb_matrix_multiply;
103 binaryfunc nb_inplace_matrix_multiply;
104 } PyNumberMethods;
105
106 typedef struct {
107 lenfunc sq_length;
108 binaryfunc sq_concat;
109 ssizeargfunc sq_repeat;
110 ssizeargfunc sq_item;
111 void *was_sq_slice;
112 ssizeobjargproc sq_ass_item;
113 void *was_sq_ass_slice;
114 objobjproc sq_contains;
115
116 binaryfunc sq_inplace_concat;
117 ssizeargfunc sq_inplace_repeat;
118 } PySequenceMethods;
119
120 typedef struct {
121 lenfunc mp_length;
122 binaryfunc mp_subscript;
123 objobjargproc mp_ass_subscript;
124 } PyMappingMethods;
125
126 typedef PySendResult (*sendfunc)(PyObject *iter, PyObject *value, PyObject **result);
127
128 typedef struct {
129 unaryfunc am_await;
130 unaryfunc am_aiter;
131 unaryfunc am_anext;
132 sendfunc am_send;
133 } PyAsyncMethods;
134
135 typedef struct {
136 getbufferproc bf_getbuffer;
137 releasebufferproc bf_releasebuffer;
138 } PyBufferProcs;
139
140 /* Allow printfunc in the tp_vectorcall_offset slot for
141 * backwards-compatibility */
142 typedef Py_ssize_t printfunc;
143
144 // If this structure is modified, Doc/includes/typestruct.h should be updated
145 // as well.
146 struct _typeobject {
147 PyObject_VAR_HEAD
148 const char *tp_name; /* For printing, in format "<module>.<name>" */
149 Py_ssize_t tp_basicsize, tp_itemsize; /* For allocation */
150
151 /* Methods to implement standard operations */
152
153 destructor tp_dealloc;
154 Py_ssize_t tp_vectorcall_offset;
155 getattrfunc tp_getattr;
156 setattrfunc tp_setattr;
157 PyAsyncMethods *tp_as_async; /* formerly known as tp_compare (Python 2)
158 or tp_reserved (Python 3) */
159 reprfunc tp_repr;
160
161 /* Method suites for standard classes */
162
163 PyNumberMethods *tp_as_number;
164 PySequenceMethods *tp_as_sequence;
165 PyMappingMethods *tp_as_mapping;
166
167 /* More standard operations (here for binary compatibility) */
168
169 hashfunc tp_hash;
170 ternaryfunc tp_call;
171 reprfunc tp_str;
172 getattrofunc tp_getattro;
173 setattrofunc tp_setattro;
174
175 /* Functions to access object as input/output buffer */
176 PyBufferProcs *tp_as_buffer;
177
178 /* Flags to define presence of optional/expanded features */
179 unsigned long tp_flags;
180
181 const char *tp_doc; /* Documentation string */
182
183 /* Assigned meaning in release 2.0 */
184 /* call function for all accessible objects */
185 traverseproc tp_traverse;
186
187 /* delete references to contained objects */
188 inquiry tp_clear;
189
190 /* Assigned meaning in release 2.1 */
191 /* rich comparisons */
192 richcmpfunc tp_richcompare;
193
194 /* weak reference enabler */
195 Py_ssize_t tp_weaklistoffset;
196
197 /* Iterators */
198 getiterfunc tp_iter;
199 iternextfunc tp_iternext;
200
201 /* Attribute descriptor and subclassing stuff */
202 PyMethodDef *tp_methods;
203 PyMemberDef *tp_members;
204 PyGetSetDef *tp_getset;
205 // Strong reference on a heap type, borrowed reference on a static type
206 PyTypeObject *tp_base;
207 PyObject *tp_dict;
208 descrgetfunc tp_descr_get;
209 descrsetfunc tp_descr_set;
210 Py_ssize_t tp_dictoffset;
211 initproc tp_init;
212 allocfunc tp_alloc;
213 newfunc tp_new;
214 freefunc tp_free; /* Low-level free-memory routine */
215 inquiry tp_is_gc; /* For PyObject_IS_GC */
216 PyObject *tp_bases;
217 PyObject *tp_mro; /* method resolution order */
218 PyObject *tp_cache; /* no longer used */
219 void *tp_subclasses; /* for static builtin types this is an index */
220 PyObject *tp_weaklist; /* not used for static builtin types */
221 destructor tp_del;
222
223 /* Type attribute cache version tag. Added in version 2.6 */
224 unsigned int tp_version_tag;
225
226 destructor tp_finalize;
227 vectorcallfunc tp_vectorcall;
228
229 /* bitset of which type-watchers care about this type */
230 unsigned char tp_watched;
231 };
232
233 /* This struct is used by the specializer
234 * It should should be treated as an opaque blob
235 * by code other than the specializer and interpreter. */
236 struct _specialization_cache {
237 // In order to avoid bloating the bytecode with lots of inline caches, the
238 // members of this structure have a somewhat unique contract. They are set
239 // by the specialization machinery, and are invalidated by PyType_Modified.
240 // The rules for using them are as follows:
241 // - If getitem is non-NULL, then it is the same Python function that
242 // PyType_Lookup(cls, "__getitem__") would return.
243 // - If getitem is NULL, then getitem_version is meaningless.
244 // - If getitem->func_version == getitem_version, then getitem can be called
245 // with two positional arguments and no keyword arguments, and has neither
246 // *args nor **kwargs (as required by BINARY_SUBSCR_GETITEM):
247 PyObject *getitem;
248 uint32_t getitem_version;
249 };
250
251 /* The *real* layout of a type object when allocated on the heap */
252 typedef struct _heaptypeobject {
253 /* Note: there's a dependency on the order of these members
254 in slotptr() in typeobject.c . */
255 PyTypeObject ht_type;
256 PyAsyncMethods as_async;
257 PyNumberMethods as_number;
258 PyMappingMethods as_mapping;
259 PySequenceMethods as_sequence; /* as_sequence comes after as_mapping,
260 so that the mapping wins when both
261 the mapping and the sequence define
262 a given operator (e.g. __getitem__).
263 see add_operators() in typeobject.c . */
264 PyBufferProcs as_buffer;
265 PyObject *ht_name, *ht_slots, *ht_qualname;
266 struct _dictkeysobject *ht_cached_keys;
267 PyObject *ht_module;
268 char *_ht_tpname; // Storage for "tp_name"; see PyType_FromModuleAndSpec
269 struct _specialization_cache _spec_cache; // For use by the specializer.
270 /* here are optional user slots, followed by the members. */
271 } PyHeapTypeObject;
272
273 PyAPI_FUNC(const char *) _PyType_Name(PyTypeObject *);
274 PyAPI_FUNC(PyObject *) _PyType_Lookup(PyTypeObject *, PyObject *);
275 PyAPI_FUNC(PyObject *) _PyType_LookupId(PyTypeObject *, _Py_Identifier *);
276 PyAPI_FUNC(PyObject *) _PyObject_LookupSpecialId(PyObject *, _Py_Identifier *);
277 #ifndef Py_BUILD_CORE
278 // Backward compatibility for 3rd-party extensions
279 // that may be using the old name.
280 #define _PyObject_LookupSpecial _PyObject_LookupSpecialId
281 #endif
282 PyAPI_FUNC(PyTypeObject *) _PyType_CalculateMetaclass(PyTypeObject *, PyObject *);
283 PyAPI_FUNC(PyObject *) _PyType_GetDocFromInternalDoc(const char *, const char *);
284 PyAPI_FUNC(PyObject *) _PyType_GetTextSignatureFromInternalDoc(const char *, const char *);
285 PyAPI_FUNC(PyObject *) PyType_GetModuleByDef(PyTypeObject *, PyModuleDef *);
286 PyAPI_FUNC(PyObject *) PyType_GetDict(PyTypeObject *);
287
288 PyAPI_FUNC(int) PyObject_Print(PyObject *, FILE *, int);
289 PyAPI_FUNC(void) _Py_BreakPoint(void);
290 PyAPI_FUNC(void) _PyObject_Dump(PyObject *);
291 PyAPI_FUNC(int) _PyObject_IsFreed(PyObject *);
292
293 PyAPI_FUNC(int) _PyObject_IsAbstract(PyObject *);
294 PyAPI_FUNC(PyObject *) _PyObject_GetAttrId(PyObject *, _Py_Identifier *);
295 PyAPI_FUNC(int) _PyObject_SetAttrId(PyObject *, _Py_Identifier *, PyObject *);
296 /* Replacements of PyObject_GetAttr() and _PyObject_GetAttrId() which
297 don't raise AttributeError.
298
299 Return 1 and set *result != NULL if an attribute is found.
300 Return 0 and set *result == NULL if an attribute is not found;
301 an AttributeError is silenced.
302 Return -1 and set *result == NULL if an error other than AttributeError
303 is raised.
304 */
305 PyAPI_FUNC(int) _PyObject_LookupAttr(PyObject *, PyObject *, PyObject **);
306 PyAPI_FUNC(int) _PyObject_LookupAttrId(PyObject *, _Py_Identifier *, PyObject **);
307
308 PyAPI_FUNC(int) _PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method);
309
310 PyAPI_FUNC(PyObject **) _PyObject_GetDictPtr(PyObject *);
311 PyAPI_FUNC(PyObject *) _PyObject_NextNotImplemented(PyObject *);
312 PyAPI_FUNC(void) PyObject_CallFinalizer(PyObject *);
313 PyAPI_FUNC(int) PyObject_CallFinalizerFromDealloc(PyObject *);
314
315 /* Same as PyObject_Generic{Get,Set}Attr, but passing the attributes
316 dict as the last parameter. */
317 PyAPI_FUNC(PyObject *)
318 _PyObject_GenericGetAttrWithDict(PyObject *, PyObject *, PyObject *, int);
319 PyAPI_FUNC(int)
320 _PyObject_GenericSetAttrWithDict(PyObject *, PyObject *,
321 PyObject *, PyObject *);
322
323 PyAPI_FUNC(PyObject *) _PyObject_FunctionStr(PyObject *);
324
325 /* Safely decref `dst` and set `dst` to `src`.
326 *
327 * As in case of Py_CLEAR "the obvious" code can be deadly:
328 *
329 * Py_DECREF(dst);
330 * dst = src;
331 *
332 * The safe way is:
333 *
334 * Py_SETREF(dst, src);
335 *
336 * That arranges to set `dst` to `src` _before_ decref'ing, so that any code
337 * triggered as a side-effect of `dst` getting torn down no longer believes
338 * `dst` points to a valid object.
339 *
340 * Temporary variables are used to only evalutate macro arguments once and so
341 * avoid the duplication of side effects. _Py_TYPEOF() or memcpy() is used to
342 * avoid a miscompilation caused by type punning. See Py_CLEAR() comment for
343 * implementation details about type punning.
344 *
345 * The memcpy() implementation does not emit a compiler warning if 'src' has
346 * not the same type than 'src': any pointer type is accepted for 'src'.
347 */
348 #ifdef _Py_TYPEOF
349 #define Py_SETREF(dst, src) \
350 do { \
351 _Py_TYPEOF(dst)* _tmp_dst_ptr = &(dst); \
352 _Py_TYPEOF(dst) _tmp_old_dst = (*_tmp_dst_ptr); \
353 *_tmp_dst_ptr = (src); \
354 Py_DECREF(_tmp_old_dst); \
355 } while (0)
356 #else
357 #define Py_SETREF(dst, src) \
358 do { \
359 PyObject **_tmp_dst_ptr = _Py_CAST(PyObject**, &(dst)); \
360 PyObject *_tmp_old_dst = (*_tmp_dst_ptr); \
361 PyObject *_tmp_src = _PyObject_CAST(src); \
362 memcpy(_tmp_dst_ptr, &_tmp_src, sizeof(PyObject*)); \
363 Py_DECREF(_tmp_old_dst); \
364 } while (0)
365 #endif
366
367 /* Py_XSETREF() is a variant of Py_SETREF() that uses Py_XDECREF() instead of
368 * Py_DECREF().
369 */
370 #ifdef _Py_TYPEOF
371 #define Py_XSETREF(dst, src) \
372 do { \
373 _Py_TYPEOF(dst)* _tmp_dst_ptr = &(dst); \
374 _Py_TYPEOF(dst) _tmp_old_dst = (*_tmp_dst_ptr); \
375 *_tmp_dst_ptr = (src); \
376 Py_XDECREF(_tmp_old_dst); \
377 } while (0)
378 #else
379 #define Py_XSETREF(dst, src) \
380 do { \
381 PyObject **_tmp_dst_ptr = _Py_CAST(PyObject**, &(dst)); \
382 PyObject *_tmp_old_dst = (*_tmp_dst_ptr); \
383 PyObject *_tmp_src = _PyObject_CAST(src); \
384 memcpy(_tmp_dst_ptr, &_tmp_src, sizeof(PyObject*)); \
385 Py_XDECREF(_tmp_old_dst); \
386 } while (0)
387 #endif
388
389
390 PyAPI_DATA(PyTypeObject) _PyNone_Type;
391 PyAPI_DATA(PyTypeObject) _PyNotImplemented_Type;
392
393 /* Maps Py_LT to Py_GT, ..., Py_GE to Py_LE.
394 * Defined in object.c.
395 */
396 PyAPI_DATA(int) _Py_SwappedOp[];
397
398 PyAPI_FUNC(void)
399 _PyDebugAllocatorStats(FILE *out, const char *block_name, int num_blocks,
400 size_t sizeof_block);
401 PyAPI_FUNC(void)
402 _PyObject_DebugTypeStats(FILE *out);
403
404 /* Define a pair of assertion macros:
405 _PyObject_ASSERT_FROM(), _PyObject_ASSERT_WITH_MSG() and _PyObject_ASSERT().
406
407 These work like the regular C assert(), in that they will abort the
408 process with a message on stderr if the given condition fails to hold,
409 but compile away to nothing if NDEBUG is defined.
410
411 However, before aborting, Python will also try to call _PyObject_Dump() on
412 the given object. This may be of use when investigating bugs in which a
413 particular object is corrupt (e.g. buggy a tp_visit method in an extension
414 module breaking the garbage collector), to help locate the broken objects.
415
416 The WITH_MSG variant allows you to supply an additional message that Python
417 will attempt to print to stderr, after the object dump. */
418 #ifdef NDEBUG
419 /* No debugging: compile away the assertions: */
420 # define _PyObject_ASSERT_FROM(obj, expr, msg, filename, lineno, func) \
421 ((void)0)
422 #else
423 /* With debugging: generate checks: */
424 # define _PyObject_ASSERT_FROM(obj, expr, msg, filename, lineno, func) \
425 ((expr) \
426 ? (void)(0) \
427 : _PyObject_AssertFailed((obj), Py_STRINGIFY(expr), \
428 (msg), (filename), (lineno), (func)))
429 #endif
430
431 #define _PyObject_ASSERT_WITH_MSG(obj, expr, msg) \
432 _PyObject_ASSERT_FROM((obj), expr, (msg), __FILE__, __LINE__, __func__)
433 #define _PyObject_ASSERT(obj, expr) \
434 _PyObject_ASSERT_WITH_MSG((obj), expr, NULL)
435
436 #define _PyObject_ASSERT_FAILED_MSG(obj, msg) \
437 _PyObject_AssertFailed((obj), NULL, (msg), __FILE__, __LINE__, __func__)
438
439 /* Declare and define _PyObject_AssertFailed() even when NDEBUG is defined,
440 to avoid causing compiler/linker errors when building extensions without
441 NDEBUG against a Python built with NDEBUG defined.
442
443 msg, expr and function can be NULL. */
444 PyAPI_FUNC(void) _Py_NO_RETURN _PyObject_AssertFailed(
445 PyObject *obj,
446 const char *expr,
447 const char *msg,
448 const char *file,
449 int line,
450 const char *function);
451
452 /* Check if an object is consistent. For example, ensure that the reference
453 counter is greater than or equal to 1, and ensure that ob_type is not NULL.
454
455 Call _PyObject_AssertFailed() if the object is inconsistent.
456
457 If check_content is zero, only check header fields: reduce the overhead.
458
459 The function always return 1. The return value is just here to be able to
460 write:
461
462 assert(_PyObject_CheckConsistency(obj, 1)); */
463 PyAPI_FUNC(int) _PyObject_CheckConsistency(
464 PyObject *op,
465 int check_content);
466
467
468 /* Trashcan mechanism, thanks to Christian Tismer.
469
470 When deallocating a container object, it's possible to trigger an unbounded
471 chain of deallocations, as each Py_DECREF in turn drops the refcount on "the
472 next" object in the chain to 0. This can easily lead to stack overflows,
473 especially in threads (which typically have less stack space to work with).
474
475 A container object can avoid this by bracketing the body of its tp_dealloc
476 function with a pair of macros:
477
478 static void
479 mytype_dealloc(mytype *p)
480 {
481 ... declarations go here ...
482
483 PyObject_GC_UnTrack(p); // must untrack first
484 Py_TRASHCAN_BEGIN(p, mytype_dealloc)
485 ... The body of the deallocator goes here, including all calls ...
486 ... to Py_DECREF on contained objects. ...
487 Py_TRASHCAN_END // there should be no code after this
488 }
489
490 CAUTION: Never return from the middle of the body! If the body needs to
491 "get out early", put a label immediately before the Py_TRASHCAN_END
492 call, and goto it. Else the call-depth counter (see below) will stay
493 above 0 forever, and the trashcan will never get emptied.
494
495 How it works: The BEGIN macro increments a call-depth counter. So long
496 as this counter is small, the body of the deallocator is run directly without
497 further ado. But if the counter gets large, it instead adds p to a list of
498 objects to be deallocated later, skips the body of the deallocator, and
499 resumes execution after the END macro. The tp_dealloc routine then returns
500 without deallocating anything (and so unbounded call-stack depth is avoided).
501
502 When the call stack finishes unwinding again, code generated by the END macro
503 notices this, and calls another routine to deallocate all the objects that
504 may have been added to the list of deferred deallocations. In effect, a
505 chain of N deallocations is broken into (N-1)/(_PyTrash_UNWIND_LEVEL-1) pieces,
506 with the call stack never exceeding a depth of _PyTrash_UNWIND_LEVEL.
507
508 Since the tp_dealloc of a subclass typically calls the tp_dealloc of the base
509 class, we need to ensure that the trashcan is only triggered on the tp_dealloc
510 of the actual class being deallocated. Otherwise we might end up with a
511 partially-deallocated object. To check this, the tp_dealloc function must be
512 passed as second argument to Py_TRASHCAN_BEGIN().
513 */
514
515 /* Python 3.9 private API, invoked by the macros below. */
516 PyAPI_FUNC(int) _PyTrash_begin(PyThreadState *tstate, PyObject *op);
517 PyAPI_FUNC(void) _PyTrash_end(PyThreadState *tstate);
518 /* Python 3.10 private API, invoked by the Py_TRASHCAN_BEGIN(). */
519 PyAPI_FUNC(int) _PyTrash_cond(PyObject *op, destructor dealloc);
520
521 #define Py_TRASHCAN_BEGIN_CONDITION(op, cond) \
522 do { \
523 PyThreadState *_tstate = NULL; \
524 /* If "cond" is false, then _tstate remains NULL and the deallocator \
525 * is run normally without involving the trashcan */ \
526 if (cond) { \
527 _tstate = _PyThreadState_UncheckedGet(); \
528 if (_PyTrash_begin(_tstate, _PyObject_CAST(op))) { \
529 break; \
530 } \
531 }
532 /* The body of the deallocator is here. */
533 #define Py_TRASHCAN_END \
534 if (_tstate) { \
535 _PyTrash_end(_tstate); \
536 } \
537 } while (0);
538
539 #define Py_TRASHCAN_BEGIN(op, dealloc) \
540 Py_TRASHCAN_BEGIN_CONDITION((op), \
541 _PyTrash_cond(_PyObject_CAST(op), (destructor)(dealloc)))
542
543 /* The following two macros, Py_TRASHCAN_SAFE_BEGIN and
544 * Py_TRASHCAN_SAFE_END, are deprecated since version 3.11 and
545 * will be removed in the future.
546 * Use Py_TRASHCAN_BEGIN and Py_TRASHCAN_END instead.
547 */
548 Py_DEPRECATED(3.11) typedef int UsingDeprecatedTrashcanMacro;
549 #define Py_TRASHCAN_SAFE_BEGIN(op) \
550 do { \
551 UsingDeprecatedTrashcanMacro cond=1; \
552 Py_TRASHCAN_BEGIN_CONDITION((op), cond);
553 #define Py_TRASHCAN_SAFE_END(op) \
554 Py_TRASHCAN_END; \
555 } while(0);
556
557 PyAPI_FUNC(void *) PyObject_GetItemData(PyObject *obj);
558
559 PyAPI_FUNC(int) _PyObject_VisitManagedDict(PyObject *obj, visitproc visit, void *arg);
560 PyAPI_FUNC(void) _PyObject_ClearManagedDict(PyObject *obj);
561
562 #define TYPE_MAX_WATCHERS 8
563
564 typedef int(*PyType_WatchCallback)(PyTypeObject *);
565 PyAPI_FUNC(int) PyType_AddWatcher(PyType_WatchCallback callback);
566 PyAPI_FUNC(int) PyType_ClearWatcher(int watcher_id);
567 PyAPI_FUNC(int) PyType_Watch(int watcher_id, PyObject *type);
568 PyAPI_FUNC(int) PyType_Unwatch(int watcher_id, PyObject *type);
569
570 /* Attempt to assign a version tag to the given type.
571 *
572 * Returns 1 if the type already had a valid version tag or a new one was
573 * assigned, or 0 if a new tag could not be assigned.
574 */
575 PyAPI_FUNC(int) PyUnstable_Type_AssignVersionTag(PyTypeObject *type);