|
1 | 1 | import collections |
| 2 | +import collections.abc |
2 | 3 | from test.test_json import PyTest, CTest |
3 | 4 |
|
4 | 5 |
|
| 6 | +class CustomIndexDict(collections.abc.Mapping, dict): |
| 7 | + # Using `Mapping` here to make this a complete dict subclass, but note the bug in #110941 |
| 8 | + # is not specific to `Mapping` subclasses and the outcome would have been the same with a |
| 9 | + # fully manually implemented dict subclass. |
| 10 | + |
| 11 | + def __init__(self, keys: tuple = ()): |
| 12 | + self._keys = keys |
| 13 | + |
| 14 | + def __getitem__(self, k): |
| 15 | + try: |
| 16 | + return self._keys.index(k) |
| 17 | + except ValueError: |
| 18 | + raise KeyError(k) |
| 19 | + |
| 20 | + def __iter__(self): |
| 21 | + return iter(self._keys) |
| 22 | + |
| 23 | + def __len__(self): |
| 24 | + return len(self._keys) |
| 25 | + |
| 26 | + |
5 | 27 | class TestDefault: |
6 | 28 | def test_default(self): |
7 | 29 | self.assertEqual( |
@@ -36,6 +58,23 @@ def test_ordereddict(self): |
36 | 58 | self.dumps(od, sort_keys=True), |
37 | 59 | '{"a": 1, "b": 2, "c": 3, "d": 4}') |
38 | 60 |
|
| 61 | + # This should behave identically for PyTest and CTest: see #110941. |
| 62 | + def test_custom_dict(self): |
| 63 | + cd = CustomIndexDict(("b", "a")) |
| 64 | + self.assertEqual( |
| 65 | + self.dumps(cd), |
| 66 | + '{"b": 0, "a": 1}') |
| 67 | + self.assertEqual( |
| 68 | + self.dumps(cd, sort_keys=True), |
| 69 | + '{"a": 1, "b": 0}') |
| 70 | + |
| 71 | + def test_empty_custom_dict(self): |
| 72 | + # Exercise the fast path when a dict subclass is empty. |
| 73 | + cd = CustomIndexDict() |
| 74 | + self.assertEqual( |
| 75 | + self.dumps(cd), |
| 76 | + '{}') |
| 77 | + |
39 | 78 |
|
40 | 79 | class TestPyDefault(TestDefault, PyTest): pass |
41 | 80 | class TestCDefault(TestDefault, CTest): pass |
0 commit comments