Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/icalendar/caselessdict.py: 80%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

64 statements  

1from icalendar.parser_tools import to_unicode 

2 

3from collections import OrderedDict 

4 

5 

6def canonsort_keys(keys, canonical_order=None): 

7 """Sorts leading keys according to canonical_order. Keys not specified in 

8 canonical_order will appear alphabetically at the end. 

9 """ 

10 canonical_map = {k: i for i, k in enumerate(canonical_order or [])} 

11 head = [k for k in keys if k in canonical_map] 

12 tail = [k for k in keys if k not in canonical_map] 

13 return sorted(head, key=lambda k: canonical_map[k]) + sorted(tail) 

14 

15 

16def canonsort_items(dict1, canonical_order=None): 

17 """Returns a list of items from dict1, sorted by canonical_order.""" 

18 return [(k, dict1[k]) for k in canonsort_keys(dict1.keys(), canonical_order)] 

19 

20 

21class CaselessDict(OrderedDict): 

22 """A dictionary that isn't case sensitive, and only uses strings as keys. 

23 Values retain their case. 

24 """ 

25 

26 def __init__(self, *args, **kwargs): 

27 """Set keys to upper for initial dict.""" 

28 super().__init__(*args, **kwargs) 

29 for key, value in self.items(): 

30 key_upper = to_unicode(key).upper() 

31 if key != key_upper: 

32 super().__delitem__(key) 

33 self[key_upper] = value 

34 

35 def __getitem__(self, key): 

36 key = to_unicode(key) 

37 return super().__getitem__(key.upper()) 

38 

39 def __setitem__(self, key, value): 

40 key = to_unicode(key) 

41 super().__setitem__(key.upper(), value) 

42 

43 def __delitem__(self, key): 

44 key = to_unicode(key) 

45 super().__delitem__(key.upper()) 

46 

47 def __contains__(self, key): 

48 key = to_unicode(key) 

49 return super().__contains__(key.upper()) 

50 

51 def get(self, key, default=None): 

52 key = to_unicode(key) 

53 return super().get(key.upper(), default) 

54 

55 def setdefault(self, key, value=None): 

56 key = to_unicode(key) 

57 return super().setdefault(key.upper(), value) 

58 

59 def pop(self, key, default=None): 

60 key = to_unicode(key) 

61 return super().pop(key.upper(), default) 

62 

63 def popitem(self): 

64 return super().popitem() 

65 

66 def has_key(self, key): 

67 key = to_unicode(key) 

68 return super().__contains__(key.upper()) 

69 

70 def update(self, *args, **kwargs): 

71 # Multiple keys where key1.upper() == key2.upper() will be lost. 

72 mappings = list(args) + [kwargs] 

73 for mapping in mappings: 

74 if hasattr(mapping, "items"): 

75 mapping = iter(mapping.items()) 

76 for key, value in mapping: 

77 self[key] = value 

78 

79 def copy(self): 

80 return type(self)(super().copy()) 

81 

82 def __repr__(self): 

83 return f"{type(self).__name__}({dict(self)})" 

84 

85 def __eq__(self, other): 

86 return self is other or dict(self.items()) == dict(other.items()) 

87 

88 def __ne__(self, other): 

89 return not self == other 

90 

91 # A list of keys that must appear first in sorted_keys and sorted_items; 

92 # must be uppercase. 

93 canonical_order = None 

94 

95 def sorted_keys(self): 

96 """Sorts keys according to the canonical_order for the derived class. 

97 Keys not specified in canonical_order will appear at the end. 

98 """ 

99 return canonsort_keys(self.keys(), self.canonical_order) 

100 

101 def sorted_items(self): 

102 """Sorts items according to the canonical_order for the derived class. 

103 Items not specified in canonical_order will appear at the end. 

104 """ 

105 return canonsort_items(self, self.canonical_order) 

106 

107 

108__all__ = ["canonsort_keys", "canonsort_items", "CaselessDict"]