Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TYP: add missing type annotations to enable mypy's strict mode #429

Merged
merged 1 commit into from
Jan 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -111,11 +111,10 @@ exclude_lines = [

[tool.mypy]
python_version = '3.10'
strict = true
show_error_codes = true
warn_unused_configs = true
warn_unused_ignores = true
warn_unreachable = true
show_error_context = true
warn_unused_ignores = true

[tool.pytest.ini_options]
minversion = "6.0"
Expand Down
2 changes: 2 additions & 0 deletions src/idefix_cli/_backports.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# type: ignore

import os
import sys

Expand Down
2 changes: 1 addition & 1 deletion src/idefix_cli/_commands/clean.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def add_arguments(parser: ArgumentParser) -> None:


def command(
directory, clean_all: bool = False, dry: bool = False, confirm: bool = True
directory: str, clean_all: bool = False, dry: bool = False, confirm: bool = True
) -> int:
origin = os.path.abspath(os.curdir)
with chdir(directory):
Expand Down
12 changes: 7 additions & 5 deletions src/idefix_cli/_commands/clone.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import os
import shutil
import sys
from argparse import ArgumentParser
from collections.abc import Generator, Sequence
from pathlib import Path
from tempfile import TemporaryDirectory
from typing import TYPE_CHECKING
Expand Down Expand Up @@ -81,14 +83,14 @@ def exists(self) -> bool:
return self._path.exists()

@property
def parent(self):
def parent(self) -> Path:
return self._path.parent

@property
def parents(self):
def parents(self) -> Sequence[Path]:
return self._path.parents

def glob(self, *args):
def glob(self, *args: str) -> Generator[Path, None, None]:
return self._path.glob(*args)

def __str__(self) -> str:
Expand All @@ -105,7 +107,7 @@ def get_include_from_conf() -> list[str]:
return raw.split()


def add_arguments(parser) -> None:
def add_arguments(parser: ArgumentParser) -> None:
parser.add_argument(
"source",
default="",
Expand Down Expand Up @@ -156,7 +158,7 @@ def command(
include = []

files_and_dirs_to_copy = files_from_patterns(
str(source),
Path(str(source)),
*BASE_INCLUDE,
*include,
*get_include_from_conf(),
Expand Down
2 changes: 1 addition & 1 deletion src/idefix_cli/_commands/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ def substitute_cmake_args(args: list[str]) -> list[str]:
return args


def add_arguments(parser) -> None:
def add_arguments(parser: ArgumentParser) -> None:
parser.add_argument("--dir", dest="directory", default=".", help="target directory")

parser.add_argument(
Expand Down
8 changes: 4 additions & 4 deletions src/idefix_cli/_commands/digest.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
from argparse import ArgumentParser
from pathlib import Path
from time import monotonic_ns
from typing import Any
from typing import Any, TextIO

from idefix_cli.lib import print_error

_LOG_LINE_REGEXP = re.compile(r"^(?P<trailer>TimeIntegrator:)(?P<data>.*\|.*)")


def _log_to_data(log: list[str]):
def _log_to_data(log: list[str]) -> dict[str, list[Any]]:
columns: dict[str, list[Any]] = {name.strip(): [] for name in log[0].split("|")}
tokenized_log = [line.replace("N/A", "NaN").split("|") for line in log[1:]]
for i, name in enumerate(columns.keys()):
Expand Down Expand Up @@ -87,11 +87,11 @@ def add_arguments(parser: ArgumentParser) -> None:
def command(
dir: str,
input_: list[str] | None = None,
output=sys.stdout,
output: TextIO = sys.stdout,
all_files: bool = False,
timeit: bool = False,
*,
_log_line_regexp=_LOG_LINE_REGEXP,
_log_line_regexp: re.Pattern[str] = _LOG_LINE_REGEXP,
) -> int:
pdir = Path(dir)
if not pdir.is_dir():
Expand Down
3 changes: 2 additions & 1 deletion src/idefix_cli/_commands/read.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
from __future__ import annotations

import json
from argparse import ArgumentParser
from pathlib import Path

import inifix

from idefix_cli.lib import print_error


def add_arguments(parser) -> None:
def add_arguments(parser: ArgumentParser) -> None:
parser.add_argument("inifile", type=str, help="target inifile")
parser.add_argument(
"--indent", type=int, help="indentation in spaces (default is flat output)"
Expand Down
15 changes: 8 additions & 7 deletions src/idefix_cli/_commands/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import re
import subprocess
import sys
from argparse import ArgumentParser
from copy import deepcopy
from enum import auto
from math import prod
Expand Down Expand Up @@ -38,7 +39,7 @@
else:
from typing_extensions import assert_never

from idefix_cli._backports import StrEnum
from idefix_cli._backports import StrEnum # type: ignore [attr-defined]
from idefix_cli.lib import chdir

MAIN_LOG_FILE = "idefix.0.log"
Expand Down Expand Up @@ -124,7 +125,7 @@ def get_command(
return cmd


class RebuildMode(StrEnum):
class RebuildMode(StrEnum): # type: ignore [misc]
ALWAYS = auto()
PROMPT = auto()

Expand Down Expand Up @@ -156,11 +157,11 @@ def get_cpu_count() -> int:


def get_highest_power_of_two(n_max: int) -> int:
return 2 ** (n_max.bit_length() - 1)
return 1 << (n_max.bit_length() - 1)


@requires_idefix()
def build_idefix(directory) -> int:
def build_idefix(directory: str) -> int:
ncpus = min(8, get_highest_power_of_two(get_cpu_count()))
cmd = ["make", "-j", str(ncpus)]
return run_subcommand(cmd, loc=Path(directory), err="failed to build idefix")
Expand Down Expand Up @@ -189,7 +190,7 @@ def parse_ncycles(unknown_args: tuple[str, ...], ncycles: int) -> tuple[str, ...
return unknown_args


def add_arguments(parser) -> None:
def add_arguments(parser: ArgumentParser) -> None:
parser.add_argument("--dir", dest="directory", default=".", help="target directory")
parser.add_argument(
"-i",
Expand Down Expand Up @@ -358,11 +359,11 @@ def command(
rebuild_mode = RebuildMode(rebuild_mode_str)
except ValueError:
print_warning(
f"Expected [idfx run].recompile to be any of {[str(_) for _ in RebuildMode]}"
f"Expected [idfx run].recompile to be any of {[str(_) for _ in RebuildMode]}" # type: ignore [attr-defined]
f"Got {rebuild_mode_str!r} from {get_config_file()}\n"
)
print_warning("Falling back to 'prompt' mode.")
rebuild_mode = RebuildMode.PROMPT
rebuild_mode = RebuildMode.PROMPT # type: ignore [assignment]

build_is_required: bool = True
if rebuild_mode is RebuildMode.ALWAYS:
Expand Down
3 changes: 2 additions & 1 deletion src/idefix_cli/_commands/switch.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
"""switch git branch in $IDEFIX_DIR using git checkout"""

import os
from argparse import ArgumentParser
from pathlib import Path

from idefix_cli.lib import print_error, requires_idefix, run_subcommand


def add_arguments(parser):
def add_arguments(parser: ArgumentParser) -> None:
parser.add_argument(
"branch",
default="-",
Expand Down
3 changes: 2 additions & 1 deletion src/idefix_cli/_commands/write.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import json
import sys
from argparse import ArgumentParser
from contextlib import ExitStack
from io import TextIOBase
from pathlib import Path
Expand All @@ -11,7 +12,7 @@
from idefix_cli.lib import print_error


def add_arguments(parser) -> None:
def add_arguments(parser: ArgumentParser) -> None:
parser.add_argument("dest", type=str, help="dest inifile")
parser.add_argument(
"source",
Expand Down
5 changes: 3 additions & 2 deletions src/idefix_cli/_theme.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import sys
import unicodedata
from collections.abc import Generator
from contextlib import contextmanager
from dataclasses import dataclass
from typing import Literal, TypedDict
Expand Down Expand Up @@ -34,7 +35,7 @@ def register(
symbols: SymbolSet,
enter: str | None = None,
exit: str | None = None,
):
) -> None:
self._registry[name] = Theme(
name=name, symbols=symbols, enter_msg=enter, exit_msg=exit
)
Expand Down Expand Up @@ -79,7 +80,7 @@ def get_symbol(key: Literal["LAUNCH", "SUCCESS", "WARNING", "ERROR", "HINT"]) ->


@contextmanager
def theme_ctx(name: str):
def theme_ctx(name: str) -> Generator[None, None, None]:
global THEME
old_name = THEME.name
THEME = themes[name]
Expand Down
18 changes: 9 additions & 9 deletions src/idefix_cli/lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
if sys.version_info >= (3, 11):
from enum import StrEnum
else:
from idefix_cli._backports import StrEnum
from idefix_cli._backports import StrEnum # type: ignore[attr-defined]

# workaround mypy not being confortable around decorator preserving signatures
# adapted from
Expand Down Expand Up @@ -53,14 +53,14 @@
__all__.append("chdir")


class _WindowsTree(StrEnum):
class _WindowsTree(StrEnum): # type: ignore [misc]
TRUNK = "|"
FORK = "|-"
ANGLE = "'-"
BRANCH = "-"


class _PosixTree(StrEnum):
class _PosixTree(StrEnum): # type: ignore [misc]
TRUNK = "│"
FORK = "├"
ANGLE = "└"
Expand Down Expand Up @@ -102,7 +102,7 @@ class requires_idefix:

def __call__(self, f: TFun) -> TFun:
@wraps(f)
def wrapper(*args, **kwargs) -> Any:
def wrapper(*args: Any, **kwargs: Any) -> Any:
if (IDEFIX_DIR := os.getenv("IDEFIX_DIR")) is None:
print_error(
"this functionality requires $IDEFIX_DIR to be defined",
Expand Down Expand Up @@ -260,8 +260,8 @@ def run_subcommand(


def files_from_patterns(
source,
*patterns,
source: os.PathLike[str],
*patterns: str,
recursive: bool = False,
excludes: list[str] | None = None,
) -> list[str]:
Expand Down Expand Up @@ -447,17 +447,17 @@ def prompt_ask(prompt: str, /) -> bool:
print("Please enter y or n", file=sys.stderr)


def __getattr__(attr: str):
def __getattr__(attr: str) -> Any:
# avoid leaking more than intended from the standard library
if attr == "chdir":
if sys.version_info >= (3, 11):
from contextlib import chdir
else:
from idefix_cli._backports import chdir
from idefix_cli._backports import chdir # type: ignore [attr-defined]
return chdir
else:
raise AttributeError(f"Unknown attribute {attr!r}")


def __dir__():
def __dir__() -> list[str]:
return list(globals()) + ["chdir"]
4 changes: 3 additions & 1 deletion tests/test_app_structure.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,9 @@ def test_plugins(isolated_conf_dir, tmp_path, capsys):
dedent(
"""
'test extension command'
def add_arguments(parser) -> None:
from argparse import ArgumentParser

def add_arguments(parser: ArgumentParser) -> None:
return

def command() -> int:
Expand Down
Loading