gh-124296: Remove private dictionary version tag (PEP 699) (#124472) · python/cpython@5aa91c5 · GitHub
Skip to content

Commit 5aa91c5

Browse files
authored
gh-124296: Remove private dictionary version tag (PEP 699) (#124472)
1 parent 60ff67d commit 5aa91c5

13 files changed

Lines changed: 35 additions & 354 deletions

File tree

Include/cpython/dictobject.h

Lines changed: 4 additions & 9 deletions

Include/internal/pycore_dict.h

Lines changed: 2 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -230,31 +230,6 @@ static inline PyDictUnicodeEntry* DK_UNICODE_ENTRIES(PyDictKeysObject *dk) {
230230
#define DICT_WATCHER_MASK ((1 << DICT_MAX_WATCHERS) - 1)
231231
#define DICT_WATCHER_AND_MODIFICATION_MASK ((1 << (DICT_MAX_WATCHERS + DICT_WATCHED_MUTATION_BITS)) - 1)
232232

233-
#ifdef Py_GIL_DISABLED
234-
235-
#define THREAD_LOCAL_DICT_VERSION_COUNT 256
236-
#define THREAD_LOCAL_DICT_VERSION_BATCH THREAD_LOCAL_DICT_VERSION_COUNT * DICT_VERSION_INCREMENT
237-
238-
static inline uint64_t
239-
dict_next_version(PyInterpreterState *interp)
240-
{
241-
PyThreadState *tstate = PyThreadState_GET();
242-
uint64_t cur_progress = (tstate->dict_global_version &
243-
(THREAD_LOCAL_DICT_VERSION_BATCH - 1));
244-
if (cur_progress == 0) {
245-
uint64_t next = _Py_atomic_add_uint64(&interp->dict_state.global_version,
246-
THREAD_LOCAL_DICT_VERSION_BATCH);
247-
tstate->dict_global_version = next;
248-
}
249-
return tstate->dict_global_version += DICT_VERSION_INCREMENT;
250-
}
251-
252-
#define DICT_NEXT_VERSION(INTERP) dict_next_version(INTERP)
253-
254-
#else
255-
#define DICT_NEXT_VERSION(INTERP) \
256-
((INTERP)->dict_state.global_version += DICT_VERSION_INCREMENT)
257-
#endif
258233

259234
PyAPI_FUNC(void)
260235
_PyDict_SendEvent(int watcher_bits,
@@ -263,20 +238,19 @@ _PyDict_SendEvent(int watcher_bits,
263238
PyObject *key,
264239
PyObject *value);
265240

266-
static inline uint64_t
241+
static inline void
267242
_PyDict_NotifyEvent(PyInterpreterState *interp,
268243
PyDict_WatchEvent event,
269244
PyDictObject *mp,
270245
PyObject *key,
271246
PyObject *value)
272247
{
273248
assert(Py_REFCNT((PyObject*)mp) > 0);
274-
int watcher_bits = mp->ma_version_tag & DICT_WATCHER_MASK;
249+
int watcher_bits = mp->_ma_watcher_tag & DICT_WATCHER_MASK;
275250
if (watcher_bits) {
276251
RARE_EVENT_STAT_INC(watched_dict_modification);
277252
_PyDict_SendEvent(watcher_bits, event, mp, key, value);
278253
}
279-
return DICT_NEXT_VERSION(interp) | (mp->ma_version_tag & DICT_WATCHER_AND_MODIFICATION_MASK);
280254
}
281255

282256
extern PyDictObject *_PyObject_MaterializeManagedDict(PyObject *obj);

Include/internal/pycore_dict_state.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,6 @@ extern "C" {
1212
#define DICT_WATCHED_MUTATION_BITS 4
1313

1414
struct _Py_dict_state {
15-
/*Global counter used to set ma_version_tag field of dictionary.
16-
* It is incremented each time that a dictionary is created and each
17-
* time that a dictionary is modified. */
18-
uint64_t global_version;
1915
uint32_t next_keys_version;
2016
PyDict_WatchCallback watchers[DICT_MAX_WATCHERS];
2117
};

Lib/test/test_dict_version.py

Lines changed: 0 additions & 191 deletions
This file was deleted.

Lib/test/test_free_threading/test_dict.py

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -142,41 +142,6 @@ def writer_func(l):
142142
for ref in thread_list:
143143
self.assertIsNone(ref())
144144

145-
@unittest.skipIf(_testcapi is None, 'need _testcapi module')
146-
def test_dict_version(self):
147-
dict_version = _testcapi.dict_version
148-
THREAD_COUNT = 10
149-
DICT_COUNT = 10000
150-
lists = []
151-
writers = []
152-
153-
def writer_func(thread_list):
154-
for i in range(DICT_COUNT):
155-
thread_list.append(dict_version({}))
156-
157-
for x in range(THREAD_COUNT):
158-
thread_list = []
159-
lists.append(thread_list)
160-
writer = Thread(target=partial(writer_func, thread_list))
161-
writers.append(writer)
162-
163-
for writer in writers:
164-
writer.start()
165-
166-
for writer in writers:
167-
writer.join()
168-
169-
total_len = 0
170-
values = set()
171-
for thread_list in lists:
172-
for v in thread_list:
173-
if v in values:
174-
print('dup', v, (v/4096)%256)
175-
values.add(v)
176-
total_len += len(thread_list)
177-
versions = set(dict_version for thread_list in lists for dict_version in thread_list)
178-
self.assertEqual(len(versions), THREAD_COUNT*DICT_COUNT)
179-
180145

181146
if __name__ == "__main__":
182147
unittest.main()
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
:c:type:`PyDictObject` no longer maintains a private version tag field
2+
``ma_version_tag`` per :pep:`699`. This field was originally added in
3+
Python 3.6 (:pep:`509`) and deprecated in Python 3.12.

Modules/_testcapi/dict.c

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -181,19 +181,6 @@ dict_popstring_null(PyObject *self, PyObject *args)
181181
RETURN_INT(PyDict_PopString(dict, key, NULL));
182182
}
183183

184-
static PyObject *
185-
dict_version(PyObject *self, PyObject *dict)
186-
{
187-
if (!PyDict_Check(dict)) {
188-
PyErr_SetString(PyExc_TypeError, "expected dict");
189-
return NULL;
190-
}
191-
_Py_COMP_DIAG_PUSH
192-
_Py_COMP_DIAG_IGNORE_DEPR_DECLS
193-
return PyLong_FromUnsignedLongLong(((PyDictObject *)dict)->ma_version_tag);
194-
_Py_COMP_DIAG_POP
195-
}
196-
197184
static PyMethodDef test_methods[] = {
198185
{"dict_containsstring", dict_containsstring, METH_VARARGS},
199186
{"dict_getitemref", dict_getitemref, METH_VARARGS},
@@ -204,7 +191,6 @@ static PyMethodDef test_methods[] = {
204191
{"dict_pop_null", dict_pop_null, METH_VARARGS},
205192
{"dict_popstring", dict_popstring, METH_VARARGS},
206193
{"dict_popstring_null", dict_popstring_null, METH_VARARGS},
207-
{"dict_version", dict_version, METH_O},
208194
{NULL},
209195
};
210196

Modules/_testcapimodule.c

Lines changed: 0 additions & 20 deletions

0 commit comments

Comments
 (0)