• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef Py_CPYTHON_DICTOBJECT_H
2 #  error "this header file must not be included directly"
3 #endif
4 
5 typedef struct _dictkeysobject PyDictKeysObject;
6 typedef struct _dictvalues PyDictValues;
7 
8 /* The ma_values pointer is NULL for a combined table
9  * or points to an array of PyObject* for a split table
10  */
11 typedef struct {
12     PyObject_HEAD
13 
14     /* Number of items in the dictionary */
15     Py_ssize_t ma_used;
16 
17     /* Dictionary version: globally unique, value change each time
18        the dictionary is modified */
19 #ifdef Py_BUILD_CORE
20     /* Bits 0-7 are for dict watchers.
21      * Bits 8-11 are for the watched mutation counter (used by tier2 optimization)
22      * The remaining bits (12-63) are the actual version tag. */
23     uint64_t ma_version_tag;
24 #else
25     Py_DEPRECATED(3.12) uint64_t ma_version_tag;
26 #endif
27 
28     PyDictKeysObject *ma_keys;
29 
30     /* If ma_values is NULL, the table is "combined": keys and values
31        are stored in ma_keys.
32 
33        If ma_values is not NULL, the table is split:
34        keys are stored in ma_keys and values are stored in ma_values */
35     PyDictValues *ma_values;
36 } PyDictObject;
37 
38 PyAPI_FUNC(PyObject *) _PyDict_GetItem_KnownHash(PyObject *mp, PyObject *key,
39                                                  Py_hash_t hash);
40 PyAPI_FUNC(PyObject *) _PyDict_GetItemStringWithError(PyObject *, const char *);
41 PyAPI_FUNC(PyObject *) PyDict_SetDefault(
42     PyObject *mp, PyObject *key, PyObject *defaultobj);
43 
44 // Inserts `key` with a value `default_value`, if `key` is not already present
45 // in the dictionary.  If `result` is not NULL, then the value associated
46 // with `key` is returned in `*result` (either the existing value, or the now
47 // inserted `default_value`).
48 // Returns:
49 //   -1 on error
50 //    0 if `key` was not present and `default_value` was inserted
51 //    1 if `key` was present and `default_value` was not inserted
52 PyAPI_FUNC(int) PyDict_SetDefaultRef(PyObject *mp, PyObject *key, PyObject *default_value, PyObject **result);
53 
54 /* Get the number of items of a dictionary. */
PyDict_GET_SIZE(PyObject * op)55 static inline Py_ssize_t PyDict_GET_SIZE(PyObject *op) {
56     PyDictObject *mp;
57     assert(PyDict_Check(op));
58     mp = _Py_CAST(PyDictObject*, op);
59 #ifdef Py_GIL_DISABLED
60     return _Py_atomic_load_ssize_relaxed(&mp->ma_used);
61 #else
62     return mp->ma_used;
63 #endif
64 }
65 #define PyDict_GET_SIZE(op) PyDict_GET_SIZE(_PyObject_CAST(op))
66 
67 PyAPI_FUNC(int) PyDict_ContainsString(PyObject *mp, const char *key);
68 
69 PyAPI_FUNC(PyObject *) _PyDict_NewPresized(Py_ssize_t minused);
70 
71 PyAPI_FUNC(int) PyDict_Pop(PyObject *dict, PyObject *key, PyObject **result);
72 PyAPI_FUNC(int) PyDict_PopString(PyObject *dict, const char *key, PyObject **result);
73 PyAPI_FUNC(PyObject *) _PyDict_Pop(PyObject *dict, PyObject *key, PyObject *default_value);
74 
75 /* Dictionary watchers */
76 
77 #define PY_FOREACH_DICT_EVENT(V) \
78     V(ADDED)                     \
79     V(MODIFIED)                  \
80     V(DELETED)                   \
81     V(CLONED)                    \
82     V(CLEARED)                   \
83     V(DEALLOCATED)
84 
85 typedef enum {
86     #define PY_DEF_EVENT(EVENT) PyDict_EVENT_##EVENT,
87     PY_FOREACH_DICT_EVENT(PY_DEF_EVENT)
88     #undef PY_DEF_EVENT
89 } PyDict_WatchEvent;
90 
91 // Callback to be invoked when a watched dict is cleared, dealloced, or modified.
92 // In clear/dealloc case, key and new_value will be NULL. Otherwise, new_value will be the
93 // new value for key, NULL if key is being deleted.
94 typedef int(*PyDict_WatchCallback)(PyDict_WatchEvent event, PyObject* dict, PyObject* key, PyObject* new_value);
95 
96 // Register/unregister a dict-watcher callback
97 PyAPI_FUNC(int) PyDict_AddWatcher(PyDict_WatchCallback callback);
98 PyAPI_FUNC(int) PyDict_ClearWatcher(int watcher_id);
99 
100 // Mark given dictionary as "watched" (callback will be called if it is modified)
101 PyAPI_FUNC(int) PyDict_Watch(int watcher_id, PyObject* dict);
102 PyAPI_FUNC(int) PyDict_Unwatch(int watcher_id, PyObject* dict);
103