Skip to content

Commit 7d49831

Browse files
authored
Merge pull request #150 from elfkuzco/simplify-types
simplify Optional and Union types
2 parents 7948d6e + cfbabf7 commit 7d49831

31 files changed

+342
-350
lines changed

CHANGELOG.md

+124-123
Large diffs are not rendered by default.

src/zimscraperlib/download.py

+21-21
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import pathlib
88
import subprocess
99
from concurrent.futures import Future, ThreadPoolExecutor
10-
from typing import ClassVar, Optional, Union
10+
from typing import ClassVar
1111

1212
import requests
1313
import yt_dlp as youtube_dl
@@ -21,7 +21,7 @@ class YoutubeDownloader:
2121
Shutdown method must be run explicitly to
2222
free any occupied resources"""
2323

24-
def __init__(self, threads: Optional[int] = 1) -> None:
24+
def __init__(self, threads: int | None = 1) -> None:
2525
self.executor = ThreadPoolExecutor(max_workers=threads)
2626

2727
def __enter__(self):
@@ -41,9 +41,9 @@ def _run_youtube_dl(self, url: str, options: dict) -> None:
4141
def download(
4242
self,
4343
url: str,
44-
options: Optional[dict],
45-
wait: Optional[bool] = True, # noqa: FBT002
46-
) -> Union[bool, Future]:
44+
options: dict | None,
45+
wait: bool | None = True, # noqa: FBT002
46+
) -> bool | Future:
4747
"""Downloads video using initialized executor.
4848
4949
url: URL or Video ID
@@ -65,8 +65,8 @@ def download(
6565

6666

6767
class YoutubeConfig(dict):
68-
options: ClassVar[dict[str, Optional[Union[str, bool, int]]]] = {}
69-
defaults: ClassVar[dict[str, Optional[Union[str, bool, int]]]] = {
68+
options: ClassVar[dict[str, str | bool | int | None]] = {}
69+
defaults: ClassVar[dict[str, str | bool | int | None]] = {
7070
"writethumbnail": True,
7171
"write_all_thumbnails": True,
7272
"writesubtitles": True,
@@ -88,8 +88,8 @@ def __init__(self, **kwargs):
8888
@classmethod
8989
def get_options(
9090
cls,
91-
target_dir: Optional[pathlib.Path] = None,
92-
filepath: Optional[pathlib.Path] = None,
91+
target_dir: pathlib.Path | None = None,
92+
filepath: pathlib.Path | None = None,
9393
**options,
9494
):
9595
if "outtmpl" not in options:
@@ -109,14 +109,14 @@ def get_options(
109109

110110

111111
class BestWebm(YoutubeConfig):
112-
options: ClassVar[dict[str, Optional[Union[str, bool, int]]]] = {
112+
options: ClassVar[dict[str, str | bool | int | None]] = {
113113
"preferredcodec": "webm",
114114
"format": "best[ext=webm]/bestvideo[ext=webm]+bestaudio[ext=webm]/best",
115115
}
116116

117117

118118
class BestMp4(YoutubeConfig):
119-
options: ClassVar[dict[str, Optional[Union[str, bool, int]]]] = {
119+
options: ClassVar[dict[str, str | bool | int | None]] = {
120120
"preferredcodec": "mp4",
121121
"format": "best[ext=mp4]/bestvideo[ext=mp4]+bestaudio[ext=m4a]/best",
122122
}
@@ -142,7 +142,7 @@ def save_large_file(url: str, fpath: pathlib.Path) -> None:
142142

143143

144144
def _get_retry_adapter(
145-
max_retries: Optional[int] = 5,
145+
max_retries: int | None = 5,
146146
) -> requests.adapters.BaseAdapter: # pyright: ignore
147147
retries = requests.packages.urllib3.util.retry.Retry( # pyright: ignore
148148
total=max_retries, # total number of retries
@@ -164,7 +164,7 @@ def _get_retry_adapter(
164164
return requests.adapters.HTTPAdapter(max_retries=retries) # pyright: ignore
165165

166166

167-
def get_session(max_retries: Optional[int] = 5) -> requests.Session:
167+
def get_session(max_retries: int | None = 5) -> requests.Session:
168168
"""Session to hold cookies and connection pool together"""
169169
session = requests.Session()
170170
session.mount("http", _get_retry_adapter(max_retries)) # tied to http and https
@@ -173,14 +173,14 @@ def get_session(max_retries: Optional[int] = 5) -> requests.Session:
173173

174174
def stream_file(
175175
url: str,
176-
fpath: Optional[pathlib.Path] = None,
177-
byte_stream: Optional[io.BytesIO] = None,
178-
block_size: Optional[int] = 1024,
179-
proxies: Optional[dict] = None,
180-
only_first_block: Optional[bool] = False, # noqa: FBT002
181-
max_retries: Optional[int] = 5,
182-
headers: Optional[dict[str, str]] = None,
183-
session: Optional[requests.Session] = None,
176+
fpath: pathlib.Path | None = None,
177+
byte_stream: io.BytesIO | None = None,
178+
block_size: int | None = 1024,
179+
proxies: dict | None = None,
180+
only_first_block: bool | None = False, # noqa: FBT002
181+
max_retries: int | None = 5,
182+
headers: dict[str, str] | None = None,
183+
session: requests.Session | None = None,
184184
) -> tuple[int, requests.structures.CaseInsensitiveDict]: # pyright: ignore
185185
"""Stream data from a URL to either a BytesIO object or a file
186186
Arguments -

src/zimscraperlib/filesystem.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@
55
66
Shortcuts to retrieve mime type using magic"""
77

8+
from __future__ import annotations
9+
810
import os
911
import pathlib
1012
from collections.abc import Callable
11-
from typing import Any, Optional, Union
13+
from typing import Any
1214

1315
import magic
1416

@@ -43,8 +45,8 @@ def get_content_mimetype(content: bytes) -> str:
4345

4446

4547
def delete_callback(
46-
fpath: Union[str, pathlib.Path],
47-
callback: Optional[Callable] = None,
48+
fpath: str | pathlib.Path,
49+
callback: Callable | None = None,
4850
*callback_args: Any,
4951
):
5052
"""helper deleting passed filepath, optionnaly calling an additional callback"""

src/zimscraperlib/fix_ogvjs_dist.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,12 @@
99
import logging
1010
import pathlib
1111
import sys
12-
from typing import Union
1312

1413
logging.basicConfig(format="%(levelname)s:%(message)s", level=logging.DEBUG)
1514
logger = logging.getLogger(__name__)
1615

1716

18-
def fix_source_dir(source_vendors_path: Union[pathlib.Path, str]):
17+
def fix_source_dir(source_vendors_path: pathlib.Path | str):
1918
"""update ogvjs plugin to trigger on webm mimetype"""
2019
root = pathlib.Path(source_vendors_path)
2120
logger.info("fixing videosjs-ogvjs.js")

src/zimscraperlib/html.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,17 @@
22
# vim: ai ts=4 sts=4 et sw=4 nu
33

44
""" Tools to work with HTML contents """
5+
from __future__ import annotations
56

67
import pathlib
7-
from typing import BinaryIO, TextIO, Union
8+
from typing import BinaryIO, TextIO
89

910
from bs4 import BeautifulSoup
1011

1112
from zimscraperlib.types import ARTICLE_MIME
1213

1314

14-
def find_title_in(content: Union[str, BinaryIO, TextIO], mime_type: str) -> str:
15+
def find_title_in(content: str | BinaryIO | TextIO, mime_type: str) -> str:
1516
"""Extracted title from HTML content
1617
1718
blank on failure to extract and non-HTML files"""
@@ -32,7 +33,7 @@ def find_title_in_file(fpath: pathlib.Path, mime_type: str) -> str:
3233
return ""
3334

3435

35-
def find_language_in(content: Union[str, BinaryIO, TextIO], mime_type: str) -> str:
36+
def find_language_in(content: str | BinaryIO | TextIO, mime_type: str) -> str:
3637
"""Extracted language from HTML content
3738
3839
blank on failure to extract and non-HTML files"""

src/zimscraperlib/i18n.py

+3-6
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import locale
88
import pathlib
99
import re
10-
from typing import Optional, Union
1110

1211
import babel
1312
import iso639
@@ -60,7 +59,7 @@ def setlocale(root_dir: pathlib.Path, locale_name: str):
6059
return Locale.setup(root_dir / "locale", locale_name)
6160

6261

63-
def get_iso_lang_data(lang: str) -> tuple[dict, Union[dict, None]]:
62+
def get_iso_lang_data(lang: str) -> tuple[dict, dict | None]:
6463
"""ISO-639-x languages details for lang. Raises NotFound
6564
6665
Included keys: iso-639-1, iso-639-2b, iso-639-2t, iso-639-3, iso-639-5
@@ -113,9 +112,7 @@ def replace_types(new_type: str) -> str:
113112
return lang_data, None
114113

115114

116-
def find_language_names(
117-
query: str, lang_data: Optional[dict] = None
118-
) -> tuple[str, str]:
115+
def find_language_names(query: str, lang_data: dict | None = None) -> tuple[str, str]:
119116
"""(native, english) language names for lang with help from language_details dict
120117
121118
Falls back to English name if available or query if not"""
@@ -152,7 +149,7 @@ def update_with_macro(lang_data: dict, macro_data: dict):
152149

153150

154151
def get_language_details(
155-
query: str, failsafe: Optional[bool] = False # noqa: FBT002
152+
query: str, failsafe: bool | None = False # noqa: FBT002
156153
) -> dict:
157154
"""language details dict from query.
158155

src/zimscraperlib/image/convertion.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
#!/usr/bin/env python3
22
# vim: ai ts=4 sts=4 et sw=4 nu
33

4+
from __future__ import annotations
5+
46
import io
57
import pathlib
6-
from typing import Union
78

89
import PIL
910

@@ -14,8 +15,8 @@
1415

1516

1617
def convert_image(
17-
src: Union[pathlib.Path, io.BytesIO],
18-
dst: Union[pathlib.Path, io.BytesIO],
18+
src: pathlib.Path | io.BytesIO,
19+
dst: pathlib.Path | io.BytesIO,
1920
**params: str,
2021
) -> None:
2122
"""convert an image file from one format to another

src/zimscraperlib/image/optimization.py

+27-28
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
import os
2929
import pathlib
3030
import subprocess
31-
from typing import Optional, Union
3231

3332
import piexif
3433
from optimize_images.img_aux_processing import do_reduce_colors, rebuild_palette
@@ -52,15 +51,15 @@ def ensure_matches(
5251

5352

5453
def optimize_png(
55-
src: Union[pathlib.Path, io.BytesIO],
56-
dst: Optional[pathlib.Path] = None,
57-
reduce_colors: Optional[bool] = False, # noqa: FBT002
58-
max_colors: Optional[int] = 256,
59-
fast_mode: Optional[bool] = True, # noqa: FBT002
60-
remove_transparency: Optional[bool] = False, # noqa: FBT002
61-
background_color: Optional[tuple[int, int, int]] = (255, 255, 255),
54+
src: pathlib.Path | io.BytesIO,
55+
dst: pathlib.Path | None = None,
56+
reduce_colors: bool | None = False, # noqa: FBT002
57+
max_colors: int | None = 256,
58+
fast_mode: bool | None = True, # noqa: FBT002
59+
remove_transparency: bool | None = False, # noqa: FBT002
60+
background_color: tuple[int, int, int] | None = (255, 255, 255),
6261
**options, # noqa: ARG001
63-
) -> Union[pathlib.Path, io.BytesIO]:
62+
) -> pathlib.Path | io.BytesIO:
6463
"""method to optimize PNG files using a pure python external optimizer
6564
6665
Arguments:
@@ -99,13 +98,13 @@ def optimize_png(
9998

10099

101100
def optimize_jpeg(
102-
src: Union[pathlib.Path, io.BytesIO],
103-
dst: Optional[pathlib.Path] = None,
104-
quality: Optional[int] = 85,
105-
fast_mode: Optional[bool] = True, # noqa: FBT002
106-
keep_exif: Optional[bool] = True, # noqa: FBT002
101+
src: pathlib.Path | io.BytesIO,
102+
dst: pathlib.Path | None = None,
103+
quality: int | None = 85,
104+
fast_mode: bool | None = True, # noqa: FBT002
105+
keep_exif: bool | None = True, # noqa: FBT002
107106
**options, # noqa: ARG001
108-
) -> Union[pathlib.Path, io.BytesIO]:
107+
) -> pathlib.Path | io.BytesIO:
109108
"""method to optimize JPEG files using a pure python external optimizer
110109
quality: JPEG quality (integer between 1 and 100)
111110
values: 50 | 55 | 35 | 100 | XX
@@ -169,13 +168,13 @@ def optimize_jpeg(
169168

170169

171170
def optimize_webp(
172-
src: Union[pathlib.Path, io.BytesIO],
173-
dst: Optional[pathlib.Path] = None,
174-
lossless: Optional[bool] = False, # noqa: FBT002
175-
quality: Optional[int] = 60,
176-
method: Optional[int] = 6,
171+
src: pathlib.Path | io.BytesIO,
172+
dst: pathlib.Path | None = None,
173+
lossless: bool | None = False, # noqa: FBT002
174+
quality: int | None = 60,
175+
method: int | None = 6,
177176
**options, # noqa: ARG001
178-
) -> Union[pathlib.Path, io.BytesIO]:
177+
) -> pathlib.Path | io.BytesIO:
179178
"""method to optimize WebP using Pillow options
180179
lossless: Whether to use lossless compression (boolean)
181180
values: True | False
@@ -214,11 +213,11 @@ def optimize_webp(
214213
def optimize_gif(
215214
src: pathlib.Path,
216215
dst: pathlib.Path,
217-
optimize_level: Optional[int] = 1,
218-
lossiness: Optional[int] = None,
219-
interlace: Optional[bool] = True, # noqa: FBT002
220-
no_extensions: Optional[bool] = True, # noqa: FBT002
221-
max_colors: Optional[int] = None,
216+
optimize_level: int | None = 1,
217+
lossiness: int | None = None,
218+
interlace: bool | None = True, # noqa: FBT002
219+
no_extensions: bool | None = True, # noqa: FBT002
220+
max_colors: int | None = None,
222221
**options, # noqa: ARG001
223222
) -> pathlib.Path:
224223
"""method to optimize GIFs using gifsicle >= 1.92
@@ -267,8 +266,8 @@ def optimize_gif(
267266
def optimize_image(
268267
src: pathlib.Path,
269268
dst: pathlib.Path,
270-
delete_src: Optional[bool] = False, # noqa: FBT002
271-
convert: Optional[Union[bool, str]] = False, # noqa: FBT002
269+
delete_src: bool | None = False, # noqa: FBT002
270+
convert: bool | str | None = False, # noqa: FBT002
272271
**options,
273272
) -> bool: # pyright: ignore
274273
"""Optimize image, automatically selecting correct optimizer

0 commit comments

Comments
 (0)