Coverage for lib/lottie/parsers/sif/xml/core_nodes.py: 85%

103 statements  

« prev     ^ index     » next       coverage.py v7.2.2, created at 2023-03-20 16:17 +0100

1from xml.dom import minidom 

2import copy 

3from uuid import uuid4 

4 

5from .utils import * 

6from lottie.parsers.sif.sif.core import ObjectRegistry 

7 

8 

9class XmlDescriptor: 

10 def __init__(self, name): 

11 self.name = name 

12 self.att_name = name.replace("-", "_").replace("[", "_").replace("]", "").replace(".", "_") 

13 

14 def to_xml(self, obj, parent: minidom.Element, dom: minidom.Document): 

15 raise NotImplementedError 

16 

17 def from_xml(self, obj, parent: minidom.Element, registry: ObjectRegistry): 

18 raise NotImplementedError 

19 

20 def from_python(self, value): 

21 raise NotImplementedError 

22 

23 def initialize_object(self, dict, obj): 

24 if self.att_name in dict: 

25 setattr(obj, self.att_name, self.from_python(dict[self.att_name])) 

26 else: 

27 setattr(obj, self.att_name, self.default()) 

28 

29 def clean(self, value): 

30 return self.from_python(value) 

31 

32 def default(self): 

33 return None 

34 

35 def __repr__(self): 

36 return "%s(%r)" % (self.__class__.__name__, self.name) 

37 

38 

39class TypedXmlDescriptor(XmlDescriptor): 

40 def __init__(self, name, type=str, default_value=None, att_name=None): 

41 super().__init__(name) 

42 self.type = type 

43 self.default_value = default_value 

44 if att_name is not None: 

45 self.att_name = att_name 

46 

47 def from_python(self, value): 

48 if value is None and self.default_value is None: 

49 return None 

50 if not value_isinstance(value, self.type): 

51 return self.type(value) 

52 return value 

53 

54 def default(self): 

55 return copy.deepcopy(self.default_value) 

56 

57 

58class ValueReference: 

59 def __init__(self, id, value=None): 

60 self.value = value 

61 self.id = id 

62 

63 @classmethod 

64 def from_registry(cls, id, registry: ObjectRegistry): 

65 return cls(id, registry.get_object(id)) 

66 

67 

68class XmlAttribute(TypedXmlDescriptor): 

69 def from_xml(self, obj, parent: minidom.Element, registry: ObjectRegistry): 

70 xml_str = parent.getAttribute(self.name) 

71 if xml_str: 

72 if xml_str.startswith(":") and xml_str[1:] in registry.registry: 72 ↛ 73line 72 didn't jump to line 73, because the condition on line 72 was never true

73 value = ValueReference.from_registry(xml_str[1:], registry) 

74 else: 

75 value = value_from_xml_string(xml_str, self.type, registry) 

76 setattr(obj, self.att_name, value) 

77 

78 def to_xml(self, obj, parent: minidom.Element, dom: minidom.Document): 

79 value = getattr(obj, self.att_name) 

80 if value is not None: 80 ↛ exitline 80 didn't return from function 'to_xml', because the condition on line 80 was never false

81 if isinstance(value, ValueReference): 81 ↛ 82line 81 didn't jump to line 82, because the condition on line 81 was never true

82 xml_str = ":" + value.id 

83 else: 

84 xml_str = value_to_xml_string(value, self.type) 

85 parent.setAttribute(self.name, xml_str) 

86 

87 

88class XmlFixedAttribute(XmlDescriptor): 

89 def __init__(self, name, value, type=str): 

90 super().__init__(name) 

91 self.value = value 

92 self.type = type 

93 

94 def to_xml(self, obj, parent: minidom.Element, dom: minidom.Document): 

95 parent.setAttribute(self.name, value_to_xml_string(self.value, self.type)) 

96 

97 def from_python(self, value): 

98 if value != self.value: 98 ↛ 99line 98 didn't jump to line 99, because the condition on line 98 was never true

99 raise ValueError("Value of %s should be %s, got %s" % (self.name, self.value, value)) 

100 return value 

101 

102 def from_xml(self, obj, parent: minidom.Element, registry: ObjectRegistry): 

103 xml_str = parent.getAttribute(self.name) 

104 setattr(obj, self.att_name, value_from_xml_string(xml_str, self.type, registry)) 

105 

106 def default(self): 

107 return self.value 

108 

109 

110class XmlSimpleElement(TypedXmlDescriptor): 

111 def from_xml(self, obj, parent: minidom.Element, registry: ObjectRegistry): 

112 cn = xml_first_element_child(parent, self.name, allow_none=True) 

113 if cn: 113 ↛ 116line 113 didn't jump to line 116, because the condition on line 113 was never false

114 value = value_from_xml_string(xml_text(cn), self.type, registry) 

115 else: 

116 value = self.default_value 

117 

118 setattr(obj, self.att_name, value) 

119 

120 def to_xml(self, obj, parent: minidom.Element, dom: minidom.Document): 

121 value = getattr(obj, self.att_name) 

122 if value is not None: 122 ↛ exitline 122 didn't return from function 'to_xml', because the condition on line 122 was never false

123 parent.appendChild(xml_make_text(dom, self.name, value_to_xml_string(value, self.type))) 

124 

125 

126class XmlMeta(TypedXmlDescriptor): 

127 def from_xml(self, obj, parent: minidom.Element, registry: ObjectRegistry): 

128 for cn in xml_child_elements(parent, "meta"): 128 ↛ 133line 128 didn't jump to line 133, because the loop on line 128 didn't complete

129 if cn.getAttribute("name") == self.name: 

130 value = value_from_xml_string(cn.getAttribute("content"), self.type, registry) 

131 break 

132 else: 

133 value = self.default_value 

134 

135 setattr(obj, self.att_name, value) 

136 

137 def to_xml(self, obj, parent: minidom.Element, dom: minidom.Document): 

138 value = getattr(obj, self.att_name) 

139 if value is not None: 139 ↛ exitline 139 didn't return from function 'to_xml', because the condition on line 139 was never false

140 meta = parent.appendChild(dom.createElement("meta")) 

141 meta.setAttribute("name", self.name) 

142 meta.setAttribute("content", value_to_xml_string(value, self.type))