Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/openpyxl/descriptors/sequence.py: 41%

64 statements  

« prev     ^ index     » next       coverage.py v6.4.4, created at 2023-07-17 14:22 -0600

1# copyright openpyxl 2010-2015 

2 

3from openpyxl.compat import safe_string 

4from openpyxl.xml.functions import Element 

5from openpyxl.utils.indexed_list import IndexedList 

6 

7from .base import Descriptor, Alias, _convert 

8from .namespace import namespaced 

9 

10 

11class Sequence(Descriptor): 

12 """ 

13 A sequence (list or tuple) that may only contain objects of the declared 

14 type 

15 """ 

16 

17 expected_type = type(None) 

18 seq_types = (list, tuple) 

19 idx_base = 0 

20 unique = False 

21 

22 

23 def __set__(self, instance, seq): 

24 if not isinstance(seq, self.seq_types): 

25 raise TypeError("Value must be a sequence") 

26 seq = [_convert(self.expected_type, value) for value in seq] 

27 if self.unique: 

28 seq = IndexedList(seq) 

29 

30 super(Sequence, self).__set__(instance, seq) 

31 

32 

33 def to_tree(self, tagname, obj, namespace=None): 

34 """ 

35 Convert the sequence represented by the descriptor to an XML element 

36 """ 

37 for idx, v in enumerate(obj, self.idx_base): 

38 if hasattr(v, "to_tree"): 

39 el = v.to_tree(tagname, idx) 

40 else: 

41 tagname = namespaced(obj, tagname, namespace) 

42 el = Element(tagname) 

43 el.text = safe_string(v) 

44 yield el 

45 

46 

47class ValueSequence(Sequence): 

48 """ 

49 A sequence of primitive types that are stored as a single attribute. 

50 "val" is the default attribute 

51 """ 

52 

53 attribute = "val" 

54 

55 

56 def to_tree(self, tagname, obj, namespace=None): 

57 tagname = namespaced(self, tagname, namespace) 

58 for v in obj: 

59 yield Element(tagname, {self.attribute:safe_string(v)}) 

60 

61 

62 def from_tree(self, node): 

63 

64 return node.get(self.attribute) 

65 

66 

67class NestedSequence(Sequence): 

68 """ 

69 Wrap a sequence in an containing object 

70 """ 

71 

72 count = False 

73 

74 def to_tree(self, tagname, obj, namespace=None): 

75 tagname = namespaced(self, tagname, namespace) 

76 container = Element(tagname) 

77 if self.count: 

78 container.set('count', str(len(obj))) 

79 for v in obj: 

80 container.append(v.to_tree()) 

81 return container 

82 

83 

84 def from_tree(self, node): 

85 return [self.expected_type.from_tree(el) for el in node] 

86 

87 

88class MultiSequence(Sequence): 

89 """ 

90 Sequences can contain objects with different tags 

91 """ 

92 

93 def __set__(self, instance, seq): 

94 if not isinstance(seq, (tuple, list)): 

95 raise ValueError("Value must be a sequence") 

96 seq = list(seq) 

97 Descriptor.__set__(self, instance, seq) 

98 

99 

100 def to_tree(self, tagname, obj, namespace=None): 

101 """ 

102 Convert the sequence represented by the descriptor to an XML element 

103 """ 

104 for v in obj: 

105 el = v.to_tree(namespace=namespace) 

106 yield el 

107 

108 

109class MultiSequencePart(Alias): 

110 """ 

111 Allow a multisequence to be built up from parts 

112 

113 Excluded from the instance __elements__ or __attrs__ as is effectively an Alias 

114 """ 

115 

116 def __init__(self, expected_type, store): 

117 self.expected_type = expected_type 

118 self.store = store 

119 

120 

121 def __set__(self, instance, value): 

122 value = _convert(self.expected_type, value) 

123 instance.__dict__[self.store].append(value) 

124 

125 

126 def __get__(self, instance, cls): 

127 return self