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

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

49 statements  

1"""UNKNOWN values from :rfc:`7265`.""" 

2 

3from __future__ import annotations 

4 

5from typing import TYPE_CHECKING, Any, ClassVar 

6 

7from icalendar.error import JCalParsingError 

8from icalendar.parser import Parameters 

9from icalendar.parser_tools import DEFAULT_ENCODING, ICAL_TYPE, to_unicode 

10 

11if TYPE_CHECKING: 

12 from icalendar.compatibility import Self 

13 from icalendar.parser.content_line import Contentline 

14 

15 

16class vUnknown(str): 

17 """A property value of the :rfc:`7265#section-5` reserved UNKNOWN value data type. 

18 

19 .. versionchanged:: 7.2.0 

20 

21 Previously ``vUnknown`` inherited from ``vText``, which unescapes values. 

22 Now ``vUnknown`` doesn't unescape its values, which is the correct behavior. 

23 

24 Unlike :class:`~icalendar.prop.text.vText`, the value is preserved verbatim 

25 when imported from and exported to iCalendar data, without :rfc:`5545` escaping 

26 or unescaping. When the value type of an unrecognized property is not known, 

27 then no escaping rules can be applied, and the value must be preserved as is 

28 round-trip. 

29 

30 See also: 

31 

32 :rfc:`7265#section-5.1` 

33 """ 

34 

35 default_value: ClassVar[str] = "UNKNOWN" 

36 params: Parameters 

37 __slots__ = ("encoding", "params") 

38 

39 def __new__( 

40 cls, 

41 value: ICAL_TYPE, 

42 encoding: str = DEFAULT_ENCODING, 

43 /, 

44 params: dict[str, Any] | None = None, 

45 ) -> Self: 

46 value = to_unicode(value, encoding=encoding) 

47 self = super().__new__(cls, value) 

48 self.encoding = encoding 

49 self.params = Parameters(params) 

50 return self 

51 

52 def __repr__(self) -> str: 

53 return f"{self.__class__.__name__}({self.to_ical()!r})" 

54 

55 def to_ical(self) -> bytes: 

56 r"""Return the value verbatim, without :rfc:`5545` escaping. 

57 

58 This method's implementation is different from that in 

59 :class:`~icalendar.prop.text.vText`, whose 

60 :meth:`~icalendar.prop.text.vText.to_ical` method escapes ``;``, ``,``, 

61 ``\``, and newlines. 

62 

63 Example: 

64 

65 The semicolon is kept verbatim for UNKNOWN, unlike a TEXT value 

66 which would escape it as ``\\;``. 

67 

68 .. code-block:: pycon 

69 

70 >>> from icalendar.prop import vText, vUnknown 

71 >>> vUnknown("a;b").to_ical() 

72 b'a;b' 

73 >>> vText("a;b").to_ical() 

74 b'a\\;b' 

75 

76 See also: 

77 

78 :rfc:`7265#section-5.2` 

79 

80 """ 

81 return self.encode(self.encoding) 

82 

83 @classmethod 

84 def from_ical(cls, ical: ICAL_TYPE) -> Self: 

85 """Take the value verbatim, without unescaping.""" 

86 return cls(ical) 

87 

88 @classmethod 

89 def get_value_from_content_line(cls, line: Contentline) -> str: 

90 """Return this type's value from ``line``, taken verbatim. 

91 

92 Value types that must not have their value unescaped provide this 

93 method, and the parser uses it to obtain the value instead of 

94 :meth:`~icalendar.parser.content_line.Contentline.parts`. For 

95 :rfc:`7265` ``UNKNOWN`` values, the escaping rules of the real value 

96 type are not known, so no unescaping can be applied. 

97 """ 

98 return line.raw_parts()[2] 

99 

100 @property 

101 def ical_value(self) -> str: 

102 """The string value of the property.""" 

103 return str(self) 

104 

105 from icalendar.param import ALTREP, GAP, LANGUAGE, RELTYPE, VALUE 

106 

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

108 """The jCal representation of this property, according to :rfc:`7265#section-5.1`. 

109 

110 If the property doesn't include a VALUE property parameter and its value 

111 type is not known, then its value type is set to ``"unknown"``. Else the 

112 property's value type is converted to lowercase. 

113 

114 The property's value is the unprocessed value text, aside from standard 

115 JSON string escaping. 

116 """ 

117 return [name, self.params.to_jcal(), self.VALUE.lower(), str(self)] 

118 

119 @classmethod 

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

121 """Examples of vUnknown.""" 

122 return [cls("Some property text.")] 

123 

124 @classmethod 

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

126 """Parse jCal from :rfc:`7265`, taking the value verbatim. 

127 

128 Parameters: 

129 jcal_property: The jCal property to parse. 

130 

131 Raises: 

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

133 """ 

134 JCalParsingError.validate_property(jcal_property, cls) 

135 string = jcal_property[3] 

136 JCalParsingError.validate_value_type(string, str, cls, 3) 

137 return cls( 

138 string, 

139 params=Parameters.from_jcal_property(jcal_property), 

140 ) 

141 

142 @classmethod 

143 def parse_jcal_value(cls, jcal_value: Any) -> Self: 

144 """Parse a jCal value into a vUnknown.""" 

145 JCalParsingError.validate_value_type(jcal_value, (str, int, float), cls) 

146 return cls(str(jcal_value)) 

147 

148 

149__all__ = ["vUnknown"]