Skip to content

Commit ffedd9a

Browse files
authored
bpo-35134: Create Include/cpython/dictobject.h (GH-10732)
* Move dictobject.h code surrounded by "#ifndef Py_LIMITED_API" to a new Include/cpython/dictobject.h header file. * Add PyAPI_FUNC() to _PyDictView_New(). * Reorganize dictobject.h: move views and iterators at the end.
1 parent dd12aa0 commit ffedd9a

File tree

2 files changed

+124
-119
lines changed

2 files changed

+124
-119
lines changed

Include/cpython/dictobject.h

+93
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
#ifndef Py_CPYTHON_DICTOBJECT_H
2+
# error "this header file must not be included directly"
3+
#endif
4+
5+
#ifdef __cplusplus
6+
extern "C" {
7+
#endif
8+
9+
typedef struct _dictkeysobject PyDictKeysObject;
10+
11+
/* The ma_values pointer is NULL for a combined table
12+
* or points to an array of PyObject* for a split table
13+
*/
14+
typedef struct {
15+
PyObject_HEAD
16+
17+
/* Number of items in the dictionary */
18+
Py_ssize_t ma_used;
19+
20+
/* Dictionary version: globally unique, value change each time
21+
the dictionary is modified */
22+
uint64_t ma_version_tag;
23+
24+
PyDictKeysObject *ma_keys;
25+
26+
/* If ma_values is NULL, the table is "combined": keys and values
27+
are stored in ma_keys.
28+
29+
If ma_values is not NULL, the table is splitted:
30+
keys are stored in ma_keys and values are stored in ma_values */
31+
PyObject **ma_values;
32+
} PyDictObject;
33+
34+
PyAPI_FUNC(PyObject *) _PyDict_GetItem_KnownHash(PyObject *mp, PyObject *key,
35+
Py_hash_t hash);
36+
PyAPI_FUNC(PyObject *) _PyDict_GetItemIdWithError(PyObject *dp,
37+
struct _Py_Identifier *key);
38+
PyAPI_FUNC(PyObject *) PyDict_SetDefault(
39+
PyObject *mp, PyObject *key, PyObject *defaultobj);
40+
PyAPI_FUNC(int) _PyDict_SetItem_KnownHash(PyObject *mp, PyObject *key,
41+
PyObject *item, Py_hash_t hash);
42+
PyAPI_FUNC(int) _PyDict_DelItem_KnownHash(PyObject *mp, PyObject *key,
43+
Py_hash_t hash);
44+
PyAPI_FUNC(int) _PyDict_DelItemIf(PyObject *mp, PyObject *key,
45+
int (*predicate)(PyObject *value));
46+
PyDictKeysObject *_PyDict_NewKeysForClass(void);
47+
PyAPI_FUNC(PyObject *) PyObject_GenericGetDict(PyObject *, void *);
48+
PyAPI_FUNC(int) _PyDict_Next(
49+
PyObject *mp, Py_ssize_t *pos, PyObject **key, PyObject **value, Py_hash_t *hash);
50+
51+
/* Get the number of items of a dictionary. */
52+
#define PyDict_GET_SIZE(mp) (assert(PyDict_Check(mp)),((PyDictObject *)mp)->ma_used)
53+
PyAPI_FUNC(int) _PyDict_Contains(PyObject *mp, PyObject *key, Py_hash_t hash);
54+
PyAPI_FUNC(PyObject *) _PyDict_NewPresized(Py_ssize_t minused);
55+
PyAPI_FUNC(void) _PyDict_MaybeUntrack(PyObject *mp);
56+
PyAPI_FUNC(int) _PyDict_HasOnlyStringKeys(PyObject *mp);
57+
Py_ssize_t _PyDict_KeysSize(PyDictKeysObject *keys);
58+
PyAPI_FUNC(Py_ssize_t) _PyDict_SizeOf(PyDictObject *);
59+
PyAPI_FUNC(PyObject *) _PyDict_Pop(PyObject *, PyObject *, PyObject *);
60+
PyObject *_PyDict_Pop_KnownHash(PyObject *, PyObject *, Py_hash_t, PyObject *);
61+
PyObject *_PyDict_FromKeys(PyObject *, PyObject *, PyObject *);
62+
#define _PyDict_HasSplitTable(d) ((d)->ma_values != NULL)
63+
64+
PyAPI_FUNC(int) PyDict_ClearFreeList(void);
65+
66+
/* Like PyDict_Merge, but override can be 0, 1 or 2. If override is 0,
67+
the first occurrence of a key wins, if override is 1, the last occurrence
68+
of a key wins, if override is 2, a KeyError with conflicting key as
69+
argument is raised.
70+
*/
71+
PyAPI_FUNC(int) _PyDict_MergeEx(PyObject *mp, PyObject *other, int override);
72+
PyAPI_FUNC(PyObject *) _PyDict_GetItemId(PyObject *dp, struct _Py_Identifier *key);
73+
PyAPI_FUNC(int) _PyDict_SetItemId(PyObject *dp, struct _Py_Identifier *key, PyObject *item);
74+
75+
PyAPI_FUNC(int) _PyDict_DelItemId(PyObject *mp, struct _Py_Identifier *key);
76+
PyAPI_FUNC(void) _PyDict_DebugMallocStats(FILE *out);
77+
78+
int _PyObjectDict_SetItem(PyTypeObject *tp, PyObject **dictptr, PyObject *name, PyObject *value);
79+
PyObject *_PyDict_LoadGlobal(PyDictObject *, PyDictObject *, PyObject *);
80+
81+
/* _PyDictView */
82+
83+
typedef struct {
84+
PyObject_HEAD
85+
PyDictObject *dv_dict;
86+
} _PyDictViewObject;
87+
88+
PyAPI_FUNC(PyObject *) _PyDictView_New(PyObject *, PyTypeObject *);
89+
PyAPI_FUNC(PyObject *) _PyDictView_Intersect(PyObject* self, PyObject *other);
90+
91+
#ifdef __cplusplus
92+
}
93+
#endif

Include/dictobject.h

+31-119
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
extern "C" {
55
#endif
66

7-
87
/* Dictionary object type -- mapping from hashable object to object */
98

109
/* The distribution includes a separate file, Objects/dictnotes.txt,
@@ -13,119 +12,26 @@ extern "C" {
1312
tuning dictionaries, and several ideas for possible optimizations.
1413
*/
1514

16-
#ifndef Py_LIMITED_API
17-
18-
typedef struct _dictkeysobject PyDictKeysObject;
19-
20-
/* The ma_values pointer is NULL for a combined table
21-
* or points to an array of PyObject* for a split table
22-
*/
23-
typedef struct {
24-
PyObject_HEAD
25-
26-
/* Number of items in the dictionary */
27-
Py_ssize_t ma_used;
28-
29-
/* Dictionary version: globally unique, value change each time
30-
the dictionary is modified */
31-
uint64_t ma_version_tag;
32-
33-
PyDictKeysObject *ma_keys;
34-
35-
/* If ma_values is NULL, the table is "combined": keys and values
36-
are stored in ma_keys.
37-
38-
If ma_values is not NULL, the table is splitted:
39-
keys are stored in ma_keys and values are stored in ma_values */
40-
PyObject **ma_values;
41-
} PyDictObject;
42-
43-
typedef struct {
44-
PyObject_HEAD
45-
PyDictObject *dv_dict;
46-
} _PyDictViewObject;
47-
48-
#endif /* Py_LIMITED_API */
49-
5015
PyAPI_DATA(PyTypeObject) PyDict_Type;
51-
PyAPI_DATA(PyTypeObject) PyDictIterKey_Type;
52-
PyAPI_DATA(PyTypeObject) PyDictIterValue_Type;
53-
PyAPI_DATA(PyTypeObject) PyDictIterItem_Type;
54-
PyAPI_DATA(PyTypeObject) PyDictRevIterKey_Type;
55-
PyAPI_DATA(PyTypeObject) PyDictRevIterItem_Type;
56-
PyAPI_DATA(PyTypeObject) PyDictRevIterValue_Type;
57-
PyAPI_DATA(PyTypeObject) PyDictKeys_Type;
58-
PyAPI_DATA(PyTypeObject) PyDictItems_Type;
59-
PyAPI_DATA(PyTypeObject) PyDictValues_Type;
6016

6117
#define PyDict_Check(op) \
6218
PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_DICT_SUBCLASS)
6319
#define PyDict_CheckExact(op) (Py_TYPE(op) == &PyDict_Type)
64-
#define PyDictKeys_Check(op) PyObject_TypeCheck(op, &PyDictKeys_Type)
65-
#define PyDictItems_Check(op) PyObject_TypeCheck(op, &PyDictItems_Type)
66-
#define PyDictValues_Check(op) PyObject_TypeCheck(op, &PyDictValues_Type)
67-
/* This excludes Values, since they are not sets. */
68-
# define PyDictViewSet_Check(op) \
69-
(PyDictKeys_Check(op) || PyDictItems_Check(op))
70-
7120

7221
PyAPI_FUNC(PyObject *) PyDict_New(void);
7322
PyAPI_FUNC(PyObject *) PyDict_GetItem(PyObject *mp, PyObject *key);
74-
#ifndef Py_LIMITED_API
75-
PyAPI_FUNC(PyObject *) _PyDict_GetItem_KnownHash(PyObject *mp, PyObject *key,
76-
Py_hash_t hash);
77-
#endif
7823
PyAPI_FUNC(PyObject *) PyDict_GetItemWithError(PyObject *mp, PyObject *key);
79-
#ifndef Py_LIMITED_API
80-
PyAPI_FUNC(PyObject *) _PyDict_GetItemIdWithError(PyObject *dp,
81-
struct _Py_Identifier *key);
82-
PyAPI_FUNC(PyObject *) PyDict_SetDefault(
83-
PyObject *mp, PyObject *key, PyObject *defaultobj);
84-
#endif
8524
PyAPI_FUNC(int) PyDict_SetItem(PyObject *mp, PyObject *key, PyObject *item);
86-
#ifndef Py_LIMITED_API
87-
PyAPI_FUNC(int) _PyDict_SetItem_KnownHash(PyObject *mp, PyObject *key,
88-
PyObject *item, Py_hash_t hash);
89-
#endif
9025
PyAPI_FUNC(int) PyDict_DelItem(PyObject *mp, PyObject *key);
91-
#ifndef Py_LIMITED_API
92-
PyAPI_FUNC(int) _PyDict_DelItem_KnownHash(PyObject *mp, PyObject *key,
93-
Py_hash_t hash);
94-
PyAPI_FUNC(int) _PyDict_DelItemIf(PyObject *mp, PyObject *key,
95-
int (*predicate)(PyObject *value));
96-
#endif
9726
PyAPI_FUNC(void) PyDict_Clear(PyObject *mp);
9827
PyAPI_FUNC(int) PyDict_Next(
9928
PyObject *mp, Py_ssize_t *pos, PyObject **key, PyObject **value);
100-
#ifndef Py_LIMITED_API
101-
PyDictKeysObject *_PyDict_NewKeysForClass(void);
102-
PyAPI_FUNC(PyObject *) PyObject_GenericGetDict(PyObject *, void *);
103-
PyAPI_FUNC(int) _PyDict_Next(
104-
PyObject *mp, Py_ssize_t *pos, PyObject **key, PyObject **value, Py_hash_t *hash);
105-
PyObject *_PyDictView_New(PyObject *, PyTypeObject *);
106-
#endif
10729
PyAPI_FUNC(PyObject *) PyDict_Keys(PyObject *mp);
10830
PyAPI_FUNC(PyObject *) PyDict_Values(PyObject *mp);
10931
PyAPI_FUNC(PyObject *) PyDict_Items(PyObject *mp);
11032
PyAPI_FUNC(Py_ssize_t) PyDict_Size(PyObject *mp);
11133
PyAPI_FUNC(PyObject *) PyDict_Copy(PyObject *mp);
11234
PyAPI_FUNC(int) PyDict_Contains(PyObject *mp, PyObject *key);
113-
#ifndef Py_LIMITED_API
114-
/* Get the number of items of a dictionary. */
115-
#define PyDict_GET_SIZE(mp) (assert(PyDict_Check(mp)),((PyDictObject *)mp)->ma_used)
116-
PyAPI_FUNC(int) _PyDict_Contains(PyObject *mp, PyObject *key, Py_hash_t hash);
117-
PyAPI_FUNC(PyObject *) _PyDict_NewPresized(Py_ssize_t minused);
118-
PyAPI_FUNC(void) _PyDict_MaybeUntrack(PyObject *mp);
119-
PyAPI_FUNC(int) _PyDict_HasOnlyStringKeys(PyObject *mp);
120-
Py_ssize_t _PyDict_KeysSize(PyDictKeysObject *keys);
121-
PyAPI_FUNC(Py_ssize_t) _PyDict_SizeOf(PyDictObject *);
122-
PyAPI_FUNC(PyObject *) _PyDict_Pop(PyObject *, PyObject *, PyObject *);
123-
PyObject *_PyDict_Pop_KnownHash(PyObject *, PyObject *, Py_hash_t, PyObject *);
124-
PyObject *_PyDict_FromKeys(PyObject *, PyObject *, PyObject *);
125-
#define _PyDict_HasSplitTable(d) ((d)->ma_values != NULL)
126-
127-
PyAPI_FUNC(int) PyDict_ClearFreeList(void);
128-
#endif
12935

13036
/* PyDict_Update(mp, other) is equivalent to PyDict_Merge(mp, other, 1). */
13137
PyAPI_FUNC(int) PyDict_Update(PyObject *mp, PyObject *other);
@@ -136,44 +42,50 @@ PyAPI_FUNC(int) PyDict_Update(PyObject *mp, PyObject *other);
13642
dict.update(other) is equivalent to PyDict_Merge(dict, other, 1).
13743
*/
13844
PyAPI_FUNC(int) PyDict_Merge(PyObject *mp,
139-
PyObject *other,
140-
int override);
141-
142-
#ifndef Py_LIMITED_API
143-
/* Like PyDict_Merge, but override can be 0, 1 or 2. If override is 0,
144-
the first occurrence of a key wins, if override is 1, the last occurrence
145-
of a key wins, if override is 2, a KeyError with conflicting key as
146-
argument is raised.
147-
*/
148-
PyAPI_FUNC(int) _PyDict_MergeEx(PyObject *mp, PyObject *other, int override);
149-
PyAPI_FUNC(PyObject *) _PyDictView_Intersect(PyObject* self, PyObject *other);
150-
#endif
45+
PyObject *other,
46+
int override);
15147

15248
/* PyDict_MergeFromSeq2 updates/merges from an iterable object producing
15349
iterable objects of length 2. If override is true, the last occurrence
15450
of a key wins, else the first. The Python dict constructor dict(seq2)
15551
is equivalent to dict={}; PyDict_MergeFromSeq(dict, seq2, 1).
15652
*/
15753
PyAPI_FUNC(int) PyDict_MergeFromSeq2(PyObject *d,
158-
PyObject *seq2,
159-
int override);
54+
PyObject *seq2,
55+
int override);
16056

16157
PyAPI_FUNC(PyObject *) PyDict_GetItemString(PyObject *dp, const char *key);
162-
#ifndef Py_LIMITED_API
163-
PyAPI_FUNC(PyObject *) _PyDict_GetItemId(PyObject *dp, struct _Py_Identifier *key);
164-
#endif /* !Py_LIMITED_API */
16558
PyAPI_FUNC(int) PyDict_SetItemString(PyObject *dp, const char *key, PyObject *item);
166-
#ifndef Py_LIMITED_API
167-
PyAPI_FUNC(int) _PyDict_SetItemId(PyObject *dp, struct _Py_Identifier *key, PyObject *item);
168-
#endif /* !Py_LIMITED_API */
16959
PyAPI_FUNC(int) PyDict_DelItemString(PyObject *dp, const char *key);
17060

171-
#ifndef Py_LIMITED_API
172-
PyAPI_FUNC(int) _PyDict_DelItemId(PyObject *mp, struct _Py_Identifier *key);
173-
PyAPI_FUNC(void) _PyDict_DebugMallocStats(FILE *out);
61+
/* Dictionary (keys, values, items) views */
62+
63+
PyAPI_DATA(PyTypeObject) PyDictKeys_Type;
64+
PyAPI_DATA(PyTypeObject) PyDictValues_Type;
65+
PyAPI_DATA(PyTypeObject) PyDictItems_Type;
66+
67+
#define PyDictKeys_Check(op) PyObject_TypeCheck(op, &PyDictKeys_Type)
68+
#define PyDictValues_Check(op) PyObject_TypeCheck(op, &PyDictValues_Type)
69+
#define PyDictItems_Check(op) PyObject_TypeCheck(op, &PyDictItems_Type)
70+
/* This excludes Values, since they are not sets. */
71+
# define PyDictViewSet_Check(op) \
72+
(PyDictKeys_Check(op) || PyDictItems_Check(op))
73+
74+
/* Dictionary (key, value, items) iterators */
17475

175-
int _PyObjectDict_SetItem(PyTypeObject *tp, PyObject **dictptr, PyObject *name, PyObject *value);
176-
PyObject *_PyDict_LoadGlobal(PyDictObject *, PyDictObject *, PyObject *);
76+
PyAPI_DATA(PyTypeObject) PyDictIterKey_Type;
77+
PyAPI_DATA(PyTypeObject) PyDictIterValue_Type;
78+
PyAPI_DATA(PyTypeObject) PyDictIterItem_Type;
79+
80+
PyAPI_DATA(PyTypeObject) PyDictRevIterKey_Type;
81+
PyAPI_DATA(PyTypeObject) PyDictRevIterItem_Type;
82+
PyAPI_DATA(PyTypeObject) PyDictRevIterValue_Type;
83+
84+
85+
#ifndef Py_LIMITED_API
86+
# define Py_CPYTHON_DICTOBJECT_H
87+
# include "cpython/dictobject.h"
88+
# undef Py_CPYTHON_DICTOBJECT_H
17789
#endif
17890

17991
#ifdef __cplusplus

0 commit comments

Comments
 (0)