Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/dns/immutable.py: 27%

41 statements  

« prev     ^ index     » next       coverage.py v7.4.1, created at 2024-02-02 06:07 +0000

1# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license 

2 

3import collections.abc 

4from typing import Any, Callable 

5 

6from dns._immutable_ctx import immutable 

7 

8 

9@immutable 

10class Dict(collections.abc.Mapping): # lgtm[py/missing-equals] 

11 def __init__( 

12 self, 

13 dictionary: Any, 

14 no_copy: bool = False, 

15 map_factory: Callable[[], collections.abc.MutableMapping] = dict, 

16 ): 

17 """Make an immutable dictionary from the specified dictionary. 

18 

19 If *no_copy* is `True`, then *dictionary* will be wrapped instead 

20 of copied. Only set this if you are sure there will be no external 

21 references to the dictionary. 

22 """ 

23 if no_copy and isinstance(dictionary, collections.abc.MutableMapping): 

24 self._odict = dictionary 

25 else: 

26 self._odict = map_factory() 

27 self._odict.update(dictionary) 

28 self._hash = None 

29 

30 def __getitem__(self, key): 

31 return self._odict.__getitem__(key) 

32 

33 def __hash__(self): # pylint: disable=invalid-hash-returned 

34 if self._hash is None: 

35 h = 0 

36 for key in sorted(self._odict.keys()): 

37 h ^= hash(key) 

38 object.__setattr__(self, "_hash", h) 

39 # this does return an int, but pylint doesn't figure that out 

40 return self._hash 

41 

42 def __len__(self): 

43 return len(self._odict) 

44 

45 def __iter__(self): 

46 return iter(self._odict) 

47 

48 

49def constify(o: Any) -> Any: 

50 """ 

51 Convert mutable types to immutable types. 

52 """ 

53 if isinstance(o, bytearray): 

54 return bytes(o) 

55 if isinstance(o, tuple): 

56 try: 

57 hash(o) 

58 return o 

59 except Exception: 

60 return tuple(constify(elt) for elt in o) 

61 if isinstance(o, list): 

62 return tuple(constify(elt) for elt in o) 

63 if isinstance(o, dict): 

64 cdict = dict() 

65 for k, v in o.items(): 

66 cdict[k] = constify(v) 

67 return Dict(cdict, True) 

68 return o