1"""This module contains compatibility code for different Python versions.
2
3All compatibility checks and imports should go here.
4This way, we can centralize the handling of different Python versions.
5
6Do NOT import this module directly if you use icalendar.
7Members will be added and removed without deprecation warnings.
8"""
9
10import functools
11import sys
12import warnings
13from collections.abc import Callable
14from typing import ParamSpec, TypeGuard, TypeVar
15
16P = ParamSpec("P")
17R = TypeVar("R")
18
19if sys.version_info >= (3, 11):
20 from typing import Self
21else:
22 from typing_extensions import Self
23
24if sys.version_info >= (3, 13):
25 from typing import TypeIs
26else:
27 from typing_extensions import TypeIs
28
29
30def deprecate_for_version_9(func: Callable[P, R]) -> Callable[P, R]:
31 """Issue a warning for deprecated functions to be removed in version 9."""
32 public_name = func.__name__.removeprefix("_")
33
34 @functools.wraps(func)
35 def wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
36 warnings.warn(
37 f"{public_name} is deprecated and will be removed in icalendar 9",
38 DeprecationWarning,
39 stacklevel=2,
40 )
41 wrapper.__name__ = public_name
42 return func(*args, **kwargs)
43
44 return wrapper
45
46
47__all__ = [
48 "Self",
49 "TypeGuard",
50 "TypeIs",
51 "deprecate_for_version_9",
52]