Coverage for barrack.py: 100%

58 statements  

« prev     ^ index     » next       coverage.py v7.8.0, created at 2025-04-08 21:58 +0200

1#!/usr/bin/env python 

2# -*- coding: utf-8 -*- 

3""" 

4Traits / mixins are the heart of archery, but sometimes you need functions to help you 

5 

6""" 

7try: 

8 from collections import MutableMapping 

9except ImportError: 

10 from collections.abc import MutableMapping 

11 

12 

13MARKER=object() 

14 

15class Path(tuple): 

16 def endswith( self, *a_tuple ): 

17 """check if path ends with the consecutive given has argumenbts value 

18 

19 >>> p = Path( [ 'a', 'b', 'c' ] ) 

20 >>> p.endswith( 'b', 'c' ) 

21 >>> True 

22 >>> p.endswith( 'c', 'b' ) 

23 >>> False 

24 """ 

25 return self[len(self) - len(a_tuple) : ] == a_tuple 

26 

27 def startswith( self, *a_tuple ): 

28 """checks if a path starts with the value 

29 

30 >>> p = Path( [ 'a', 'b', 'c', 'd' ] ) 

31 >>> p.startswith( 'a', 'b' ) 

32 >>> True 

33 """ 

34 return self[: len( a_tuple ) ] == a_tuple 

35 

36 def _contains( self, a_tuple, _from = 0, follow = 0): 

37 if len( a_tuple) == follow: 

38 return True 

39 index = False 

40 here = self[ _from:] 

41 

42 try: 

43 index = here.index(a_tuple[follow] ) 

44 return self._contains( 

45 a_tuple, 

46 index + 1 , 

47 follow + 1 

48 ) 

49 except ValueError: 

50 return False 

51 return False 

52 

53 def contains(self, *a_tuple ): 

54 """checks if the serie of keys is contained in a path 

55 

56 >>> p = Path( [ 'a', 'b', 'c', 'd' ] ) 

57 >>> p.contains( 'b', 'c' ) 

58 >>> True 

59 

60 """ 

61 return self._contains(a_tuple) 

62 

63 def value(self): 

64 """ function provided for code readability: 

65 - returns the left most value of the Path aka the value 

66 """ 

67 return self[-1] 

68 

69 def key(self): 

70 """ function provided for code readability: 

71 - returns all the keys in the Path 

72 """ 

73 return Path(self[:-1]) 

74 

75def make_from_path(type_of_mapping, path): 

76 """Work in Progress 

77 create a mutable mapping from a `Path`_ (tuple made of a series of keys in a dict leading to a 

78 value followed by a value). 

79 The source is used a mapping factory and is reset in the process 

80 

81 >>> make_from_path(dict, ("y", "z", 2)) 

82 >>> #Out[2]: {'y': {'z': 2}} 

83 

84 """ 

85 path = list(path) 

86 value = path.pop() 

87 last_key = path.pop() 

88 tmap = type_of_mapping 

89 mapping = tmap({last_key : value}) 

90 while path: 

91 _next = path.pop() 

92 mapping = tmap({_next : mapping }) 

93 return mapping 

94 

95def bowyer(_mapping_fact, _mapping_to_convert): 

96 """the craftsman that makes bow 

97 A function that given a function in the form  

98 f(tree) will convert a one level tree in your mapping""" 

99 _toc = _mapping_fact(_mapping_to_convert) 

100 for k, v in _toc.items(): 

101 if isinstance(v, MutableMapping) and len(v): 

102 _toc[k] = bowyer(_mapping_fact, v) 

103 return _toc 

104 

105def mapping_row_iter(tree, path=MARKER): 

106 """ 

107 iterator on a tree that yield an iterator on a mapping in the form of  

108 a list of ordered key that leads to the element and the value 

109 

110 >>> from archery import mapping_row_iter 

111 >>> [ x for x in mapping_row_iter({ 

112 ... "john" : {'math':10.0, 'sport':1.0},~ 

113 ... "lily" : { 'math':20, 'sport':15.0} 

114 ... })] 

115 >>> #[['john', 'sport', 1.0], ['john', 'math', 10.0],~ 

116 >>> #['lily', 'sport', 15.0], ['lily', 'math', 20]] 

117 

118 """ 

119 if path is MARKER: 

120 path = () 

121 for k, v in tree.items(): 

122 if isinstance(v, MutableMapping) and len(v): 

123 for child in mapping_row_iter(v, (path + (k,))): 

124 yield child 

125 else: 

126 yield path + (k , v) 

127 

128 

129def paired_row_iter(tree, path=MARKER): 

130 """ 

131 iterator on a tree that yield a pair key (path to a value), value 

132 """ 

133 if path is MARKER: 

134 path = tuple() 

135 

136 for k, v in tree.items(): 

137 if isinstance(v, MutableMapping) and len(v): 

138 for child in paired_row_iter(v, path + (k,)): 

139 yield child 

140 else: 

141 yield ((path + (k,)) , v) 

142 

143