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
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
1# copyright openpyxl 2010-2015
3from openpyxl.compat import safe_string
4from openpyxl.xml.functions import Element
5from openpyxl.utils.indexed_list import IndexedList
7from .base import Descriptor, Alias, _convert
8from .namespace import namespaced
11class Sequence(Descriptor):
12 """
13 A sequence (list or tuple) that may only contain objects of the declared
14 type
15 """
17 expected_type = type(None)
18 seq_types = (list, tuple)
19 idx_base = 0
20 unique = False
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)
30 super(Sequence, self).__set__(instance, seq)
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
47class ValueSequence(Sequence):
48 """
49 A sequence of primitive types that are stored as a single attribute.
50 "val" is the default attribute
51 """
53 attribute = "val"
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)})
62 def from_tree(self, node):
64 return node.get(self.attribute)
67class NestedSequence(Sequence):
68 """
69 Wrap a sequence in an containing object
70 """
72 count = False
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
84 def from_tree(self, node):
85 return [self.expected_type.from_tree(el) for el in node]
88class MultiSequence(Sequence):
89 """
90 Sequences can contain objects with different tags
91 """
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)
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
109class MultiSequencePart(Alias):
110 """
111 Allow a multisequence to be built up from parts
113 Excluded from the instance __elements__ or __attrs__ as is effectively an Alias
114 """
116 def __init__(self, expected_type, store):
117 self.expected_type = expected_type
118 self.store = store
121 def __set__(self, instance, value):
122 value = _convert(self.expected_type, value)
123 instance.__dict__[self.store].append(value)
126 def __get__(self, instance, cls):
127 return self