Skip to content

Commit eb3f798

Browse files
committed
add unit test.
1 parent a5cfe98 commit eb3f798

File tree

3 files changed

+29
-43
lines changed

3 files changed

+29
-43
lines changed

Lib/test/test_defaultdict.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import unittest
66

77
from collections import defaultdict
8+
from threading import Condition, Thread
89

910
def foobar():
1011
return list
@@ -185,6 +186,32 @@ def test_union(self):
185186

186187
with self.assertRaises(TypeError):
187188
i |= None
189+
190+
def test_default_race(self):
191+
cv = Condition()
192+
key = "default_race_key"
193+
194+
def default_factory(cv: Condition, cv_flag: list[bool]):
195+
with cv:
196+
while not cv_flag[0]:
197+
cv.wait()
198+
return "default_value"
199+
ready_flag = [False]
200+
test_dict = defaultdict(lambda: default_factory(cv, ready_flag))
201+
202+
def writer(cv: Condition, cv_flag: list[bool], race_dict: dict):
203+
with cv:
204+
race_dict[key] = "writer_value"
205+
cv_flag[0] = True
206+
cv.notify()
207+
208+
default_factory_thread = Thread(target=lambda: test_dict[key])
209+
writer_thread = Thread(target=lambda: writer(cv, ready_flag, test_dict))
210+
default_factory_thread.start()
211+
writer_thread.start()
212+
default_factory_thread.join()
213+
writer_thread.join()
214+
self.assertEqual(test_dict[key], "writer_value")
188215

189216
if __name__ == "__main__":
190217
unittest.main()

Modules/_collectionsmodule.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2231,18 +2231,16 @@ defdict_missing(PyObject *op, PyObject *key)
22312231
value = _PyObject_CallNoArgs(factory);
22322232
if (value == NULL)
22332233
return value;
2234-
// if (PyObject_SetItem(op, key, value) < 0) {
2235-
// Py_DECREF(value);
2236-
// return NULL;
2237-
// }
22382234
PyObject* result;
22392235
int res = PyDict_SetDefaultRef(op, key, value, &result);
22402236
if (res < 0) {
2237+
// set default ref with error
22412238
PyObject *tup;
22422239
tup = PyTuple_Pack(1, key);
22432240
if (!tup) return NULL;
22442241
PyErr_SetObject(PyExc_KeyError, tup);
22452242
Py_DECREF(tup);
2243+
Py_DECREF(value);
22462244
} else if (res > 0) {
22472245
// Key was already in the dict
22482246
Py_DECREF(value);

edward_defaultdict_test.py

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

0 commit comments

Comments
 (0)