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 warnings
12from typing import TYPE_CHECKING
13
14try:
15 from typing import Self
16except ImportError:
17 try:
18 from typing_extensions import Self
19 except ImportError:
20 Self = "Self"
21
22if TYPE_CHECKING:
23 import sys
24 from typing import TypeGuard
25
26 if sys.version_info >= (3, 13):
27 from typing import TypeIs
28 else:
29 from typing_extensions import TypeIs
30 if sys.version_info >= (3, 11):
31 from typing import Self
32 else:
33 from typing_extensions import Self
34else:
35 # we cannot use a TypeGuard = "TypeGuard" hack since it's used with a parameter
36 TypeGuard = TypeIs = Self = None
37
38
39def deprecate_for_version_8(func):
40 """Issue a warning for deprecated functions to be removed in version 8."""
41 public_name = func.__name__.removeprefix("_")
42
43 @functools.wraps(func)
44 def wrapper(*args, **kwargs):
45 warnings.warn(
46 f"{public_name} is deprecated and will be removed in icalendar 8",
47 DeprecationWarning,
48 stacklevel=2,
49 )
50 wrapper.__name__ = public_name
51 return func(*args, **kwargs)
52
53 return wrapper
54
55
56__all__ = [
57 "Self",
58 "TypeGuard",
59 "TypeIs",
60 "deprecate_for_version_8",
61]