Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/icalendar/prop/float.py: 54%

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

56 statements  

1"""FLOAT values from :rfc:`5545`.""" 

2 

3import math 

4from typing import Any, ClassVar 

5from xml.etree.ElementTree import Element, SubElement 

6 

7from icalendar.compatibility import Self 

8from icalendar.error import JCalParsingError 

9from icalendar.parser import Parameters 

10from icalendar.parser.xcal.base import XCalParser 

11from icalendar.parser.xcal.string import xsd_float_to_string 

12from icalendar.parser.xcal.wrapper import from_xcal_wrapper 

13 

14 

15class vFloat(float): 

16 """Float 

17 

18 Value Name: 

19 FLOAT 

20 

21 Purpose: 

22 This value type is used to identify properties that contain 

23 a real-number value. 

24 

25 Format Definition: 

26 This value type is defined by the following notation: 

27 

28 .. code-block:: text 

29 

30 float = (["+"] / "-") 1*DIGIT ["." 1*DIGIT] 

31 

32 Description: 

33 If the property permits, multiple "float" values are 

34 specified by a COMMA-separated list of values. 

35 

36 Example: 

37 

38 .. code-block:: text 

39 

40 1000000.0000001 

41 1.333 

42 -3.14 

43 

44 .. code-block:: pycon 

45 

46 >>> from icalendar.prop import vFloat 

47 >>> float = vFloat.from_ical('1000000.0000001') 

48 >>> float 

49 1000000.0000001 

50 >>> float = vFloat.from_ical('1.333') 

51 >>> float 

52 1.333 

53 >>> float = vFloat.from_ical('+1.333') 

54 >>> float 

55 1.333 

56 >>> float = vFloat.from_ical('-3.14') 

57 >>> float 

58 -3.14 

59 """ 

60 

61 default_value: ClassVar[str] = "FLOAT" 

62 params: Parameters 

63 

64 def __new__( 

65 cls, *args: Any, params: dict[str, Any] | None = None, **kwargs: Any 

66 ) -> Self: 

67 self = super().__new__(cls, *args, **kwargs) 

68 self.params = Parameters(params) 

69 return self 

70 

71 def to_ical(self) -> bytes: 

72 return str(self).encode("utf-8") 

73 

74 @classmethod 

75 def from_ical(cls, ical: str | float) -> Self: 

76 try: 

77 self = cls(ical) 

78 except Exception as e: 

79 raise ValueError(f"Expected float value, got: {ical}") from e 

80 if not math.isfinite(self): 

81 raise ValueError(f"Expected finite float value, got: {ical}") 

82 return self 

83 

84 @classmethod 

85 def examples(cls) -> list[Self]: 

86 """Examples of vFloat.""" 

87 return [cls(3.1415)] 

88 

89 from icalendar.param import VALUE 

90 

91 def to_jcal(self, name: str) -> list: 

92 """The jCal representation of this property according to :rfc:`7265`.""" 

93 return [name, self.params.to_jcal(), self.VALUE.lower(), float(self)] 

94 

95 @property 

96 def ical_value(self) -> float: 

97 """Converts the FLOAT property type according to :rfc:`5545#section-3.3.7` to a Python float.""" 

98 return float(self) 

99 

100 @classmethod 

101 def from_jcal(cls, jcal_property: list) -> Self: 

102 """Parse jCal from :rfc:`7265`. 

103 

104 Parameters: 

105 jcal_property: The jCal property to parse. 

106 

107 Raises: 

108 ~error.JCalParsingError: If the jCal provided is invalid. 

109 """ 

110 JCalParsingError.validate_property(jcal_property, cls) 

111 if jcal_property[0].upper() == "GEO": 

112 from icalendar.prop import vGeo 

113 

114 return vGeo.from_jcal(jcal_property) 

115 JCalParsingError.validate_value_type(jcal_property[3], float, cls, 3) 

116 return cls( 

117 jcal_property[3], 

118 params=Parameters.from_jcal_property(jcal_property), 

119 ) 

120 

121 @classmethod 

122 @from_xcal_wrapper 

123 def from_xcal(cls, parser: XCalParser, params: Parameters) -> Self: 

124 """Parse xCal from :rfc:`6321`. 

125 

126 Parameters: 

127 element: The xCal element to parse. 

128 

129 Raises: 

130 ~error.XCalParsingError: If the provided xCal is invalid. 

131 """ 

132 element = parser.parse_tag(cls.default_value) 

133 value = element.get_xsd_float() 

134 return cls(value, params=params) 

135 

136 def to_xcal(self, element: Element) -> None: 

137 """Add the xCal representation of this property according to :rfc:`6321`.""" 

138 self.params.to_xcal(element) 

139 element = SubElement(element, self.default_value.lower()) 

140 element.text = xsd_float_to_string(self) 

141 

142 

143__all__ = ["vFloat"]