Source code for icalendar.prop.float
"""FLOAT values from :rfc:`5545`."""
import math
from typing import Any, ClassVar
from xml.etree.ElementTree import Element, SubElement
from icalendar.compatibility import Self
from icalendar.error import JCalParsingError
from icalendar.parser import Parameters
from icalendar.parser.xcal.base import XCalParser
from icalendar.parser.xcal.string import xsd_float_to_string
from icalendar.parser.xcal.wrapper import from_xcal_wrapper
[docs]
class vFloat(float):
"""Float
Value Name:
FLOAT
Purpose:
This value type is used to identify properties that contain
a real-number value.
Format Definition:
This value type is defined by the following notation:
.. code-block:: text
float = (["+"] / "-") 1*DIGIT ["." 1*DIGIT]
Description:
If the property permits, multiple "float" values are
specified by a COMMA-separated list of values.
Example:
.. code-block:: text
1000000.0000001
1.333
-3.14
.. code-block:: pycon
>>> from icalendar.prop import vFloat
>>> float = vFloat.from_ical('1000000.0000001')
>>> float
1000000.0000001
>>> float = vFloat.from_ical('1.333')
>>> float
1.333
>>> float = vFloat.from_ical('+1.333')
>>> float
1.333
>>> float = vFloat.from_ical('-3.14')
>>> float
-3.14
"""
default_value: ClassVar[str] = "FLOAT"
params: Parameters
def __new__(
cls, *args: Any, params: dict[str, Any] | None = None, **kwargs: Any
) -> Self:
self = super().__new__(cls, *args, **kwargs)
self.params = Parameters(params)
return self
[docs]
def to_ical(self) -> bytes:
return str(self).encode("utf-8")
[docs]
@classmethod
def from_ical(cls, ical: str | float) -> Self:
try:
self = cls(ical)
except Exception as e:
raise ValueError(f"Expected float value, got: {ical}") from e
if not math.isfinite(self):
raise ValueError(f"Expected finite float value, got: {ical}")
return self
[docs]
@classmethod
def examples(cls) -> list[Self]:
"""Examples of vFloat."""
return [cls(3.1415)]
from icalendar.param import VALUE
[docs]
def to_jcal(self, name: str) -> list:
"""The jCal representation of this property according to :rfc:`7265`."""
return [name, self.params.to_jcal(), self.VALUE.lower(), float(self)]
@property
def ical_value(self) -> float:
"""Converts the FLOAT property type according to :rfc:`5545#section-3.3.7` to a Python float."""
return float(self)
[docs]
@classmethod
def from_jcal(cls, jcal_property: list) -> Self:
"""Parse jCal from :rfc:`7265`.
Parameters:
jcal_property: The jCal property to parse.
Raises:
~icalendar.error.JCalParsingError: If the jCal provided is invalid.
"""
JCalParsingError.validate_property(jcal_property, cls)
if jcal_property[0].upper() == "GEO":
from icalendar.prop import vGeo
return vGeo.from_jcal(jcal_property)
JCalParsingError.validate_value_type(jcal_property[3], float, cls, 3)
return cls(
jcal_property[3],
params=Parameters.from_jcal_property(jcal_property),
)
[docs]
@classmethod
@from_xcal_wrapper
def from_xcal(cls, parser: XCalParser, params: Parameters) -> Self:
"""Parse xCal from :rfc:`6321`.
Parameters:
element: The xCal element to parse.
Raises:
~error.XCalParsingError: If the provided xCal is invalid.
"""
element = parser.parse_tag(cls.default_value)
value = element.get_xsd_float()
return cls(value, params=params)
[docs]
def to_xcal(self, element: Element) -> None:
"""Add the xCal representation of this property according to :rfc:`6321`."""
self.params.to_xcal(element)
element = SubElement(element, self.default_value.lower())
element.text = xsd_float_to_string(self)
__all__ = ["vFloat"]