diff --git a/stubs/icalendar/METADATA.toml b/stubs/icalendar/METADATA.toml index df95fc7f8..18d11b38f 100644 --- a/stubs/icalendar/METADATA.toml +++ b/stubs/icalendar/METADATA.toml @@ -1,6 +1,10 @@ -version = "~= 6.0.1" +version = "6.1.*" upstream_repository = "https://github.com/collective/icalendar" -requires = ["types-python-dateutil", "backports.zoneinfo; python_version<'3.9'"] +requires = [ + "types-python-dateutil", + "types-pytz", + "backports.zoneinfo; python_version<'3.9'", +] [tool.stubtest] stubtest_requirements = ["pytz"] diff --git a/stubs/icalendar/icalendar/__init__.pyi b/stubs/icalendar/icalendar/__init__.pyi index 7aa257843..b4651f094 100644 --- a/stubs/icalendar/icalendar/__init__.pyi +++ b/stubs/icalendar/icalendar/__init__.pyi @@ -1,3 +1,11 @@ +from .alarms import ( + Alarms as Alarms, + AlarmTime as AlarmTime, + ComponentEndMissing as ComponentEndMissing, + ComponentStartMissing as ComponentStartMissing, + IncompleteAlarmInformation as IncompleteAlarmInformation, + LocalTimezoneMissing as LocalTimezoneMissing, +) from .cal import ( Alarm as Alarm, Calendar as Calendar, @@ -87,4 +95,10 @@ __all__ = [ "vMonth", "IncompleteComponent", "InvalidCalendar", + "Alarms", + "AlarmTime", + "ComponentEndMissing", + "ComponentStartMissing", + "IncompleteAlarmInformation", + "LocalTimezoneMissing", ] diff --git a/stubs/icalendar/icalendar/alarms.pyi b/stubs/icalendar/icalendar/alarms.pyi new file mode 100644 index 000000000..52eab13aa --- /dev/null +++ b/stubs/icalendar/icalendar/alarms.pyi @@ -0,0 +1,54 @@ +import datetime +from typing_extensions import TypeAlias + +from .cal import Alarm, Event, Todo + +__all__ = [ + "Alarms", + "AlarmTime", + "IncompleteAlarmInformation", + "ComponentEndMissing", + "ComponentStartMissing", + "LocalTimezoneMissing", +] + +Parent: TypeAlias = Event | Todo + +class IncompleteAlarmInformation(ValueError): ... +class ComponentStartMissing(IncompleteAlarmInformation): ... +class ComponentEndMissing(IncompleteAlarmInformation): ... +class LocalTimezoneMissing(IncompleteAlarmInformation): ... + +class AlarmTime: + def __init__( + self, + alarm: Alarm, + trigger: datetime.datetime, + acknowledged_until: datetime.datetime | None = None, + snoozed_until: datetime.datetime | None = None, + parent: Parent | None = None, + ): ... + @property + def acknowledged(self) -> datetime.datetime | None: ... + @property + def alarm(self) -> Alarm: ... + @property + def parent(self) -> Parent | None: ... + def is_active(self) -> bool: ... + @property + def trigger(self) -> datetime.date: ... + +class Alarms: + def __init__(self, component: Alarm | Event | Todo | None = None): ... + def add_component(self, component: Alarm | Parent) -> None: ... + def set_parent(self, parent: Parent) -> None: ... + def add_alarm(self, alarm: Alarm) -> None: ... + def set_start(self, dt: datetime.date | None) -> None: ... + def set_end(self, dt: datetime.date | None) -> None: ... + def acknowledge_until(self, dt: datetime.date | None) -> None: ... + def snooze_until(self, dt: datetime.date | None) -> None: ... + def set_local_timezone(self, tzinfo: datetime.tzinfo | str | None) -> None: ... + @property + def times(self) -> list[AlarmTime]: ... + @property + def active(self) -> list[AlarmTime]: ... diff --git a/stubs/icalendar/icalendar/cal.pyi b/stubs/icalendar/icalendar/cal.pyi index 2b1b1542f..dfd516166 100644 --- a/stubs/icalendar/icalendar/cal.pyi +++ b/stubs/icalendar/icalendar/cal.pyi @@ -1,12 +1,14 @@ import datetime from _typeshed import Incomplete, SupportsItems from collections.abc import Callable -from typing import Any, ClassVar, Final, Literal, overload -from typing_extensions import TypeIs +from typing import Any, ClassVar, Final, Literal, NamedTuple, overload +from typing_extensions import Self +from .alarms import Alarms from .caselessdict import CaselessDict from .parser import Contentline, Contentlines from .prop import TypesFactory +from .timezone.tzp import TZP __all__ = [ "Alarm", @@ -37,6 +39,8 @@ INLINE: CaselessDict[int] class InvalidCalendar(ValueError): ... class IncompleteComponent(ValueError): ... +def create_utc_property(name: str, docs: str) -> property: ... + class Component(CaselessDict[Incomplete]): name: ClassVar[str | None] required: ClassVar[tuple[str, ...]] @@ -64,8 +68,8 @@ class Component(CaselessDict[Incomplete]): def get_inline(self, name, decode: bool = True): ... def set_inline(self, name, values, encode: bool = True) -> None: ... def add_component(self, component: Component) -> None: ... - def walk(self, name: str | None = None, select: Callable[[Component], bool] = ...): ... - def property_items(self, recursive: bool = True, sorted: bool = True): ... + def walk(self, name: str | None = None, select: Callable[[Component], bool] = ...) -> list[Component]: ... + def property_items(self, recursive: bool = True, sorted: bool = True) -> list[tuple[str, object]]: ... @overload @classmethod def from_ical(cls, st: str, multiple: Literal[False] = False) -> Component: ... # or any of its subclasses @@ -76,16 +80,27 @@ class Component(CaselessDict[Incomplete]): def content_lines(self, sorted: bool = True) -> Contentlines: ... def to_ical(self, sorted: bool = True) -> bytes: ... def __eq__(self, other: Component) -> bool: ... # type: ignore[override] + @property + def DTSTAMP(self) -> datetime.datetime | None: ... + @DTSTAMP.setter + def DTSTAMP(self, value: datetime.datetime) -> None: ... + @property + def LAST_MODIFIED(self) -> datetime.datetime | None: ... + @LAST_MODIFIED.setter + def LAST_MODIFIED(self, value: datetime.datetime) -> None: ... + def is_thunderbird(self) -> bool: ... # type_def is a TypeForm -def create_single_property(prop: str, value_attr: str, value_type: tuple[type, ...], type_def: Any, doc: str) -> property: ... -def is_date(dt: datetime.date) -> bool: ... # TypeIs[datetime.date and not datetime.datetime] -def is_datetime(dt: datetime.date) -> TypeIs[datetime.datetime]: ... +def create_single_property( + prop: str, value_attr: str | None, value_type: tuple[type, ...], type_def: Any, doc: str, vProp: type[Incomplete] = ... +) -> property: ... class Event(Component): name: ClassVar[Literal["VEVENT"]] + @property + def alarms(self) -> Alarms: ... @classmethod - def example(cls, name: str) -> Event: ... + def example(cls, name: str = "rfc_9074_example_3") -> Event: ... @property def DTSTART(self) -> datetime.date | datetime.datetime | None: ... @DTSTART.setter @@ -108,9 +123,49 @@ class Event(Component): def end(self) -> datetime.date | datetime.datetime: ... @end.setter def end(self, value: datetime.date | datetime.datetime | None) -> None: ... + @property + def X_MOZ_SNOOZE_TIME(self) -> datetime.datetime | None: ... + @X_MOZ_SNOOZE_TIME.setter + def X_MOZ_SNOOZE_TIME(self, value: datetime.datetime) -> None: ... + @property + def X_MOZ_LASTACK(self) -> datetime.datetime | None: ... + @X_MOZ_LASTACK.setter + def X_MOZ_LASTACK(self, value: datetime.datetime) -> None: ... class Todo(Component): name: ClassVar[Literal["VTODO"]] + @property + def DTSTART(self) -> datetime.datetime | datetime.date | None: ... + @DTSTART.setter + def DTSTART(self, value: datetime.datetime | datetime.date | None) -> None: ... + @property + def DUE(self) -> datetime.datetime | datetime.date | None: ... + @DUE.setter + def DUE(self, value: datetime.datetime | datetime.date | None) -> None: ... + @property + def DURATION(self) -> datetime.timedelta | None: ... + @DURATION.setter + def DURATION(self, value: datetime.timedelta | None) -> None: ... + @property + def start(self) -> datetime.datetime | datetime.date: ... + @start.setter + def start(self, value: datetime.datetime | datetime.date | None) -> None: ... + @property + def end(self) -> datetime.datetime | datetime.date: ... + @end.setter + def end(self, value: datetime.datetime | datetime.date | None) -> None: ... + @property + def duration(self) -> datetime.timedelta: ... + @property + def X_MOZ_SNOOZE_TIME(self) -> datetime.datetime | None: ... + @X_MOZ_SNOOZE_TIME.setter + def X_MOZ_SNOOZE_TIME(self, value: datetime.datetime) -> None: ... + @property + def X_MOZ_LASTACK(self) -> datetime.datetime | None: ... + @X_MOZ_LASTACK.setter + def X_MOZ_LASTACK(self, value: datetime.datetime) -> None: ... + @property + def alarms(self) -> Alarms: ... class Journal(Component): name: ClassVar[Literal["VJOURNAL"]] @@ -132,25 +187,96 @@ class FreeBusy(Component): class Timezone(Component): name: ClassVar[Literal["VTIMEZONE"]] @classmethod - def example(cls, name: str) -> Calendar: ... - def to_tz(self, tzp=...): ... # FIXME -> DstTzInfo: ... + def example(cls, name: str = "pacific_fiji") -> Calendar: ... + def to_tz(self, tzp: TZP = ..., lookup_tzid: bool = True) -> datetime.tzinfo: ... @property def tz_name(self) -> str: ... def get_transitions(self) -> tuple[list[datetime.datetime], list[tuple[datetime.timedelta, datetime.timedelta, str]]]: ... + @classmethod + def from_tzinfo( + cls, timezone: datetime.tzinfo, tzid: str | None = None, first_date: datetime.date = ..., last_date: datetime.date = ... + ) -> Self: ... + @classmethod + def from_tzid(cls, tzid: str, tzp: TZP = ..., first_date: datetime.date = ..., last_date: datetime.date = ...) -> Self: ... + @property + def standard(self) -> list[TimezoneStandard]: ... + @property + def daylight(self) -> list[TimezoneDaylight]: ... class TimezoneStandard(Component): name: ClassVar[Literal["STANDARD"]] + @property + def DTSTART(self) -> datetime.date | datetime.datetime | None: ... + @DTSTART.setter + def DTSTART(self, value: datetime.date | datetime.datetime | None) -> None: ... + @property + def TZOFFSETTO(self) -> datetime.timedelta | None: ... + @TZOFFSETTO.setter + def TZOFFSETTO(self, value: datetime.timedelta | None) -> None: ... + @property + def TZOFFSETFROM(self) -> datetime.timedelta | None: ... + @TZOFFSETFROM.setter + def TZOFFSETFROM(self, value: datetime.timedelta | None) -> None: ... class TimezoneDaylight(Component): name: ClassVar[Literal["DAYLIGHT"]] + @property + def DTSTART(self) -> datetime.date | datetime.datetime | None: ... + @DTSTART.setter + def DTSTART(self, value: datetime.date | datetime.datetime | None) -> None: ... + @property + def TZOFFSETTO(self) -> datetime.timedelta | None: ... + @TZOFFSETTO.setter + def TZOFFSETTO(self, value: datetime.timedelta | None) -> None: ... + @property + def TZOFFSETFROM(self) -> datetime.timedelta | None: ... + @TZOFFSETFROM.setter + def TZOFFSETFROM(self, value: datetime.timedelta | None) -> None: ... class Alarm(Component): name: ClassVar[Literal["VALARM"]] + @property + def REPEAT(self) -> int: ... + @REPEAT.setter + def REPEAT(self, value: int) -> None: ... + @property + def DURATION(self) -> datetime.timedelta | None: ... + @DURATION.setter + def DURATION(self, value: datetime.timedelta | None) -> None: ... + @property + def ACKNOWLEDGED(self) -> datetime.datetime | None: ... + @ACKNOWLEDGED.setter + def ACKNOWLEDGED(self, value: datetime.datetime | None) -> None: ... + @property + def TRIGGER(self) -> datetime.timedelta | datetime.datetime | None: ... + @TRIGGER.setter + def TRIGGER(self, value: datetime.timedelta | datetime.datetime | None) -> None: ... + @property + def TRIGGER_RELATED(self) -> Literal["START", "END"]: ... + @TRIGGER_RELATED.setter + def TRIGGER_RELATED(self, value: Literal["START", "END"]) -> None: ... + + class Triggers(NamedTuple): + start: tuple[datetime.timedelta, ...] + end: tuple[datetime.timedelta, ...] + absolute: tuple[datetime.datetime, ...] + + @property + def triggers(self) -> Alarm.Triggers: ... class Calendar(Component): name: ClassVar[Literal["VCALENDAR"]] @classmethod - def example(cls, name: str) -> Calendar: ... + def example(cls, name: str = "example") -> Calendar: ... + @property + def events(self) -> list[Event]: ... + @property + def todos(self) -> list[Todo]: ... + def get_used_tzids(self) -> set[str]: ... + def get_missing_tzids(self) -> set[str]: ... + @property + def timezones(self) -> list[Timezone]: ... + def add_missing_timezones(self, first_date: datetime.date = ..., last_date: datetime.date = ...) -> None: ... types_factory: Final[TypesFactory] component_factory: Final[ComponentFactory] diff --git a/stubs/icalendar/icalendar/prop.pyi b/stubs/icalendar/icalendar/prop.pyi index 5256204cc..17d79298b 100644 --- a/stubs/icalendar/icalendar/prop.pyi +++ b/stubs/icalendar/icalendar/prop.pyi @@ -9,13 +9,13 @@ from typing_extensions import Self, TypeAlias from .caselessdict import CaselessDict from .parser import Parameters from .parser_tools import ICAL_TYPE +from .timezone import tzid_from_dt as tzid_from_dt, tzid_from_tzinfo as tzid_from_tzinfo __all__ = [ "DURATION_REGEX", "TimeBase", "TypesFactory", "WEEKDAY_RULE", - "tzid_from_dt", "vBinary", "vBoolean", "vCalAddress", @@ -39,6 +39,8 @@ __all__ = [ "vUTCOffset", "vUri", "vWeekday", + "tzid_from_dt", + "tzid_from_tzinfo", ] _PropType: TypeAlias = type[Any] # any of the v* classes in this file @@ -47,8 +49,6 @@ _vRecurT = TypeVar("_vRecurT", bound=vRecur) DURATION_REGEX: Final[Pattern[str]] WEEKDAY_RULE: Final[Pattern[str]] -def tzid_from_dt(dt: datetime.datetime) -> str | None: ... - class vBinary: obj: Incomplete params: Parameters @@ -140,7 +140,7 @@ class vDatetime(TimeBase): def __init__(self, dt) -> None: ... def to_ical(self) -> bytes: ... @staticmethod - def from_ical(ical, timezone: str | None = None) -> datetime.datetime: ... + def from_ical(ical, timezone: datetime.timezone | str | None = None) -> datetime.datetime: ... class vDuration(TimeBase): td: Incomplete @@ -241,13 +241,14 @@ class vGeo: class vUTCOffset: ignore_exceptions: bool - td: Incomplete + td: datetime.timedelta params: Parameters - def __init__(self, td) -> None: ... + def __init__(self, td: datetime.timedelta) -> None: ... def to_ical(self) -> bytes: ... @classmethod def from_ical(cls, ical): ... - def __eq__(self, other): ... + def __eq__(self, other: object) -> bool: ... + def __hash__(self) -> int: ... class vInline(str): params: Parameters diff --git a/stubs/icalendar/icalendar/timezone/__init__.pyi b/stubs/icalendar/icalendar/timezone/__init__.pyi index a7021d39f..4cd6dade8 100644 --- a/stubs/icalendar/icalendar/timezone/__init__.pyi +++ b/stubs/icalendar/icalendar/timezone/__init__.pyi @@ -1,6 +1,7 @@ -from ..timezone.tzp import TZP # to prevent "tzp" from being defined here +from ..timezone.tzp import TZP as TZP # to prevent "tzp" from being defined here +from .tzid import tzid_from_dt as tzid_from_dt, tzid_from_tzinfo as tzid_from_tzinfo, tzids_from_tzinfo as tzids_from_tzinfo -__all__ = ["tzp", "use_pytz", "use_zoneinfo"] +__all__ = ["TZP", "tzp", "use_pytz", "use_zoneinfo", "tzid_from_tzinfo", "tzid_from_dt", "tzids_from_tzinfo"] tzp: TZP diff --git a/stubs/icalendar/icalendar/timezone/equivalent_timezone_ids.pyi b/stubs/icalendar/icalendar/timezone/equivalent_timezone_ids.pyi new file mode 100644 index 000000000..046385bb0 --- /dev/null +++ b/stubs/icalendar/icalendar/timezone/equivalent_timezone_ids.pyi @@ -0,0 +1,15 @@ +import datetime +from collections.abc import Callable +from typing import Final + +__all__ = ["main"] + +def check(dt: datetime.datetime, tz: datetime.tzinfo) -> tuple[datetime.datetime, datetime.timedelta]: ... +def checks(tz: datetime.tzinfo) -> list[tuple[datetime.datetime, datetime.timedelta]]: ... + +START: Final[datetime.datetime] +END: Final[datetime.datetime] + +DTS: Final[list[datetime.datetime]] + +def main(create_timezones: list[Callable[[str], datetime.tzinfo]], name: str, pool_size: int = ...) -> None: ... diff --git a/stubs/icalendar/icalendar/timezone/equivalent_timezone_ids_result.pyi b/stubs/icalendar/icalendar/timezone/equivalent_timezone_ids_result.pyi new file mode 100644 index 000000000..db990d137 --- /dev/null +++ b/stubs/icalendar/icalendar/timezone/equivalent_timezone_ids_result.pyi @@ -0,0 +1,6 @@ +from _typeshed import Incomplete +from typing import Final + +__all__ = ["lookup"] + +lookup: Final[Incomplete] diff --git a/stubs/icalendar/icalendar/timezone/tzid.pyi b/stubs/icalendar/icalendar/timezone/tzid.pyi new file mode 100644 index 000000000..c70bc41cf --- /dev/null +++ b/stubs/icalendar/icalendar/timezone/tzid.pyi @@ -0,0 +1,8 @@ +import datetime + +__all__ = ["tzid_from_tzinfo", "tzid_from_dt", "tzids_from_tzinfo"] + +def tzids_from_tzinfo(tzinfo: datetime.tzinfo | None) -> tuple[str, ...]: ... +def tzid_from_tzinfo(tzinfo: datetime.tzinfo | None) -> str | None: ... +def tzid_from_dt(dt: datetime.datetime) -> str | None: ... +def tzinfo2tzids(tzinfo: datetime.tzinfo | None) -> set[str]: ... diff --git a/stubs/icalendar/icalendar/timezone/tzp.pyi b/stubs/icalendar/icalendar/timezone/tzp.pyi index 0796edc88..7a2102561 100644 --- a/stubs/icalendar/icalendar/timezone/tzp.pyi +++ b/stubs/icalendar/icalendar/timezone/tzp.pyi @@ -17,8 +17,8 @@ class TZP: def use_zoneinfo(self) -> None: ... def use(self, provider: str | TZProvider) -> None: ... def use_default(self) -> None: ... - def localize_utc(self, dt: datetime.datetime) -> datetime.datetime: ... - def localize(self, dt: datetime.datetime, tz: datetime.tzinfo | str) -> datetime.datetime: ... + def localize_utc(self, dt: datetime.date) -> datetime.datetime: ... + def localize(self, dt: datetime.date, tz: datetime.tzinfo | str) -> datetime.datetime: ... def cache_timezone_component(self, timezone_component: Timezone) -> None: ... def fix_rrule_until(self, rrule: rrule, ical_rrule: vRecur) -> None: ... def create_timezone(self, timezone_component: Timezone) -> datetime.tzinfo: ... diff --git a/stubs/icalendar/icalendar/tools.pyi b/stubs/icalendar/icalendar/tools.pyi index 6b9dd1480..d58219227 100644 --- a/stubs/icalendar/icalendar/tools.pyi +++ b/stubs/icalendar/icalendar/tools.pyi @@ -1,8 +1,12 @@ +import datetime from typing import Final +from typing_extensions import TypeGuard, TypeIs + +from pytz.tzinfo import BaseTzInfo from .prop import vText -__all__ = ["UIDGenerator"] +__all__ = ["UIDGenerator", "is_date", "is_datetime", "to_datetime", "is_pytz", "is_pytz_dt", "normalize_pytz"] class UIDGenerator: chars: Final[list[str]] @@ -10,3 +14,10 @@ class UIDGenerator: def rnd_string(length: int = 16) -> str: ... @staticmethod def uid(host_name: str = "example.com", unique: str = "") -> vText: ... + +def is_date(dt: datetime.date) -> bool: ... # and not datetime.date +def is_datetime(dt: datetime.date) -> TypeIs[datetime.datetime]: ... +def to_datetime(dt: datetime.date) -> datetime.datetime: ... +def is_pytz(tz: datetime.tzinfo) -> TypeIs[BaseTzInfo]: ... +def is_pytz_dt(dt: datetime.date) -> TypeGuard[datetime.datetime]: ... # and dt.tzinfo is BaseTZInfo +def normalize_pytz(dt: datetime.date) -> datetime.datetime: ...