| # Test cases for dicts (compile and run) |
| |
| [case testDictStuff] |
| from typing import Dict, Any, List, Set, Tuple |
| from defaultdictwrap import make_dict |
| |
| def f(x: int) -> int: |
| dict1 = {} # type: Dict[int, int] |
| dict1[1] = 1 |
| dict2 = {} # type: Dict[int, int] |
| dict2[x] = 2 |
| dict1.update(dict2) |
| |
| l = [(5, 2)] # type: Any |
| dict1.update(l) |
| d2 = {6: 4} # type: Any |
| dict1.update(d2) |
| |
| return dict1[1] |
| |
| def g() -> int: |
| d = make_dict() |
| d['a'] = 10 |
| d['a'] += 10 |
| d['b'] += 10 |
| l = [('c', 2)] # type: Any |
| d.update(l) |
| d2 = {'d': 4} # type: Any |
| d.update(d2) |
| return d['a'] + d['b'] |
| |
| def h() -> None: |
| d = {} # type: Dict[Any, Any] |
| d[{}] |
| |
| def update_dict(x: Dict[Any, Any], y: Any): |
| x.update(y) |
| |
| def make_dict1(x: Any) -> Dict[Any, Any]: |
| return dict(x) |
| |
| def make_dict2(x: Dict[Any, Any]) -> Dict[Any, Any]: |
| return dict(x) |
| |
| def u(x: int) -> int: |
| d = {} # type: Dict[str, int] |
| d.update(x=x) |
| return d['x'] |
| |
| def get_content(d: Dict[int, int]) -> Tuple[List[int], List[int], List[Tuple[int, int]]]: |
| return list(d.keys()), list(d.values()), list(d.items()) |
| |
| def get_content_set(d: Dict[int, int]) -> Tuple[Set[int], Set[int], Set[Tuple[int, int]]]: |
| return set(d.keys()), set(d.values()), set(d.items()) |
| [file defaultdictwrap.py] |
| from typing import Dict |
| from collections import defaultdict # type: ignore |
| def make_dict() -> Dict[str, int]: |
| return defaultdict(int) |
| |
| [file driver.py] |
| from collections import OrderedDict |
| from native import ( |
| f, g, h, u, make_dict1, make_dict2, update_dict, get_content, get_content_set |
| ) |
| assert f(1) == 2 |
| assert f(2) == 1 |
| assert g() == 30 |
| # Make sure we get a TypeError from indexing with unhashable and not KeyError |
| try: |
| h() |
| except TypeError: |
| pass |
| else: |
| assert False |
| d = {'a': 1, 'b': 2} |
| assert make_dict1(d) == d |
| assert make_dict1(d.items()) == d |
| assert make_dict2(d) == d |
| # object.__dict__ is a "mappingproxy" and not a dict |
| assert make_dict1(object.__dict__) == dict(object.__dict__) |
| d = {} |
| update_dict(d, object.__dict__) |
| assert d == dict(object.__dict__) |
| |
| assert u(10) == 10 |
| assert get_content({1: 2}) == ([1], [2], [(1, 2)]) |
| od = OrderedDict([(1, 2), (3, 4)]) |
| assert get_content(od) == ([1, 3], [2, 4], [(1, 2), (3, 4)]) |
| od.move_to_end(1) |
| assert get_content(od) == ([3, 1], [4, 2], [(3, 4), (1, 2)]) |
| assert get_content_set({1: 2}) == ({1}, {2}, {(1, 2)}) |
| assert get_content_set(od) == ({1, 3}, {2, 4}, {(1, 2), (3, 4)}) |
| |
| [typing fixtures/typing-full.pyi] |
| |
| [case testDictIterationMethodsRun] |
| from typing import Dict, TypedDict, Union |
| |
| class ExtensionDict(TypedDict): |
| python: str |
| c: str |
| |
| def print_dict_methods(d1: Dict[int, int], |
| d2: Dict[int, int], |
| d3: Dict[int, int]) -> None: |
| for k in d1.keys(): |
| print(k) |
| for k, v in d2.items(): |
| print(k) |
| print(v) |
| for v in d3.values(): |
| print(v) |
| |
| def print_dict_methods_special(d1: Union[Dict[int, int], Dict[str, str]], |
| d2: ExtensionDict) -> None: |
| for k in d1.keys(): |
| print(k) |
| for k, v in d1.items(): |
| print(k) |
| print(v) |
| for v2 in d2.values(): |
| print(v2) |
| for k2, v2 in d2.items(): |
| print(k2) |
| print(v2) |
| |
| |
| def clear_during_iter(d: Dict[int, int]) -> None: |
| for k in d: |
| d.clear() |
| |
| class Custom(Dict[int, int]): pass |
| [file driver.py] |
| from native import print_dict_methods, print_dict_methods_special, Custom, clear_during_iter |
| from collections import OrderedDict |
| print_dict_methods({}, {}, {}) |
| print_dict_methods({1: 2}, {3: 4, 5: 6}, {7: 8}) |
| print('==') |
| c = Custom({0: 1}) |
| print_dict_methods(c, c, c) |
| print('==') |
| d = OrderedDict([(1, 2), (3, 4)]) |
| print_dict_methods(d, d, d) |
| print('==') |
| print_dict_methods_special({1: 2}, {"python": ".py", "c": ".c"}) |
| d.move_to_end(1) |
| print_dict_methods(d, d, d) |
| clear_during_iter({}) # OK |
| try: |
| clear_during_iter({1: 2, 3: 4}) |
| except RuntimeError as e: |
| assert str(e) == "dictionary changed size during iteration" |
| else: |
| assert False |
| try: |
| clear_during_iter(d) |
| except RuntimeError as e: |
| assert str(e) in ( |
| "OrderedDict changed size during iteration", |
| # Error message changed in Python 3.13 and some 3.12 patch version |
| "OrderedDict mutated during iteration", |
| ) |
| else: |
| assert False |
| |
| class CustomMad(dict): |
| def __iter__(self): |
| return self |
| def __next__(self): |
| raise ValueError |
| m = CustomMad() |
| try: |
| clear_during_iter(m) |
| except ValueError: |
| pass |
| else: |
| assert False |
| |
| class CustomBad(dict): |
| def items(self): |
| return [(1, 2, 3)] # Oops |
| b = CustomBad() |
| try: |
| print_dict_methods(b, b, b) |
| except TypeError as e: |
| assert str(e) == "a tuple of length 2 expected" |
| else: |
| assert False |
| [typing fixtures/typing-full.pyi] |
| [out] |
| 1 |
| 3 |
| 4 |
| 5 |
| 6 |
| 8 |
| == |
| 0 |
| 0 |
| 1 |
| 1 |
| == |
| 1 |
| 3 |
| 1 |
| 2 |
| 3 |
| 4 |
| 2 |
| 4 |
| == |
| 1 |
| 1 |
| 2 |
| .py |
| .c |
| python |
| .py |
| c |
| .c |
| 3 |
| 1 |
| 3 |
| 4 |
| 1 |
| 2 |
| 4 |
| 2 |
| |
| [case testDictMethods] |
| from collections import defaultdict |
| from typing import Dict, Optional, List, Set |
| |
| def test_dict_clear() -> None: |
| d = {'a': 1, 'b': 2} |
| d.clear() |
| assert d == {} |
| dd: Dict[str, int] = defaultdict(int) |
| dd['a'] = 1 |
| dd.clear() |
| assert dd == {} |
| |
| def test_dict_copy() -> None: |
| d: Dict[str, int] = {} |
| assert d.copy() == d |
| d = {'a': 1, 'b': 2} |
| assert d.copy() == d |
| assert d.copy() is not d |
| dd: Dict[str, int] = defaultdict(int) |
| dd['a'] = 1 |
| assert dd.copy() == dd |
| assert isinstance(dd.copy(), defaultdict) |
| |
| class MyDict(dict): |
| def __init__(self, *args, **kwargs): |
| self.update(*args, **kwargs) |
| |
| def setdefault(self, k, v=None): |
| if v is None: |
| if k in self.keys(): |
| return self[k] |
| else: |
| return None |
| else: |
| return super().setdefault(k, v) + 10 |
| |
| def test_dict_setdefault() -> None: |
| d: Dict[str, Optional[int]] = {'a': 1, 'b': 2} |
| assert d.setdefault('a', 2) == 1 |
| assert d.setdefault('b', 2) == 2 |
| assert d.setdefault('c', 3) == 3 |
| assert d['a'] == 1 |
| assert d['c'] == 3 |
| assert d.setdefault('a') == 1 |
| assert d.setdefault('e') == None |
| assert d.setdefault('e', 100) == None |
| |
| def test_dict_subclass_setdefault() -> None: |
| d = MyDict() |
| d['a'] = 1 |
| assert d.setdefault('a', 2) == 11 |
| assert d.setdefault('b', 2) == 12 |
| assert d.setdefault('c', 3) == 13 |
| assert d['a'] == 1 |
| assert d['c'] == 3 |
| assert d.setdefault('a') == 1 |
| assert d.setdefault('e') == None |
| assert d.setdefault('e', 100) == 110 |
| |
| def test_dict_empty_collection_setdefault() -> None: |
| d1: Dict[str, List[int]] = {'a': [1, 2, 3]} |
| assert d1.setdefault('a', []) == [1, 2, 3] |
| assert d1.setdefault('b', []) == [] |
| assert 'b' in d1 |
| d1.setdefault('b', []).append(3) |
| assert d1['b'] == [3] |
| assert d1.setdefault('c', [1]) == [1] |
| |
| d2: Dict[str, Dict[str, int]] = {'a': {'a': 1}} |
| assert d2.setdefault('a', {}) == {'a': 1} |
| assert d2.setdefault('b', {}) == {} |
| assert 'b' in d2 |
| d2.setdefault('b', {})['aa'] = 2 |
| d2.setdefault('b', {})['bb'] = 3 |
| assert d2['b'] == {'aa': 2, 'bb': 3} |
| assert d2.setdefault('c', {'cc': 1}) == {'cc': 1} |
| |
| d3: Dict[str, Set[str]] = {'a': set('a')} |
| assert d3.setdefault('a', set()) == {'a'} |
| assert d3.setdefault('b', set()) == set() |
| d3.setdefault('b', set()).add('b') |
| d3.setdefault('b', set()).add('c') |
| assert d3['b'] == {'b', 'c'} |
| assert d3.setdefault('c', set('d')) == {'d'} |
| |
| [case testDictToBool] |
| from typing import Dict, List |
| |
| def is_true(x: dict) -> bool: |
| if x: |
| return True |
| else: |
| return False |
| |
| def is_false(x: dict) -> bool: |
| if not x: |
| return True |
| else: |
| return False |
| |
| def test_dict_to_bool() -> None: |
| assert is_false({}) |
| assert not is_true({}) |
| tmp_list: List[Dict] = [{2: bool}, {'a': 'b'}] |
| for x in tmp_list: |
| assert is_true(x) |
| assert not is_false(x) |