Source code for icalendar.prop.dt.list

from collections.abc import Sequence
from datetime import date, datetime
from typing import Any, ClassVar
from xml.etree.ElementTree import Element

from icalendar.compatibility import Self
from icalendar.error import JCalParsingError, XCalParsingError
from icalendar.parser import Parameters
from icalendar.parser.xcal.base import XCalParser
from icalendar.parser.xcal.wrapper import from_xcal_wrapper
from icalendar.parser_tools import from_unicode

from .base import TimeBase
from .types import vDDDTypes


[docs] class vDDDLists: """A list of vDDDTypes values.""" default_value: ClassVar[str] = "DATE-TIME" params: Parameters dts: list[vDDDTypes] def __init__(self, dt_list, params: dict[str, Any] | None = None) -> None: if params is None: params = {} if not hasattr(dt_list, "__iter__") or ( isinstance(dt_list, Sequence) and len(dt_list) == 2 and dt_list[1] is None ): # A ``(dt, None)`` pair (tuple or list) is the rdates form of a single # date, not a list of two values, so don't iterate it element-wise (#1439). dt_list = [dt_list] vddd = [] tzid = None for dt_l in dt_list: dt = vDDDTypes(dt_l) if not isinstance(dt_l, vDDDTypes) else dt_l vddd.append(dt) if "TZID" in dt.params: tzid = dt.params["TZID"] if tzid: # NOTE: no support for multiple timezones here! params["TZID"] = tzid self.params = Parameters(params) self.dts = vddd
[docs] def to_ical(self): dts_ical = (from_unicode(dt.to_ical()) for dt in self.dts) return b",".join(dts_ical)
[docs] @staticmethod def from_ical(ical, timezone=None): out = [] ical_dates = ical.split(",") for ical_dt in ical_dates: out.append(vDDDTypes.from_ical(ical_dt, timezone=timezone)) return out
def __eq__(self, other): if isinstance(other, vDDDLists): return self.dts == other.dts if isinstance(other, (TimeBase, date)): return self.dts == [other] return False def __repr__(self): """String representation.""" return f"{self.__class__.__name__}({self.dts})"
[docs] @classmethod def examples(cls) -> list[Self]: """Examples of vDDDLists.""" return [cls([datetime(2025, 11, 10, 16, 50)])]
[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(), *[dt.to_jcal(name)[3] for dt in self.dts], ]
def _get_value(self) -> str | None: return None if not self.dts else self.dts[0].VALUE from icalendar.param import VALUE
[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) values = jcal_property[3:] prop = jcal_property[:3] dts = [] for value in values: dts.append(vDDDTypes.from_jcal(prop + [value])) return cls( dts, params=Parameters.from_jcal_property(jcal_property), )
__hash__ = None @property def dt(self) -> TimeBase: """Return the time/date value of the list. This is a compatibility method for the vDDDTypes interface. Returns: The first value of the list. Raises: IndexError: If the list is empty. """ return self.dts[0].dt
[docs] def to_xcal(self, element: Element) -> None: """Convert a vDDDTypes to an xCal element.""" self.params.to_xcal(element) for dt in self.dts: dt.to_xcal(element)
[docs] @classmethod @from_xcal_wrapper def from_xcal(cls, parser: XCalParser, params: Parameters) -> Self: """Parse xCal from :rfc:`6321`. Parameters: xml: The XML to parse or a parser. Raises: ~error.XCalParsingError: If the provided xCal is invalid. """ dts = [] while not parser.is_finished(): dts.append(vDDDTypes.from_xcal(parser)) if dts: tz = getattr(dts[0].dt, "tzinfo", None) for dt in dts[1:]: if getattr(dt.dt, "tzinfo", None) != tz: raise XCalParsingError( "Cannot mix floating with UTC", None, parser.element ) return cls( dts, params=params, )
__all__ = ["vDDDLists"]