From 400ee7a520ff28925a772822ab16bc9815d307a5 Mon Sep 17 00:00:00 2001 From: ZaharChernenko <124883289+ZaharChernenko@users.noreply.github.com> Date: Tue, 10 Mar 2026 02:16:08 +0300 Subject: [PATCH] refactor: modernize type annotations to 3.10+ syntax --- python_coderunner/pyproject.toml | 2 +- .../src/coderunner/coderunner.py | 4 +-- .../src/coderunner_factory/interface.py | 3 +-- .../vim_coderunner_factory.py | 5 ++-- .../file_ext_command_builders_dispatcher.py | 8 +++--- .../file_type_command_builders_dispatcher.py | 10 +++---- .../glob_command_builders_dispatcher.py | 8 +++--- .../command_builders_dispatcher/interface.py | 3 +-- .../shebang_command_builders_dispatcher.py | 4 +-- .../basic.py | 14 +++++----- .../src/commands_executor/__init__.py | 2 +- .../{inteface.py => interface.py} | 0 .../vim_commands_executor.py | 2 +- python_coderunner/src/config/basic.py | 26 +++++++++---------- python_coderunner/src/config/interface.py | 9 +++---- .../validator/dispatchers_order_validator.py | 8 +++--- .../config/validator/dispatchers_validator.py | 6 ++--- python_coderunner/src/editor/interface.py | 3 +-- python_coderunner/src/editor/vim_editor.py | 4 +-- .../editor_service_for_coderunner/basic.py | 4 +-- .../src/file_info_extractor/base.py | 5 ++-- .../src/file_info_extractor/interface.py | 5 ++-- .../vim_file_info_extractor.py | 6 ++--- .../src/project_info_extractor/interface.py | 6 ++--- ...st_file_ext_command_builders_dispatcher.py | 6 ++--- ...t_file_type_command_builders_dispatcher.py | 6 ++--- .../test_glob_command_builders_dispatcher.py | 12 +++------ ...est_shebang_command_builders_dispatcher.py | 9 +++---- ...ic_command_dispatcher_strategy_selector.py | 7 +++-- python_coderunner/tests/unit/conftest.py | 16 ++++++------ .../test_interface_file_info_extractor.py | 3 +-- .../test_interface_project_info_extractor.py | 9 +++---- 32 files changed, 93 insertions(+), 122 deletions(-) rename python_coderunner/src/commands_executor/{inteface.py => interface.py} (100%) diff --git a/python_coderunner/pyproject.toml b/python_coderunner/pyproject.toml index bfcca57..9a1dda1 100644 --- a/python_coderunner/pyproject.toml +++ b/python_coderunner/pyproject.toml @@ -3,7 +3,7 @@ name = "vim-code-runner" authors = [ {name = "Zahar Chernenko", email = "zaharchernenko35@gmail.com"}, ] -version = "1.0.1" +version = "1.0.2" requires-python = ">=3.10" [dependency-groups] diff --git a/python_coderunner/src/coderunner/coderunner.py b/python_coderunner/src/coderunner/coderunner.py index 696fc77..da04305 100644 --- a/python_coderunner/src/coderunner/coderunner.py +++ b/python_coderunner/src/coderunner/coderunner.py @@ -1,4 +1,4 @@ -from typing import Callable, Optional +from typing import Callable from ..command_builder import ICommandBuilder from ..command_dispatcher_strategy_selector import ( @@ -40,7 +40,7 @@ def run_by_file_ext(self) -> None: def run_by_file_type(self) -> None: self._run(self._command_dispatcher_strategy_selector.dispatch_by_file_type) - def _run(self, strategy: Callable[[str], Optional[ICommandBuilder]]) -> None: + def _run(self, strategy: Callable[[str], ICommandBuilder | None]) -> None: try: with self._editor_service.get_file_for_run() as file_path_abs: if (command_builder := strategy(file_path_abs)) is not None: diff --git a/python_coderunner/src/coderunner_factory/interface.py b/python_coderunner/src/coderunner_factory/interface.py index 7003cc3..34c9918 100644 --- a/python_coderunner/src/coderunner_factory/interface.py +++ b/python_coderunner/src/coderunner_factory/interface.py @@ -1,10 +1,9 @@ from abc import ABC, abstractmethod -from typing import Optional from ..coderunner import TCodeRunner class ICodeRunnerFactory(ABC): @abstractmethod - def create(self) -> Optional[TCodeRunner]: + def create(self) -> TCodeRunner | None: raise NotImplementedError diff --git a/python_coderunner/src/coderunner_factory/vim_coderunner_factory.py b/python_coderunner/src/coderunner_factory/vim_coderunner_factory.py index ecbc2f8..80349a8 100644 --- a/python_coderunner/src/coderunner_factory/vim_coderunner_factory.py +++ b/python_coderunner/src/coderunner_factory/vim_coderunner_factory.py @@ -1,6 +1,5 @@ import glob import re -from typing import Dict, Optional from ..coderunner import TCodeRunner from ..command_builder import TInterpolatorCommandBuilder @@ -43,7 +42,7 @@ class TVimCodeRunnerFactory(ICodeRunnerFactory): - def create(self) -> Optional[TCodeRunner]: + def create(self) -> TCodeRunner | None: config: TVimConfig = self._create_config() message_printer: TVimMessagePrinter = TVimMessagePrinter() @@ -205,7 +204,7 @@ def _create_glob_command_builders_dispatcher( file_info_extractor: TVimFileInfoExtractor, project_info_extractor: TVimProjectInfoExtractor, ) -> TGlobCommandBuildersDispatcher: - dict_with_commands: Dict[str, str] = config.get_by_glob() + dict_with_commands: dict[str, str] = config.get_by_glob() return TGlobCommandBuildersDispatcher( tuple( ( diff --git a/python_coderunner/src/command_builders_dispatcher/file_ext_command_builders_dispatcher.py b/python_coderunner/src/command_builders_dispatcher/file_ext_command_builders_dispatcher.py index e3f1a4f..a3f4d93 100644 --- a/python_coderunner/src/command_builders_dispatcher/file_ext_command_builders_dispatcher.py +++ b/python_coderunner/src/command_builders_dispatcher/file_ext_command_builders_dispatcher.py @@ -1,4 +1,4 @@ -from typing import Dict, Final, Optional +from typing import Final from ..command_builder import ICommandBuilder from ..file_info_extractor import IFileInfoExtractor @@ -6,10 +6,10 @@ class TFileExtCommandBuildersDispatcher(ICommandBuildersDispatcher): - def __init__(self, file_ext_to_builder: Dict[str, ICommandBuilder], file_info_extractor: IFileInfoExtractor): - self._file_ext_to_builder: Final[Dict[str, ICommandBuilder]] = file_ext_to_builder + def __init__(self, file_ext_to_builder: dict[str, ICommandBuilder], file_info_extractor: IFileInfoExtractor): + self._file_ext_to_builder: Final[dict[str, ICommandBuilder]] = file_ext_to_builder self._file_info_extractor: IFileInfoExtractor = file_info_extractor - def dispatch(self, file_path_abs: str) -> Optional[ICommandBuilder]: + def dispatch(self, file_path_abs: str) -> ICommandBuilder | None: file_ext: str = self._file_info_extractor.get_file_ext(file_path_abs) return self._file_ext_to_builder.get(file_ext) diff --git a/python_coderunner/src/command_builders_dispatcher/file_type_command_builders_dispatcher.py b/python_coderunner/src/command_builders_dispatcher/file_type_command_builders_dispatcher.py index 969284f..254001c 100644 --- a/python_coderunner/src/command_builders_dispatcher/file_type_command_builders_dispatcher.py +++ b/python_coderunner/src/command_builders_dispatcher/file_type_command_builders_dispatcher.py @@ -1,4 +1,4 @@ -from typing import Dict, Final, Optional +from typing import Final from ..command_builder import ICommandBuilder from ..file_info_extractor import IFileInfoExtractor @@ -6,12 +6,12 @@ class TFileTypeCommandBuildersDispatcher(ICommandBuildersDispatcher): - def __init__(self, file_type_to_builder: Dict[str, ICommandBuilder], file_info_extractor: IFileInfoExtractor): - self._file_type_to_builder: Final[Dict[str, ICommandBuilder]] = file_type_to_builder + def __init__(self, file_type_to_builder: dict[str, ICommandBuilder], file_info_extractor: IFileInfoExtractor): + self._file_type_to_builder: Final[dict[str, ICommandBuilder]] = file_type_to_builder self._file_info_extractor: IFileInfoExtractor = file_info_extractor - def dispatch(self, file_path_abs: str) -> Optional[ICommandBuilder]: - file_type: Optional[str] = self._file_info_extractor.get_file_type(file_path_abs) + def dispatch(self, file_path_abs: str) -> ICommandBuilder | None: + file_type: str | None = self._file_info_extractor.get_file_type(file_path_abs) if file_type is None: return None return self._file_type_to_builder.get(file_type) diff --git a/python_coderunner/src/command_builders_dispatcher/glob_command_builders_dispatcher.py b/python_coderunner/src/command_builders_dispatcher/glob_command_builders_dispatcher.py index 509fea0..0b7ded0 100644 --- a/python_coderunner/src/command_builders_dispatcher/glob_command_builders_dispatcher.py +++ b/python_coderunner/src/command_builders_dispatcher/glob_command_builders_dispatcher.py @@ -1,15 +1,15 @@ import re -from typing import Final, Optional, Tuple +from typing import Final from ..command_builder import ICommandBuilder from .interface import ICommandBuildersDispatcher class TGlobCommandBuildersDispatcher(ICommandBuildersDispatcher): - def __init__(self, glob_to_builder: Tuple[Tuple[re.Pattern[str], ICommandBuilder], ...]): - self._glob_to_builder: Final[Tuple[Tuple[re.Pattern[str], ICommandBuilder], ...]] = glob_to_builder + def __init__(self, glob_to_builder: tuple[tuple[re.Pattern[str], ICommandBuilder], ...]): + self._glob_to_builder: Final[tuple[tuple[re.Pattern[str], ICommandBuilder], ...]] = glob_to_builder - def dispatch(self, file_path_abs: str) -> Optional[ICommandBuilder]: + def dispatch(self, file_path_abs: str) -> ICommandBuilder | None: for pattern, builder in self._glob_to_builder: if pattern.match(file_path_abs): return builder diff --git a/python_coderunner/src/command_builders_dispatcher/interface.py b/python_coderunner/src/command_builders_dispatcher/interface.py index e5d0b67..5f742fd 100644 --- a/python_coderunner/src/command_builders_dispatcher/interface.py +++ b/python_coderunner/src/command_builders_dispatcher/interface.py @@ -1,12 +1,11 @@ from abc import ABC, abstractmethod -from typing import Optional from ..command_builder import ICommandBuilder class ICommandBuildersDispatcher(ABC): @abstractmethod - def dispatch(self, file_path_abs: str) -> Optional[ICommandBuilder]: + def dispatch(self, file_path_abs: str) -> ICommandBuilder | None: """ Dispatch is optional for fallback strategy. """ diff --git a/python_coderunner/src/command_builders_dispatcher/shebang_command_builders_dispatcher.py b/python_coderunner/src/command_builders_dispatcher/shebang_command_builders_dispatcher.py index 88d91d7..be4201b 100644 --- a/python_coderunner/src/command_builders_dispatcher/shebang_command_builders_dispatcher.py +++ b/python_coderunner/src/command_builders_dispatcher/shebang_command_builders_dispatcher.py @@ -1,5 +1,3 @@ -from typing import Optional - from ..command_builder import ICommandBuilder, TConcatenatorCommandBuilder from ..file_info_extractor import IFileInfoExtractor from .interface import ICommandBuildersDispatcher @@ -9,7 +7,7 @@ class TShebangCommandBuildersDispatcher(ICommandBuildersDispatcher): def __init__(self, file_info_extractor: IFileInfoExtractor): self._file_info_extractor: IFileInfoExtractor = file_info_extractor - def dispatch(self, file_path_abs: str) -> Optional[ICommandBuilder]: + def dispatch(self, file_path_abs: str) -> ICommandBuilder | None: if (shebang := self._file_info_extractor.get_shebang(file_path_abs)) is not None: return TConcatenatorCommandBuilder(shebang) return None diff --git a/python_coderunner/src/command_dispatcher_strategy_selector/basic.py b/python_coderunner/src/command_dispatcher_strategy_selector/basic.py index 071aba0..11947eb 100644 --- a/python_coderunner/src/command_dispatcher_strategy_selector/basic.py +++ b/python_coderunner/src/command_dispatcher_strategy_selector/basic.py @@ -1,5 +1,3 @@ -from typing import Optional - from ..command_builder import ICommandBuilder from ..command_builders_dispatcher import ( TFileExtCommandBuildersDispatcher, @@ -32,20 +30,20 @@ def __init__( file_type_command_builders_dispatcher ) - def dispatch_by_shebang(self, file_path_abs: str) -> Optional[ICommandBuilder]: + def dispatch_by_shebang(self, file_path_abs: str) -> ICommandBuilder | None: return self._shebang_command_builders_dispatcher.dispatch(file_path_abs) - def dispatch_by_glob(self, file_path_abs: str) -> Optional[ICommandBuilder]: + def dispatch_by_glob(self, file_path_abs: str) -> ICommandBuilder | None: return self._glob_command_builders_dispatcher.dispatch(file_path_abs) - def dispatch_by_file_ext(self, file_path_abs: str) -> Optional[ICommandBuilder]: + def dispatch_by_file_ext(self, file_path_abs: str) -> ICommandBuilder | None: return self._file_ext_command_builders_dispatcher.dispatch(file_path_abs) - def dispatch_by_file_type(self, file_path_abs: str) -> Optional[ICommandBuilder]: + def dispatch_by_file_type(self, file_path_abs: str) -> ICommandBuilder | None: return self._file_type_command_builders_dispatcher.dispatch(file_path_abs) - def dispatch(self, file_path_abs: str) -> Optional[ICommandBuilder]: - command_builder: Optional[ICommandBuilder] = None + def dispatch(self, file_path_abs: str) -> ICommandBuilder | None: + command_builder: ICommandBuilder | None = None if ( self._config.get_respect_shebang() diff --git a/python_coderunner/src/commands_executor/__init__.py b/python_coderunner/src/commands_executor/__init__.py index 90ad3e6..acb533d 100644 --- a/python_coderunner/src/commands_executor/__init__.py +++ b/python_coderunner/src/commands_executor/__init__.py @@ -1,2 +1,2 @@ -from .inteface import ICommandsExecutor +from .interface import ICommandsExecutor from .vim_commands_executor import TVimCommandsExecutor diff --git a/python_coderunner/src/commands_executor/inteface.py b/python_coderunner/src/commands_executor/interface.py similarity index 100% rename from python_coderunner/src/commands_executor/inteface.py rename to python_coderunner/src/commands_executor/interface.py diff --git a/python_coderunner/src/commands_executor/vim_commands_executor.py b/python_coderunner/src/commands_executor/vim_commands_executor.py index b339cf3..0b6dbb4 100644 --- a/python_coderunner/src/commands_executor/vim_commands_executor.py +++ b/python_coderunner/src/commands_executor/vim_commands_executor.py @@ -1,7 +1,7 @@ import vim from ..config import IConfig -from .inteface import ICommandsExecutor +from .interface import ICommandsExecutor class TVimCommandsExecutor(ICommandsExecutor): diff --git a/python_coderunner/src/config/basic.py b/python_coderunner/src/config/basic.py index a7f85f5..b76cfa4 100644 --- a/python_coderunner/src/config/basic.py +++ b/python_coderunner/src/config/basic.py @@ -1,4 +1,4 @@ -from typing import Dict, List, TypeVar +from typing import TypeVar from .config_field import TConfigField from .exceptions import ConfigFieldNotFoundError, ConfigFieldValidationError @@ -10,10 +10,10 @@ class TBasicConfig(IConfig): def __init__( self, - by_file_ext_field: TConfigField[Dict[str, str]], - by_file_type_field: TConfigField[Dict[str, str]], - by_glob_field: TConfigField[Dict[str, str]], - dispatchers_order_field: TConfigField[List[EDispatchersTypes]], + by_file_ext_field: TConfigField[dict[str, str]], + by_file_type_field: TConfigField[dict[str, str]], + by_glob_field: TConfigField[dict[str, str]], + dispatchers_order_field: TConfigField[list[EDispatchersTypes]], coderunner_tempfile_prefix_field: TConfigField[str], executor_field: TConfigField[str], ignore_selection_field: TConfigField[bool], @@ -22,10 +22,10 @@ def __init__( save_all_files_before_run_field: TConfigField[bool], save_file_before_run_field: TConfigField[bool], ): - self._by_file_ext_field: TConfigField[Dict[str, str]] = by_file_ext_field - self._by_file_type_field: TConfigField[Dict[str, str]] = by_file_type_field - self._by_glob_field: TConfigField[Dict[str, str]] = by_glob_field - self._dispatchers_order_field: TConfigField[List[EDispatchersTypes]] = dispatchers_order_field + self._by_file_ext_field: TConfigField[dict[str, str]] = by_file_ext_field + self._by_file_type_field: TConfigField[dict[str, str]] = by_file_type_field + self._by_glob_field: TConfigField[dict[str, str]] = by_glob_field + self._dispatchers_order_field: TConfigField[list[EDispatchersTypes]] = dispatchers_order_field self._coderunner_tempfile_prefix_field: TConfigField[str] = coderunner_tempfile_prefix_field self._executor_field: TConfigField[str] = executor_field self._ignore_selection_field: TConfigField[bool] = ignore_selection_field @@ -44,16 +44,16 @@ def _get_field_value(self, field: TConfigField[ValueType]) -> ValueType: except (ConfigFieldNotFoundError, ConfigFieldValidationError) as e: raise ValueError(str(e)) from e - def get_by_file_ext(self) -> Dict[str, str]: + def get_by_file_ext(self) -> dict[str, str]: return self._get_field_value(self._by_file_ext_field) - def get_by_file_type(self) -> Dict[str, str]: + def get_by_file_type(self) -> dict[str, str]: return self._get_field_value(self._by_file_type_field) - def get_by_glob(self) -> Dict[str, str]: + def get_by_glob(self) -> dict[str, str]: return self._get_field_value(self._by_glob_field) - def get_dispatchers_order(self) -> List[EDispatchersTypes]: + def get_dispatchers_order(self) -> list[EDispatchersTypes]: return self._get_field_value(self._dispatchers_order_field) def get_coderunner_tempfile_prefix(self) -> str: diff --git a/python_coderunner/src/config/interface.py b/python_coderunner/src/config/interface.py index d94a9a5..2015e00 100644 --- a/python_coderunner/src/config/interface.py +++ b/python_coderunner/src/config/interface.py @@ -1,6 +1,5 @@ from abc import ABC, abstractmethod from enum import StrEnum -from typing import Dict, List class EDispatchersTypes(StrEnum): @@ -13,22 +12,22 @@ class IConfig(ABC): """Configuration interface""" @abstractmethod - def get_by_file_ext(self) -> Dict[str, str]: + def get_by_file_ext(self) -> dict[str, str]: """Gets config for file extension-based dispatching""" raise NotImplementedError @abstractmethod - def get_by_file_type(self) -> Dict[str, str]: + def get_by_file_type(self) -> dict[str, str]: """Gets config for file type-based dispatching""" raise NotImplementedError @abstractmethod - def get_by_glob(self) -> Dict[str, str]: + def get_by_glob(self) -> dict[str, str]: """Gets config for glob pattern-based dispatching""" raise NotImplementedError @abstractmethod - def get_dispatchers_order(self) -> List[EDispatchersTypes]: + def get_dispatchers_order(self) -> list[EDispatchersTypes]: """Gets the priority order of dispatchers""" raise NotImplementedError diff --git a/python_coderunner/src/config/validator/dispatchers_order_validator.py b/python_coderunner/src/config/validator/dispatchers_order_validator.py index 25e4b5e..2d7365b 100644 --- a/python_coderunner/src/config/validator/dispatchers_order_validator.py +++ b/python_coderunner/src/config/validator/dispatchers_order_validator.py @@ -1,15 +1,15 @@ -from typing import Any, List, Set +from typing import Any from ..interface import EDispatchersTypes from .exceptions import ValidationError from .interface import IValidator -class TDispatchersOrderValidator(IValidator[List[EDispatchersTypes]]): +class TDispatchersOrderValidator(IValidator[list[EDispatchersTypes]]): def __init__(self) -> None: - self.allowed_dispatcher_types: Set[EDispatchersTypes] = set(EDispatchersTypes) + self.allowed_dispatcher_types: set[EDispatchersTypes] = set(EDispatchersTypes) - def __call__(self, value: Any) -> List[EDispatchersTypes]: + def __call__(self, value: Any) -> list[EDispatchersTypes]: if not isinstance(value, list): raise ValidationError(f"Invalid dispatcher order container type: {type(value)}.") diff --git a/python_coderunner/src/config/validator/dispatchers_validator.py b/python_coderunner/src/config/validator/dispatchers_validator.py index 4992f6e..13a4484 100644 --- a/python_coderunner/src/config/validator/dispatchers_validator.py +++ b/python_coderunner/src/config/validator/dispatchers_validator.py @@ -1,11 +1,11 @@ -from typing import Any, Dict +from typing import Any from .exceptions import ValidationError from .interface import IValidator -class TDispatchersValidator(IValidator[Dict[str, str]]): - def __call__(self, value: Any) -> Dict[str, str]: +class TDispatchersValidator(IValidator[dict[str, str]]): + def __call__(self, value: Any) -> dict[str, str]: if not isinstance(value, dict): raise ValidationError(f"Invalid dispatcher container type: {type(value)}.") for key, val in value.items(): diff --git a/python_coderunner/src/editor/interface.py b/python_coderunner/src/editor/interface.py index 497ae6c..11dd7aa 100644 --- a/python_coderunner/src/editor/interface.py +++ b/python_coderunner/src/editor/interface.py @@ -1,5 +1,4 @@ from abc import ABC, abstractmethod -from typing import Optional class IEditor(ABC): @@ -8,7 +7,7 @@ def get_current_file_name(self) -> str: raise NotImplementedError @abstractmethod - def get_selected_text(self) -> Optional[str]: + def get_selected_text(self) -> str | None: raise NotImplementedError @abstractmethod diff --git a/python_coderunner/src/editor/vim_editor.py b/python_coderunner/src/editor/vim_editor.py index 9b0bc61..d68ae41 100644 --- a/python_coderunner/src/editor/vim_editor.py +++ b/python_coderunner/src/editor/vim_editor.py @@ -1,5 +1,3 @@ -from typing import Optional - import vim from .interface import IEditor @@ -9,7 +7,7 @@ class TVimEditor(IEditor): def get_current_file_name(self) -> str: return vim.current.buffer.name - def get_selected_text(self) -> Optional[str]: + def get_selected_text(self) -> str | None: return vim.eval("coderunner#GetSelectedText(a:visualmode, a:range, a:first_line, a:last_line)") def save_all_files(self) -> None: diff --git a/python_coderunner/src/editor_service_for_coderunner/basic.py b/python_coderunner/src/editor_service_for_coderunner/basic.py index 5397bbf..b02a623 100644 --- a/python_coderunner/src/editor_service_for_coderunner/basic.py +++ b/python_coderunner/src/editor_service_for_coderunner/basic.py @@ -1,7 +1,7 @@ import os from contextlib import contextmanager from tempfile import NamedTemporaryFile -from typing import Generator, List +from typing import Generator from ..config import IConfig from ..editor import IEditor @@ -13,7 +13,7 @@ def __init__(self, config: IConfig, editor: IEditor, file_info_extractor: IFileI self._config: IConfig = config self._editor: IEditor = editor self._file_info_extractor: IFileInfoExtractor = file_info_extractor - self._temp_files: List[str] = [] + self._temp_files: list[str] = [] @contextmanager def get_file_for_run(self) -> Generator[str, None, None]: diff --git a/python_coderunner/src/file_info_extractor/base.py b/python_coderunner/src/file_info_extractor/base.py index 10dfeea..8982e4e 100644 --- a/python_coderunner/src/file_info_extractor/base.py +++ b/python_coderunner/src/file_info_extractor/base.py @@ -1,6 +1,5 @@ import os from abc import abstractmethod -from typing import Optional from .interface import IFileInfoExtractor @@ -33,10 +32,10 @@ def get_file_name_without_ext(self, file_path_abs: str) -> str: return base[:dot_pos] if dot_pos != -1 else base @abstractmethod - def get_file_type(self, file_path_abs: str) -> Optional[str]: + def get_file_type(self, file_path_abs: str) -> str | None: raise NotImplementedError - def get_shebang(self, file_path_abs: str) -> Optional[str]: + def get_shebang(self, file_path_abs: str) -> str | None: if not os.path.exists(file_path_abs): return None diff --git a/python_coderunner/src/file_info_extractor/interface.py b/python_coderunner/src/file_info_extractor/interface.py index 8b3c9c1..1691793 100644 --- a/python_coderunner/src/file_info_extractor/interface.py +++ b/python_coderunner/src/file_info_extractor/interface.py @@ -1,5 +1,4 @@ from abc import ABC, abstractmethod -from typing import Optional class IFileInfoExtractor(ABC): @@ -33,9 +32,9 @@ def get_file_name_without_ext(self, file_path_abs: str) -> str: raise NotImplementedError @abstractmethod - def get_file_type(self, file_path_abs: str) -> Optional[str]: + def get_file_type(self, file_path_abs: str) -> str | None: raise NotImplementedError @abstractmethod - def get_shebang(self, file_path_abs: str) -> Optional[str]: + def get_shebang(self, file_path_abs: str) -> str | None: raise NotImplementedError diff --git a/python_coderunner/src/file_info_extractor/vim_file_info_extractor.py b/python_coderunner/src/file_info_extractor/vim_file_info_extractor.py index 4e6c5a2..d6bef72 100644 --- a/python_coderunner/src/file_info_extractor/vim_file_info_extractor.py +++ b/python_coderunner/src/file_info_extractor/vim_file_info_extractor.py @@ -1,11 +1,9 @@ -from typing import Optional - import vim from .base import TBaseFileInfoExtractor class TVimFileInfoExtractor(TBaseFileInfoExtractor): - def get_file_type(self, file_path_abs: str) -> Optional[str]: - file_type: Optional[str] = vim.eval("&filetype") + def get_file_type(self, file_path_abs: str) -> str | None: + file_type: str | None = vim.eval("&filetype") return None if not file_type else file_type diff --git a/python_coderunner/src/project_info_extractor/interface.py b/python_coderunner/src/project_info_extractor/interface.py index be01ca6..ea06b67 100644 --- a/python_coderunner/src/project_info_extractor/interface.py +++ b/python_coderunner/src/project_info_extractor/interface.py @@ -1,6 +1,6 @@ import os from abc import ABC, abstractmethod -from typing import Iterable, Set +from typing import Iterable from ..file_info_extractor import IFileInfoExtractor @@ -13,13 +13,13 @@ def __init__(self, file_info_extractor: IFileInfoExtractor): def get_workspace_root(self) -> str: raise NotImplementedError - def get_all_files_filter_by_exts(self, exts: Set[str]) -> Iterable[str]: + def get_all_files_filter_by_exts(self, exts: set[str]) -> Iterable[str]: for root, _, files in os.walk(self.get_workspace_root()): for file in files: if self._file_info_extractor.get_file_ext(file) in exts: yield os.path.join(root, file) - def get_all_files_filter_by_file_type(self, file_types: Set[str]) -> Iterable[str]: + def get_all_files_filter_by_file_type(self, file_types: set[str]) -> Iterable[str]: for root, _, files in os.walk(self.get_workspace_root()): for file in files: if self._file_info_extractor.get_file_type(file) in file_types: diff --git a/python_coderunner/tests/unit/command_builders_dispatcher/test_file_ext_command_builders_dispatcher.py b/python_coderunner/tests/unit/command_builders_dispatcher/test_file_ext_command_builders_dispatcher.py index 25f12ce..7a0ee7a 100644 --- a/python_coderunner/tests/unit/command_builders_dispatcher/test_file_ext_command_builders_dispatcher.py +++ b/python_coderunner/tests/unit/command_builders_dispatcher/test_file_ext_command_builders_dispatcher.py @@ -1,5 +1,3 @@ -from typing import Optional - import pytest from src.command_builder import ICommandBuilder @@ -21,9 +19,9 @@ def test_file_ext_command_builders_dispatcher( fixture_file_ext_command_builders_dispatcher: TFileExtCommandBuildersDispatcher, file_path: str, - expected_build_result: Optional[str], + expected_build_result: str | None, ) -> None: - dispatch_result: Optional[ICommandBuilder] = fixture_file_ext_command_builders_dispatcher.dispatch(file_path) + dispatch_result: ICommandBuilder | None = fixture_file_ext_command_builders_dispatcher.dispatch(file_path) if expected_build_result is not None: assert dispatch_result is not None diff --git a/python_coderunner/tests/unit/command_builders_dispatcher/test_file_type_command_builders_dispatcher.py b/python_coderunner/tests/unit/command_builders_dispatcher/test_file_type_command_builders_dispatcher.py index a18c676..c43ec2a 100644 --- a/python_coderunner/tests/unit/command_builders_dispatcher/test_file_type_command_builders_dispatcher.py +++ b/python_coderunner/tests/unit/command_builders_dispatcher/test_file_type_command_builders_dispatcher.py @@ -1,5 +1,3 @@ -from typing import Optional - import pytest from src.command_builder import ICommandBuilder @@ -21,9 +19,9 @@ def test_file_type_command_builders_dispatcher( fixture_file_type_command_builders_dispatcher: TFileTypeCommandBuildersDispatcher, file_path: str, - expected_build_result: Optional[str], + expected_build_result: str | None, ) -> None: - dispatch_result: Optional[ICommandBuilder] = fixture_file_type_command_builders_dispatcher.dispatch(file_path) + dispatch_result: ICommandBuilder | None = fixture_file_type_command_builders_dispatcher.dispatch(file_path) if expected_build_result is not None: assert dispatch_result is not None diff --git a/python_coderunner/tests/unit/command_builders_dispatcher/test_glob_command_builders_dispatcher.py b/python_coderunner/tests/unit/command_builders_dispatcher/test_glob_command_builders_dispatcher.py index a38be74..7a6e976 100644 --- a/python_coderunner/tests/unit/command_builders_dispatcher/test_glob_command_builders_dispatcher.py +++ b/python_coderunner/tests/unit/command_builders_dispatcher/test_glob_command_builders_dispatcher.py @@ -1,11 +1,7 @@ -from typing import Optional - import pytest from src.command_builder import ICommandBuilder -from src.command_builders_dispatcher import ( - TFileTypeCommandBuildersDispatcher, -) +from src.command_builders_dispatcher import TGlobCommandBuildersDispatcher @pytest.mark.parametrize( @@ -22,11 +18,11 @@ ], ) def test_glob_command_builders_dispatcher( - fixture_glob_command_builders_dispatcher: TFileTypeCommandBuildersDispatcher, + fixture_glob_command_builders_dispatcher: TGlobCommandBuildersDispatcher, file_path: str, - expected_build_result: Optional[str], + expected_build_result: str | None, ) -> None: - dispatch_result: Optional[ICommandBuilder] = fixture_glob_command_builders_dispatcher.dispatch(file_path) + dispatch_result: ICommandBuilder | None = fixture_glob_command_builders_dispatcher.dispatch(file_path) if expected_build_result is not None: assert dispatch_result is not None diff --git a/python_coderunner/tests/unit/command_builders_dispatcher/test_shebang_command_builders_dispatcher.py b/python_coderunner/tests/unit/command_builders_dispatcher/test_shebang_command_builders_dispatcher.py index 927674c..6bb3ade 100644 --- a/python_coderunner/tests/unit/command_builders_dispatcher/test_shebang_command_builders_dispatcher.py +++ b/python_coderunner/tests/unit/command_builders_dispatcher/test_shebang_command_builders_dispatcher.py @@ -1,5 +1,4 @@ from pathlib import Path -from typing import Optional import pytest @@ -25,8 +24,8 @@ ) def test_shebang_command_builders_dispatcher( fixture_shebang_command_builders_dispatcher: TShebangCommandBuildersDispatcher, - content: Optional[bytes], - expected_result: Optional[str], + content: bytes | None, + expected_result: str | None, tmp_path: Path, ) -> None: file_path_abs: Path = tmp_path / "test_file" @@ -36,9 +35,7 @@ def test_shebang_command_builders_dispatcher( return file_path_abs.write_bytes(content) - dispatch_result: Optional[ICommandBuilder] = fixture_shebang_command_builders_dispatcher.dispatch( - str(file_path_abs) - ) + dispatch_result: ICommandBuilder | None = fixture_shebang_command_builders_dispatcher.dispatch(str(file_path_abs)) if expected_result is None: assert dispatch_result is None diff --git a/python_coderunner/tests/unit/command_dispatcher_strategy_selector/test_basic_command_dispatcher_strategy_selector.py b/python_coderunner/tests/unit/command_dispatcher_strategy_selector/test_basic_command_dispatcher_strategy_selector.py index 81003db..5e46410 100644 --- a/python_coderunner/tests/unit/command_dispatcher_strategy_selector/test_basic_command_dispatcher_strategy_selector.py +++ b/python_coderunner/tests/unit/command_dispatcher_strategy_selector/test_basic_command_dispatcher_strategy_selector.py @@ -1,5 +1,4 @@ from pathlib import Path -from typing import List, Optional from unittest.mock import MagicMock import pytest @@ -71,9 +70,9 @@ def test_basic_command_dispatcher_strategy_selector( fixture_file_type_command_builders_dispatcher: TFileTypeCommandBuildersDispatcher, file_path: str, content: bytes, - order: List[EDispatchersTypes], + order: list[EDispatchersTypes], respect_shebang: bool, - expected: Optional[str], + expected: str | None, tmp_path: Path, ) -> None: file_path_abs = tmp_path / file_path @@ -88,7 +87,7 @@ def test_basic_command_dispatcher_strategy_selector( file_type_command_builders_dispatcher=fixture_file_type_command_builders_dispatcher, config=config, ) - dispatch_result: Optional[ICommandBuilder] = selector.dispatch(str(file_path_abs)) + dispatch_result: ICommandBuilder | None = selector.dispatch(str(file_path_abs)) if expected is None: assert dispatch_result is None diff --git a/python_coderunner/tests/unit/conftest.py b/python_coderunner/tests/unit/conftest.py index 70a6685..93cc2b0 100644 --- a/python_coderunner/tests/unit/conftest.py +++ b/python_coderunner/tests/unit/conftest.py @@ -3,7 +3,7 @@ import sys import tempfile import unittest -from typing import Dict, Generator, Tuple +from typing import Generator from unittest import mock from unittest.mock import MagicMock @@ -137,8 +137,8 @@ def fixture_shebang_command_builders_dispatcher( def fixture_file_ext_command_builders_dispatcher( fixture_file_info_extractor: IFileInfoExtractor, ) -> TFileExtCommandBuildersDispatcher: - extensions: Tuple[str, ...] = (".py", ".js", ".ts", ".java", ".cpp", ".c", ".go", ".rb", ".txt", ".z") - file_ext_to_builder: Dict[str, ICommandBuilder] = { + extensions: tuple[str, ...] = (".py", ".js", ".ts", ".java", ".cpp", ".c", ".go", ".rb", ".txt", ".z") + file_ext_to_builder: dict[str, ICommandBuilder] = { ext: MagicMock(spec=ICommandBuilder, build=MagicMock(return_value=ext)) for ext in extensions } @@ -151,13 +151,13 @@ def fixture_file_ext_command_builders_dispatcher( def fixture_file_type_command_builders_dispatcher( fixture_file_info_extractor: IFileInfoExtractor, ) -> TFileTypeCommandBuildersDispatcher: - languages: Tuple[str, ...] = ( + languages: tuple[str, ...] = ( "python", "javascript", "typescript", "cpp", ) - file_type_to_builder: Dict[str, ICommandBuilder] = { + file_type_to_builder: dict[str, ICommandBuilder] = { lang: MagicMock(spec=ICommandBuilder, build=MagicMock(return_value=lang)) for lang in languages } @@ -168,7 +168,7 @@ def fixture_file_type_command_builders_dispatcher( @pytest.fixture def fixture_glob_command_builders_dispatcher() -> TGlobCommandBuildersDispatcher: - glob_patterns: Tuple[str, ...] = ( + glob_patterns: tuple[str, ...] = ( "**/*.py", "**/test.py", "*.js", @@ -179,7 +179,7 @@ def fixture_glob_command_builders_dispatcher() -> TGlobCommandBuildersDispatcher "**/*.log", "**/*.*.*", ) - glob_to_builder: Tuple[Tuple[re.Pattern, ICommandBuilder], ...] = tuple( + glob_to_builder: tuple[tuple[re.Pattern, ICommandBuilder], ...] = tuple( ( re.compile(glob.translate(pattern, recursive=True, include_hidden=True)), MagicMock(spec=ICommandBuilder, build=MagicMock(return_value=pattern)), @@ -217,7 +217,7 @@ def fixture_file_info_extractor(request: pytest.FixtureRequest) -> IFileInfoExtr @pytest.fixture def fixture_vim_file_info_extractor() -> Generator[IFileInfoExtractor, None, None]: extractor: TVimFileInfoExtractor = TVimFileInfoExtractor() - ext_to_lang: Dict[str, str] = { + ext_to_lang: dict[str, str] = { ".py": "python", ".cpp": "cpp", ".rs": "rust", diff --git a/python_coderunner/tests/unit/file_info_extractor/test_interface_file_info_extractor.py b/python_coderunner/tests/unit/file_info_extractor/test_interface_file_info_extractor.py index 6f6262b..b68348b 100644 --- a/python_coderunner/tests/unit/file_info_extractor/test_interface_file_info_extractor.py +++ b/python_coderunner/tests/unit/file_info_extractor/test_interface_file_info_extractor.py @@ -1,6 +1,5 @@ import os import tempfile -from typing import Optional from unittest.mock import patch import pytest @@ -73,7 +72,7 @@ def test_get_drive_letter_unix(self, fixture_file_info_extractor: IFileInfoExtra ], ) def test_get_shebang( - self, fixture_file_info_extractor: IFileInfoExtractor, content: Optional[str], expected: Optional[str] + self, fixture_file_info_extractor: IFileInfoExtractor, content: str | None, expected: str | None ) -> None: if content is None: assert fixture_file_info_extractor.get_shebang("/bad/path") is expected diff --git a/python_coderunner/tests/unit/project_info_extractor/test_interface_project_info_extractor.py b/python_coderunner/tests/unit/project_info_extractor/test_interface_project_info_extractor.py index 73b0b41..ef5d9a1 100644 --- a/python_coderunner/tests/unit/project_info_extractor/test_interface_project_info_extractor.py +++ b/python_coderunner/tests/unit/project_info_extractor/test_interface_project_info_extractor.py @@ -1,5 +1,4 @@ from pathlib import Path -from typing import Set from src.project_info_extractor import IProjectInfoExtractor @@ -20,8 +19,8 @@ def test_get_all_files_filter_by_exts(self, fixture_project_info_extractor: IPro file_path.parent.mkdir(parents=True, exist_ok=True) file_path.touch(exist_ok=True) - exts: Set[str] = {".py", ".md"} - result: Set[Path] = {Path(p) for p in fixture_project_info_extractor.get_all_files_filter_by_exts(exts)} + exts: set[str] = {".py", ".md"} + result: set[Path] = {Path(p) for p in fixture_project_info_extractor.get_all_files_filter_by_exts(exts)} assert result == { workspace_root / "file_0.py", workspace_root / "file_1.py", @@ -45,8 +44,8 @@ def test_get_all_files_filter_by_file_type(self, fixture_project_info_extractor: file_path.parent.mkdir(parents=True, exist_ok=True) file_path.touch(exist_ok=True) - file_types: Set[str] = {"python", "cpp", "cobol"} - result: Set[Path] = { + file_types: set[str] = {"python", "cpp", "cobol"} + result: set[Path] = { Path(p) for p in fixture_project_info_extractor.get_all_files_filter_by_file_type(file_types) } assert result == {