Skip to content

Commit ba11972

Browse files
BoboTiGlev-bliteigenmannmartin
authored
feat: type annotations (#165)
* feat: type annotations * fix tests accordingly * cast to timezone * guard more imports on icalendar version * remove bad import from merge resolve * chore: apply suggestions Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Lev Blit <levblt1@gmail.com> Co-authored-by: Martin Eigenmann <eigenmannmartin@users.noreply.github.com>
1 parent eacbe3d commit ba11972

8 files changed

Lines changed: 145 additions & 111 deletions

File tree

MANIFEST.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
recursive-include test *.ics *.txt
1+
recursive-include test *.ics *.txt py.typed

icalevents/icaldownload.py

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,15 @@
22
Downloads an iCal url or reads an iCal file.
33
"""
44

5+
from __future__ import annotations
6+
7+
from contextlib import suppress
8+
from pathlib import Path
9+
510
import urllib3
6-
import logging
711

812

9-
def apple_data_fix(content):
13+
def apple_data_fix(content: str) -> str:
1014
"""
1115
Fix Apple tzdata bug.
1216
@@ -16,7 +20,7 @@ def apple_data_fix(content):
1620
return content.replace("TZOFFSETFROM:+5328", "TZOFFSETFROM:+0053")
1721

1822

19-
def apple_url_fix(url):
23+
def apple_url_fix(url: str) -> str:
2024
"""
2125
Fix Apple URL.
2226
@@ -33,17 +37,14 @@ class ICalDownload:
3337
Downloads or reads and decodes iCal sources.
3438
"""
3539

36-
def __init__(self, http=None):
37-
# Get logger
38-
logger = logging.getLogger()
39-
40+
def __init__(self, http: urllib3.PoolManager | None = None) -> None:
4041
# default http connection to use
4142
if http is None:
4243
http = urllib3.PoolManager()
4344

4445
self.http = http
4546

46-
def data_from_url(self, url, apple_fix=False):
47+
def data_from_url(self, url: str, apple_fix: bool = False) -> str:
4748
"""
4849
Download iCal data from URL.
4950
@@ -59,16 +60,14 @@ def data_from_url(self, url, apple_fix=False):
5960
if not response.data:
6061
raise ConnectionError("Could not get data from %s!" % url)
6162

62-
content_type = response.headers.get("content-type")
63-
64-
try:
65-
encoding = content_type.split("charset=")[1]
66-
except (AttributeError, IndexError):
67-
encoding = "utf-8"
63+
encoding = "utf-8"
64+
if content_type := response.headers.get("content-type"):
65+
with suppress(AttributeError, IndexError):
66+
encoding = content_type.split("charset=")[1]
6867

6968
return self.decode(response.data, encoding, apple_fix=apple_fix)
7069

71-
def data_from_file(self, file, apple_fix=False):
70+
def data_from_file(self, file: str | Path, apple_fix: bool = False) -> str:
7271
"""
7372
Read iCal data from file.
7473
@@ -84,14 +83,18 @@ def data_from_file(self, file, apple_fix=False):
8483

8584
return self.decode(content, apple_fix=apple_fix)
8685

87-
def data_from_string(self, string_content, apple_fix=False):
86+
def data_from_string(
87+
self, string_content: bytes | str, apple_fix: bool = False
88+
) -> str:
8889
if not string_content:
8990
raise OSError("String content is not readable or is empty!")
9091

9192
return self.decode(string_content, apple_fix=apple_fix)
9293

9394
@staticmethod
94-
def decode(content, encoding="utf-8", apple_fix=False):
95+
def decode(
96+
content: bytes | str, encoding: str = "utf-8", apple_fix: bool = False
97+
) -> str:
9598
"""
9699
Decode content using the set charset.
97100

icalevents/icalevents.py

Lines changed: 42 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,34 @@
1+
from __future__ import annotations
2+
3+
from datetime import datetime, tzinfo as _tzinfo
4+
from pathlib import Path
15
from threading import Lock, Thread
26

3-
from .icalparser import parse_events, Event
7+
import urllib3
8+
9+
from .icalparser import Event, parse_events
410
from .icaldownload import ICalDownload
511

612

713
# Lock for event data
814
event_lock = Lock()
915
# Event data
10-
event_store = {}
16+
event_store: dict[str, list[Event]] = {}
1117
# Threads
12-
threads = {}
18+
threads: dict[str, list[Thread]] = {}
1319

1420

1521
def events(
16-
url=None,
17-
file=None,
18-
string_content=None,
19-
start=None,
20-
end=None,
21-
fix_apple=False,
22-
http=None,
23-
tzinfo=None,
24-
sort=None,
25-
strict=False,
22+
url: str | None = None,
23+
file: str | Path | None = None,
24+
string_content: bytes | str | None = None,
25+
start: datetime | None = None,
26+
end: datetime | None = None,
27+
fix_apple: bool = False,
28+
http: urllib3.PoolManager | None = None,
29+
tzinfo: _tzinfo | None = None,
30+
sort: bool = False,
31+
strict: bool = False,
2632
) -> list[Event]:
2733
"""
2834
Get all events form the given iCal URL occurring in the given time range.
@@ -42,7 +48,7 @@ def events(
4248
"""
4349
found_events = []
4450

45-
content = None
51+
content = ""
4652
ical_download = ICalDownload(http=http)
4753

4854
if url:
@@ -58,13 +64,21 @@ def events(
5864
content, start=start, end=end, tzinfo=tzinfo, sort=sort, strict=strict
5965
)
6066

61-
if sort is True:
67+
if sort:
6268
found_events.sort()
6369

6470
return found_events
6571

6672

67-
def request_data(key, url, file, string_content, start, end, fix_apple):
73+
def request_data(
74+
key: str,
75+
url: str | None,
76+
file: str | Path | None,
77+
string_content: bytes | str | None,
78+
start: datetime | None,
79+
end: datetime | None,
80+
fix_apple: bool,
81+
) -> None:
6882
"""
6983
Request data, update local data cache and remove this Thread from queue.
7084
@@ -93,8 +107,14 @@ def request_data(key, url, file, string_content, start, end, fix_apple):
93107

94108

95109
def events_async(
96-
key, url=None, file=None, start=None, string_content=None, end=None, fix_apple=False
97-
):
110+
key: str,
111+
url: str | None = None,
112+
file: str | Path | None = None,
113+
start: datetime | None = None,
114+
string_content: bytes | str | None = None,
115+
end: datetime | None = None,
116+
fix_apple: bool = False,
117+
) -> None:
98118
"""
99119
Trigger an asynchronous data request.
100120
@@ -121,7 +141,7 @@ def events_async(
121141
threads[key][0].start()
122142

123143

124-
def request_finished(key):
144+
def request_finished(key: str) -> None:
125145
"""
126146
Remove finished Thread from queue.
127147
@@ -134,7 +154,7 @@ def request_finished(key):
134154
threads[key][0].run()
135155

136156

137-
def update_events(key, data):
157+
def update_events(key: str, data: list[Event]) -> None:
138158
"""
139159
Set the latest events for a key.
140160
@@ -145,7 +165,7 @@ def update_events(key, data):
145165
event_store[key] = data
146166

147167

148-
def latest_events(key):
168+
def latest_events(key: str) -> list[Event]:
149169
"""
150170
Get the latest downloaded events for the given key.
151171
@@ -158,7 +178,7 @@ def latest_events(key):
158178
return res
159179

160180

161-
def all_done(key):
181+
def all_done(key: str) -> bool:
162182
"""
163183
Check if requests for the given key are active.
164184

0 commit comments

Comments
 (0)