Skip to content

Commit 1030dab

Browse files
committed
Modernize the code base
1 parent 90f3d8a commit 1030dab

37 files changed

Lines changed: 210 additions & 227 deletions

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ pathvalidate = "^3.1.0"
2929
mutagen = "^1.46.0"
3030
docstring-parser = "^0.16"
3131
python-magic = "^0.4.27"
32-
Pillow = "^10.0.0"
32+
Pillow = "^12.0.0"
3333
piexif = "^1.1.3"
3434
pymediainfo = {version = "^6.0.1", optional = true}
3535
isodate = "^0.6.1"

tempren/adhoc.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import subprocess
22
from pathlib import Path
3-
from typing import Optional, Tuple
43

54
from tempren.exceptions import ExecutionTimeoutError, MissingMetadataError
65
from tempren.factories import TagFactoryFromClass
@@ -17,7 +16,7 @@ def short_description(self) -> str:
1716
return self._render_description(super().short_description)
1817

1918
@property
20-
def long_description(self) -> Optional[str]:
19+
def long_description(self) -> str | None:
2120
long_description = super().long_description
2221
if long_description:
2322
long_description = self._render_description(long_description)
@@ -59,7 +58,7 @@ class AdHocTag(Tag):
5958
"""
6059

6160
executable: Path
62-
args: Tuple[str, ...] = ()
61+
args: tuple[str, ...] = ()
6362
timeout_ms: int = 3000
6463

6564
def __init__(self, executable: Path):
@@ -76,7 +75,7 @@ def configure(self, *positional_args: str, timeout_ms: int = 3000):
7675
self.args = positional_args
7776
self.timeout_ms = timeout_ms
7877

79-
def process(self, file: File, context: Optional[str]) -> str:
78+
def process(self, file: File, context: str | None) -> str:
8079
if context is None:
8180
command_line = (
8281
[str(self.executable)] + list(self.args) + [str(file.relative_path)]

tempren/alias.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import Any, Optional, Type
1+
from typing import Any
22

33
from tempren.factories import TagFactoryFromClass
44
from tempren.primitives import File, Pattern, Tag, TagName
@@ -31,7 +31,7 @@ class AliasTag(Tag):
3131
def __init__(self, pattern: Pattern) -> None:
3232
self.pattern = pattern
3333

34-
def process(self, file: File, context: Optional[str]) -> Any:
34+
def process(self, file: File, context: str | None) -> Any:
3535
return self.pattern.process(file)
3636

3737

@@ -46,7 +46,7 @@ def short_description(self) -> str:
4646
return self._render_description(super().short_description)
4747

4848
@property
49-
def long_description(self) -> Optional[str]:
49+
def long_description(self) -> str | None:
5050
long_description = super().long_description
5151
assert long_description, "AliasTag description changed"
5252
long_description = self._render_description(long_description)
@@ -74,7 +74,7 @@ class AliasTagFactoryFromClass(AliasTagFactory):
7474

7575
_tag_alias_suffix = "TagAlias"
7676

77-
def __init__(self, tag_alias_class: Type[TagAlias], compiler: TemplateCompiler):
77+
def __init__(self, tag_alias_class: type[TagAlias], compiler: TemplateCompiler):
7878
class_name = tag_alias_class.__name__
7979
if class_name.endswith(self._tag_alias_suffix):
8080
alias_tag_name = TagName(class_name[: -len(self._tag_alias_suffix)])

tempren/cli.py

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,13 @@
55
import shutil
66
import sys
77
from argparse import ArgumentParser, Namespace
8+
from collections.abc import Sequence
89
from enum import IntEnum
910
from itertools import chain
1011
from logging import LogRecord
1112
from pathlib import Path
1213
from textwrap import indent
13-
from typing import Any, Dict, List, NoReturn, Optional, Sequence, Text, Tuple, Union
14+
from typing import Any, NoReturn
1415

1516
from tempren.exceptions import FileNotSupportedError, TemplateEvaluationError
1617
from tempren.filesystem import DestinationAlreadyExistsError
@@ -87,7 +88,7 @@ def tag_name_from_executable(exec_path: Path) -> str:
8788
return base_name
8889

8990

90-
def adhoc_tag(val: str) -> Tuple[TagName, Path]:
91+
def adhoc_tag(val: str) -> tuple[TagName, Path]:
9192
val = nonempty_string(val)
9293
components = val.split("=", maxsplit=1)
9394
if len(components) == 1:
@@ -109,7 +110,7 @@ def adhoc_tag(val: str) -> Tuple[TagName, Path]:
109110
raise argparse.ArgumentTypeError(f"'{tag_name}' cannot be used as tag name")
110111

111112

112-
def alias(val: str) -> Tuple[TagName, str]:
113+
def alias(val: str) -> tuple[TagName, str]:
113114
val = nonempty_string(val)
114115
components = val.split("=", maxsplit=1)
115116
if len(components) < 2:
@@ -126,8 +127,8 @@ def alias(val: str) -> Tuple[TagName, str]:
126127

127128

128129
def validate_adhoc_tags(
129-
adhoc_tags: List[List[Tuple[TagName, Path]]]
130-
) -> Dict[TagName, Path]:
130+
adhoc_tags: list[list[tuple[TagName, Path]]]
131+
) -> dict[TagName, Path]:
131132
if not adhoc_tags:
132133
return dict()
133134
list_of_tuples = list(chain(*adhoc_tags))
@@ -152,7 +153,7 @@ def validate_adhoc_tags(
152153
return dict(list_of_tuples)
153154

154155

155-
def validate_aliases(aliases: List[List[Tuple[TagName, str]]]) -> Dict[TagName, str]:
156+
def validate_aliases(aliases: list[list[tuple[TagName, str]]]) -> dict[TagName, str]:
156157
# TODO: Merge with validate_adhoc_tags
157158
if not aliases:
158159
return dict()
@@ -182,7 +183,7 @@ def validate_aliases(aliases: List[List[Tuple[TagName, str]]]) -> Dict[TagName,
182183
class SystemExitError(Exception): # TODO: Use ConfigurationError instead
183184
status: int
184185

185-
def __init__(self, status: int, message: Optional[str]):
186+
def __init__(self, status: int, message: str | None):
186187
super().__init__(message)
187188
self.status = status
188189

@@ -192,8 +193,8 @@ def __call__(
192193
self,
193194
parser: ArgumentParser,
194195
args: Namespace,
195-
values: Union[Text, Sequence[Any], None],
196-
option_string: Optional[Text] = None,
196+
values: str | Sequence[Any] | None,
197+
option_string: str | None = None,
197198
):
198199
registry = build_tag_registry(
199200
validate_adhoc_tags(args.ad_hoc), validate_aliases(args.alias)
@@ -227,8 +228,8 @@ def __call__(
227228
self,
228229
parser: ArgumentParser,
229230
args: Namespace,
230-
values: Union[str, Sequence[Any], None],
231-
option_string: Optional[Text] = None,
231+
values: str | Sequence[Any] | None,
232+
option_string: str | None = None,
232233
):
233234
if values is None:
234235
parser.print_help()
@@ -268,8 +269,8 @@ def __call__(
268269
self,
269270
parser: ArgumentParser,
270271
namespace: Namespace,
271-
values: Union[Text, Sequence[Any], None],
272-
option_string: Optional[Text] = None,
272+
values: str | Sequence[Any] | None,
273+
option_string: str | None = None,
273274
):
274275
log.info(self.find_package_version())
275276
parser.exit()
@@ -290,8 +291,8 @@ def __call__(
290291
self,
291292
parser: ArgumentParser,
292293
namespace: Namespace,
293-
values: Union[Text, Sequence[Any], None],
294-
option_string: Optional[Text] = None,
294+
values: str | Sequence[Any] | None,
295+
option_string: str | None = None,
295296
):
296297
root_logger = logging.getLogger()
297298
root_logger.setLevel(root_logger.level - 10)
@@ -303,8 +304,8 @@ def __call__(
303304
self,
304305
parser: ArgumentParser,
305306
namespace: Namespace,
306-
values: Union[Text, Sequence[Any], None],
307-
option_string: Optional[Text] = None,
307+
values: str | Sequence[Any] | None,
308+
option_string: str | None = None,
308309
):
309310
root_logger = logging.getLogger()
310311
root_logger.setLevel(root_logger.level + 10)
@@ -320,7 +321,7 @@ def _get_help_string(self, action):
320321
return action.help
321322

322323

323-
def process_cli_configuration(argv: List[str]) -> RuntimeConfiguration:
324+
def process_cli_configuration(argv: list[str]) -> RuntimeConfiguration:
324325
log.debug("Parsing command line arguments")
325326
parser = argparse.ArgumentParser(
326327
prog="tempren",
@@ -520,7 +521,7 @@ def process_cli_configuration(argv: List[str]) -> RuntimeConfiguration:
520521
# We could catch resulting `SystemExit` exception but related error message still would be missing.
521522
# This behaviour is not comfortable for testing so here we monkeypatch exit method to
522523
# throw more practical exception instead.
523-
def throwing_exit(status: int = 0, message: Optional[str] = "") -> NoReturn:
524+
def throwing_exit(status: int = 0, message: str | None = "") -> NoReturn:
524525
raise SystemExitError(status, message)
525526

526527
parser.exit = throwing_exit # type: ignore
@@ -602,7 +603,7 @@ def render_template_evaluation_error(
602603

603604
def cli_prompt_conflict_resolver(
604605
source_path: Path, destination_path: Path
605-
) -> Union[ConflictResolutionStrategy, Path]:
606+
) -> ConflictResolutionStrategy | Path:
606607
log.warning("While processing:")
607608
log.warning(f" {source_path}")
608609
log.warning("following path was generated:")

tempren/discovery.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,30 @@
33
import logging
44
import pkgutil
55
from collections import defaultdict
6+
from collections.abc import Callable
67
from types import ModuleType
7-
from typing import Callable, Dict, List, Type, TypeVar
8+
from typing import TypeVar
89

910
from tempren.alias import TagAlias
1011
from tempren.primitives import CategoryName, Tag
1112

1213
log = logging.getLogger(__name__)
1314

1415

15-
def discover_tags_in_package(package) -> Dict[CategoryName, List[Type[Tag]]]:
16+
def discover_tags_in_package(package) -> dict[CategoryName, list[type[Tag]]]:
1617
return _discover_classes_in_package(package, Tag)
1718

1819

19-
def discover_aliases_in_package(package) -> Dict[CategoryName, List[Type[TagAlias]]]:
20+
def discover_aliases_in_package(package) -> dict[CategoryName, list[type[TagAlias]]]:
2021
return _discover_classes_in_package(package, TagAlias)
2122

2223

2324
BaseClass = TypeVar("BaseClass")
2425

2526

2627
def _discover_classes_in_package(
27-
package, base_klass: Type[BaseClass]
28-
) -> Dict[CategoryName, List[Type[BaseClass]]]:
28+
package, base_klass: type[BaseClass]
29+
) -> dict[CategoryName, list[type[BaseClass]]]:
2930
def _is_base_class(klass: type):
3031
if (
3132
not inspect.isclass(klass)

tempren/factories.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import textwrap
2-
from typing import Optional, Type
32

43
from docstring_parser import parse as parse_docstring
54

@@ -9,7 +8,7 @@
98
class TagFactoryFromClass(TagFactory):
109
"""Produces tag instances by instantiating provided python class"""
1110

12-
_tag_class: Type[Tag]
11+
_tag_class: type[Tag]
1312
_tag_name: TagName
1413

1514
@property
@@ -50,7 +49,7 @@ def _create_configuration_signature(self) -> str:
5049
single_line_signature = f"%{self._tag_name}{signature_str}{context_metavar}"
5150
return single_line_signature
5251

53-
def _create_arguments_description(self) -> Optional[str]:
52+
def _create_arguments_description(self) -> str | None:
5453
argument_description = []
5554
for argument in self._parsed_configure_docstring.params:
5655
argument_description.append(f"{argument.arg_name} - {argument.description}")
@@ -65,10 +64,10 @@ def short_description(self) -> str:
6564
return ""
6665

6766
@property
68-
def long_description(self) -> Optional[str]:
67+
def long_description(self) -> str | None:
6968
return self._parsed_class_docstring.long_description
7069

71-
def __init__(self, tag_class: Type[Tag], tag_name: TagName):
70+
def __init__(self, tag_class: type[Tag], tag_name: TagName):
7271
self._tag_class = tag_class
7372
self._tag_name = tag_name
7473
self._parsed_class_docstring = parse_docstring(

tempren/file_filters.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import logging
33
import re
44
from abc import ABC, abstractmethod
5-
from typing import Callable
5+
from collections.abc import Callable
66

77
from tempren.evaluation import evaluate_expression
88
from tempren.exceptions import ExpressionEvaluationError, TemplateEvaluationError

tempren/file_sorters.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import logging
22
from abc import ABC, abstractmethod
3-
from typing import Iterable, Tuple
3+
from collections.abc import Iterable
44

55
from tempren.evaluation import evaluate_expression
66
from tempren.exceptions import ExpressionEvaluationError, TemplateEvaluationError
@@ -27,7 +27,7 @@ def __init__(self, pattern: Pattern, invert: bool = False):
2727
def __call__(self, files: Iterable[File]) -> Iterable[File]:
2828
return sorted(files, key=self._generate_sort_key, reverse=self.invert)
2929

30-
def _generate_sort_key(self, file: File) -> Tuple:
30+
def _generate_sort_key(self, file: File) -> tuple:
3131
self.log.debug("Rendering sorting value template for '%s'", file)
3232
rendered_expression = "(" + self.pattern.process_as_expression(file) + ", )"
3333
self.log.debug("Evaluating sorting value expression '%s'", rendered_expression)

tempren/filesystem.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
import os
33
import shutil
44
from abc import ABC, abstractmethod
5+
from collections.abc import Callable, Iterable
56
from pathlib import Path
6-
from typing import Callable, Iterable, List, Set
77

88
from tempren.primitives import File
99

@@ -109,7 +109,7 @@ def _gather_in(self, directory: Path) -> Iterable[File]:
109109

110110

111111
class ExplicitFileGatherer(FileGatherer):
112-
def __init__(self, files: List[Path]):
112+
def __init__(self, files: list[Path]):
113113
self._files_to_provide = files
114114

115115
def gather_files(self) -> Iterable[File]:
@@ -127,7 +127,7 @@ def include_hidden(self, include: bool):
127127
for gatherer in self._gatherers:
128128
gatherer.include_hidden = include
129129

130-
def __init__(self, gatherers: List[FileGatherer]):
130+
def __init__(self, gatherers: list[FileGatherer]):
131131
if not gatherers:
132132
raise ValueError("No subsequent file gatherers provided")
133133
self._gatherers = gatherers
@@ -168,8 +168,8 @@ def __call__(
168168

169169
class DryRunRenamer:
170170
def __init__(self):
171-
self.removed_paths: Set[Path] = set()
172-
self.created_paths: Set[Path] = set()
171+
self.removed_paths: set[Path] = set()
172+
self.created_paths: set[Path] = set()
173173

174174
def __call__(
175175
self,

0 commit comments

Comments
 (0)