diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 4cf5687..27b394d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -71,4 +71,5 @@ repos: hooks: - id: mypy additional_dependencies: [types-all] + files: babelizer/.*\.py$ exclude: ^babelizer/data diff --git a/babelizer/_datadir.py b/babelizer/_datadir.py index 02ceff7..afb08e3 100644 --- a/babelizer/_datadir.py +++ b/babelizer/_datadir.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import sys if sys.version_info >= (3, 12): # pragma: no cover (PY12+) diff --git a/babelizer/_files/bmi_py.py b/babelizer/_files/bmi_py.py index 33e10cf..1d00e5b 100644 --- a/babelizer/_files/bmi_py.py +++ b/babelizer/_files/bmi_py.py @@ -1,11 +1,13 @@ +from __future__ import annotations + import os +from collections.abc import Mapping +from typing import Any -def render(plugin_metadata) -> str: +def render(plugin_metadata: Mapping[str, Any]) -> str: """Render _bmi.py.""" - languages = { - library["language"] for library in plugin_metadata._meta["library"].values() - } + languages = {library["language"] for library in plugin_metadata["library"].values()} assert len(languages) == 1 language = languages.pop() @@ -15,22 +17,18 @@ def render(plugin_metadata) -> str: return _render_bmi_c(plugin_metadata) -def _render_bmi_c(plugin_metadata) -> str: +def _render_bmi_c(plugin_metadata: Mapping[str, Any]) -> str: """Render _bmi.py for a non-python library.""" - languages = [ - library["language"] for library in plugin_metadata._meta["library"].values() - ] + languages = [library["language"] for library in plugin_metadata["library"].values()] language = languages[0] assert language in ("c", "c++", "fortran") imports = [ - f"from {plugin_metadata.get('package', 'name')}.lib import {cls}" - for cls in plugin_metadata._meta["library"] + f"from {plugin_metadata['package']['name']}.lib import {cls}" + for cls in plugin_metadata["library"] ] - names = [ - f" {cls!r},".replace("'", '"') for cls in plugin_metadata._meta["library"] - ] + names = [f" {cls!r},".replace("'", '"') for cls in plugin_metadata["library"]] return f"""\ {os.linesep.join(sorted(imports))} @@ -41,11 +39,9 @@ def _render_bmi_c(plugin_metadata) -> str: """ -def _render_bmi_py(plugin_metadata) -> str: +def _render_bmi_py(plugin_metadata: Mapping[str, Any]) -> str: """Render _bmi.py for a python library.""" - languages = [ - library["language"] for library in plugin_metadata._meta["library"].values() - ] + languages = [library["language"] for library in plugin_metadata["library"].values()] language = languages[0] assert language == "python" @@ -60,7 +56,7 @@ def _render_bmi_py(plugin_metadata) -> str: imports = [ f"from {component['library']} import {component['entry_point']} as {cls}" - for cls, component in plugin_metadata._meta["library"].items() + for cls, component in plugin_metadata["library"].items() ] rename = [ @@ -70,12 +66,10 @@ def _render_bmi_py(plugin_metadata) -> str: """.replace( "'", '"' ) - for cls in plugin_metadata._meta["library"] + for cls in plugin_metadata["library"] ] - names = [ - f" {cls!r},".replace("'", '"') for cls in plugin_metadata._meta["library"] - ] + names = [f" {cls!r},".replace("'", '"') for cls in plugin_metadata["library"]] return f"""\ {header} diff --git a/babelizer/_files/gitignore.py b/babelizer/_files/gitignore.py index 4d361f5..1296106 100644 --- a/babelizer/_files/gitignore.py +++ b/babelizer/_files/gitignore.py @@ -1,7 +1,11 @@ +from __future__ import annotations + import os +from collections.abc import Mapping +from typing import Any -def render(plugin_metadata) -> str: +def render(plugin_metadata: Mapping[str, Any]) -> str: """Render a .gitignore file.""" package_name = plugin_metadata["package"]["name"] diff --git a/babelizer/_files/init_py.py b/babelizer/_files/init_py.py index 963c999..5999df8 100644 --- a/babelizer/_files/init_py.py +++ b/babelizer/_files/init_py.py @@ -1,19 +1,20 @@ +from __future__ import annotations + import os +from collections.abc import Mapping +from typing import Any -def render(plugin_metadata) -> str: +def render(plugin_metadata: Mapping[str, Any]) -> str: """Render __init__.py.""" - package_name = plugin_metadata.get("package", "name") + package_name = plugin_metadata["package"]["name"] imports = [f"from {package_name}._version import __version__"] imports += [ - f"from {package_name}._bmi import {cls}" - for cls in plugin_metadata._meta["library"] + f"from {package_name}._bmi import {cls}" for cls in plugin_metadata["library"] ] - names = [ - f" {cls!r},".replace("'", '"') for cls in plugin_metadata._meta["library"] - ] + names = [f" {cls!r},".replace("'", '"') for cls in plugin_metadata["library"]] return f"""\ {os.linesep.join(sorted(imports))} diff --git a/babelizer/_files/lib_init_py.py b/babelizer/_files/lib_init_py.py index 3c9227b..269b655 100644 --- a/babelizer/_files/lib_init_py.py +++ b/babelizer/_files/lib_init_py.py @@ -1,17 +1,19 @@ +from __future__ import annotations + import os +from collections.abc import Mapping +from typing import Any -def render(plugin_metadata) -> str: +def render(plugin_metadata: Mapping[str, Any]) -> str: """Render lib/__init__.py.""" - package_name = plugin_metadata.get("package", "name") + package_name = plugin_metadata["package"]["name"] imports = [ f"from {package_name}.lib.{cls.lower()} import {cls}" - for cls in plugin_metadata._meta["library"] + for cls in plugin_metadata["library"] ] - names = [ - f" {cls!r},".replace("'", '"') for cls in plugin_metadata._meta["library"] - ] + names = [f" {cls!r},".replace("'", '"') for cls in plugin_metadata["library"]] return f"""\ {os.linesep.join(sorted(imports))} diff --git a/babelizer/_files/license_rst.py b/babelizer/_files/license_rst.py index a18ebb1..1d5bc49 100644 --- a/babelizer/_files/license_rst.py +++ b/babelizer/_files/license_rst.py @@ -1,7 +1,11 @@ +from __future__ import annotations + +from collections.abc import Mapping from datetime import datetime +from typing import Any -def render(plugin_metadata) -> str: +def render(plugin_metadata: Mapping[str, Any]) -> str: """Render LICENSE.rst.""" license_name = plugin_metadata["info"]["package_license"] kwds = { diff --git a/babelizer/_files/meson_build.py b/babelizer/_files/meson_build.py index ac725bb..4996e3d 100644 --- a/babelizer/_files/meson_build.py +++ b/babelizer/_files/meson_build.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import os from collections import defaultdict from collections.abc import Iterable @@ -60,7 +62,7 @@ def render(paths: Iterable[str], install: Iterable[str] = ()) -> str: return (2 * os.linesep).join(contents) -def _render_install_block(install: Iterable[str]): +def _render_install_block(install: Iterable[str]) -> str: install_sources = defaultdict(list) for root, fname in (os.path.split(src) for src in install): install_sources[root].append(fname) diff --git a/babelizer/_files/readme.py b/babelizer/_files/readme.py index 9308fd0..f9cdbf9 100644 --- a/babelizer/_files/readme.py +++ b/babelizer/_files/readme.py @@ -1,10 +1,14 @@ +from __future__ import annotations + +from typing import Any + from jinja2 import Environment from jinja2 import FileSystemLoader from babelizer._datadir import get_datadir -def render(context): +def render(context: dict[str, Any]) -> str: env = Environment(loader=FileSystemLoader(get_datadir())) template = env.get_template("{{cookiecutter.package_name}}/README.rst") diff --git a/babelizer/cli.py b/babelizer/cli.py index be19859..42b49ac 100644 --- a/babelizer/cli.py +++ b/babelizer/cli.py @@ -1,10 +1,15 @@ """The command line interface to the babelizer.""" +from __future__ import annotations + import fnmatch +import io import os import pathlib import tempfile +from collections.abc import Collection from functools import partial +from typing import cast import click import git @@ -30,8 +35,8 @@ class BabelizerAbort(click.Abort): """Exception raised when a user interrupts the babelizer.""" - def __init__(self, message): - err(str(message)) + def __init__(self, message: str): + err(message) @click.group() @@ -42,7 +47,7 @@ def __init__(self, message): type=click.Path(exists=True, file_okay=False, dir_okay=True, readable=True), help="Change to directory, then execute.", ) -def babelize(cd): +def babelize(cd: str) -> None: """Wrap BMI libraries with Python bindings.""" os.chdir(cd) @@ -71,12 +76,14 @@ def babelize(cd): help="The initial version of the babelized package", ) @click.argument("meta", type=click.File(mode="r")) -def init(meta, template, quiet, verbose, package_version): +def init( + meta: click.File, template: str, quiet: bool, verbose: bool, package_version: str +) -> None: """Initialize a repository with babelized project files. META is babelizer configuration information, usually saved to a file. """ - output = pathlib.Path(".") + output = "." template = template or get_datadir() if not quiet: @@ -84,9 +91,9 @@ def init(meta, template, quiet, verbose, package_version): fmt = pathlib.Path(meta.name).suffix[1:] or "toml" try: - babel_metadata = BabelMetadata.from_stream(meta, fmt=fmt) + babel_metadata = BabelMetadata.from_stream(cast(io.TextIOBase, meta), fmt=fmt) except (ScanError, ValidationError) as error: - raise BabelizerAbort(error) + raise BabelizerAbort(str(error)) try: new_folder = render( @@ -97,13 +104,12 @@ def init(meta, template, quiet, verbose, package_version): version=package_version, ) except (ValidationError, OutputDirExistsError) as error: - raise BabelizerAbort(error) + raise BabelizerAbort(str(error)) if not quiet: out( - "Don't forget to drop model metadata files into {}".format( - new_folder / "meta" - ) + "Don't forget to drop model metadata files into" + f" {os.path.join(new_folder, 'meta')}" ) repo = git.Repo(new_folder) repo.git.add("--all") @@ -133,13 +139,17 @@ def init(meta, template, quiet, verbose, package_version): @click.option( "--set-version", default=None, help="Set the version of the updated package" ) -def update(template, quiet, verbose, set_version): +def update( + template: str | None, quiet: bool, verbose: bool, set_version: str | None +) -> None: """Update an existing babelized project.""" - package_path = pathlib.Path(".").resolve() + package_path = os.path.realpath(".") for fname in ("babel.toml", "babel.yaml", "plugin.yaml"): - if (package_path / fname).is_file(): - metadata_path = package_path / fname + # if (package_path / fname).is_file(): + # metadata_path = package_path / fname + if os.path.isfile(os.path.join(package_path, fname)): + metadata_path = os.path.join(package_path, fname) break else: metadata_path = None @@ -156,7 +166,7 @@ def update(template, quiet, verbose, set_version): try: babel_metadata = BabelMetadata.from_path(metadata_path) except ValidationError as error: - raise BabelizerAbort(error) + raise BabelizerAbort(str(error)) try: version = set_version or get_setup_py_version() @@ -170,12 +180,14 @@ def update(template, quiet, verbose, set_version): ] ) ) + version = "0.1.0" if version is None else version out(f"re-rendering {package_path}") with save_files(["CHANGES.rst", "CREDITS.rst"]): render( babel_metadata, - package_path.parent, + os.path.dirname(package_path), + # package_path.parent, template=template, clobber=True, version=version, @@ -196,22 +208,21 @@ def update(template, quiet, verbose, set_version): if not quiet: out( - "Don't forget to drop model metadata files into {}".format( - package_path / "meta" - ) + "Don't forget to drop model metadata files into" + f" {os.path.join(package_path, 'meta')}" ) print(package_path) @babelize.command() -def sample_config(): +def sample_config() -> None: """Generate the babelizer configuration file.""" print_sample_config() @babelize.command() -def sample_license(): +def sample_license() -> None: """Generate a license file.""" context = { "info": { @@ -224,7 +235,7 @@ def sample_license(): @babelize.command() -def sample_gitignore(): +def sample_gitignore() -> None: """Generate a .gitignore file.""" context = { "package": {"name": "springfield_monorail"}, @@ -235,7 +246,7 @@ def sample_gitignore(): @babelize.command() @click.argument("extension", nargs=-1) -def sample_meson_build(extension): +def sample_meson_build(extension: Collection[str]) -> None: """Generate a meson.build file.""" if len(extension) == 0: contents = render_meson_build( @@ -259,7 +270,7 @@ def sample_meson_build(extension): @babelize.command() -def sample_readme(): +def sample_readme() -> None: context = { "cookiecutter": { "language": "python", @@ -280,26 +291,27 @@ def sample_readme(): print(render_readme(context)) -def _get_dir_contents(base, trunk=None): - base = pathlib.Path(base) +def _get_dir_contents(base: str, trunk: str | None = None) -> set[str]: files = set() - for item in base.iterdir(): - if item.is_dir(): + for item in os.listdir(base): + if os.path.isdir(item): files |= _get_dir_contents(item, trunk=trunk) else: - files.add(str(item.relative_to(trunk))) + files.add(os.path.relpath(item, start=trunk)) return files -def _repo_contents(base): - repo = git.Repo(str(base)) +def _repo_contents(base: str) -> set[str]: + repo = git.Repo(base) return set( repo.git.ls_tree("--full-tree", "-r", "--name-only", "HEAD").splitlines() ) -def _generated_files(babel_metadata, template=None, version="0.1"): +def _generated_files( + babel_metadata: BabelMetadata, template: str | None = None, version: str = "0.1" +) -> set[str]: with tempfile.TemporaryDirectory() as tmpdir: new_folder = render( babel_metadata, diff --git a/babelizer/metadata.py b/babelizer/metadata.py index c98260c..c407cae 100644 --- a/babelizer/metadata.py +++ b/babelizer/metadata.py @@ -1,12 +1,18 @@ """Library metadata used by the babelizer to wrap libraries.""" +from __future__ import annotations + +import io import pathlib import sys import warnings from collections import defaultdict +from collections.abc import Callable from collections.abc import Generator +from collections.abc import Iterable from collections.abc import Mapping from contextlib import suppress +from typing import Any import tomli_w import yaml @@ -20,7 +26,11 @@ from babelizer.errors import ValidationError -def validate_dict(meta, required=None, optional=None): +def validate_dict( + meta: dict[str, Any], + required: Iterable[str] | None = None, + optional: Iterable[str] | None = None, +) -> None: """Validate babelizer configuration metadata. Parameters @@ -57,7 +67,7 @@ def validate_dict(meta, required=None, optional=None): ) -def _norm_os(name): +def _norm_os(name: str) -> str: if name == "linux": name = "ubuntu" elif name == "mac": @@ -67,13 +77,22 @@ def _norm_os(name): return name -class BabelMetadata(Mapping): +class BabelMetadata(Mapping[str, Any]): """Library metadata.""" - LOADERS = {"yaml": yaml.safe_load, "toml": tomllib.loads} + LOADERS: dict[str, Callable[[str], dict[str, Any]]] = { + "yaml": yaml.safe_load, + "toml": tomllib.loads, + } def __init__( - self, library=None, build=None, package=None, info=None, plugin=None, ci=None + self, + library: dict[str, Any] | None = None, + build: dict[str, Any] | None = None, + package: dict[str, Any] | None = None, + info: dict[str, Any] | None = None, + plugin: dict[str, Any] | None = None, + ci: dict[str, Any] | None = None, ): """Metadata used by the babelizer to wrap a library. @@ -122,7 +141,7 @@ def __len__(self) -> int: return len(self._meta) @classmethod - def from_stream(cls, stream, fmt="toml"): + def from_stream(cls, stream: io.TextIOBase, fmt: str = "toml") -> BabelMetadata: """Create an instance of BabelMetadata from a file-like object. Parameters @@ -154,7 +173,7 @@ def from_stream(cls, stream, fmt="toml"): return cls(**meta) @classmethod - def from_path(cls, filepath): + def from_path(cls, filepath: str) -> BabelMetadata: """Create an instance of BabelMetadata from a path-like object. Parameters @@ -171,25 +190,8 @@ def from_path(cls, filepath): with open(filepath) as fp: return BabelMetadata.from_stream(fp, fmt=path.suffix[1:]) - def get(self, section, value): - """Get a metadata value from the given section. - - Parameters - ---------- - section : str - Section name. - value : str - Key name. - - Returns - ------- - value - Metadata value. - """ - return self._meta[section][value] - @staticmethod - def validate(config): + def validate(config: dict[str, Any]) -> None: """Ensure babelizer configuration metadata are valid. Parameters @@ -262,8 +264,8 @@ def validate(config): ) @staticmethod - def _handle_old_style_entry_points(library): - def _header_ext(language): + def _handle_old_style_entry_points(library: dict[str, Any]) -> dict[str, Any]: + def _header_ext(language: str) -> str: try: return {"c": ".h", "c++": ".hxx"}[language] except KeyError: @@ -275,20 +277,20 @@ def _header_ext(language): libraries = {} for entry_point in entry_points: - babelized_class, library, class_name = BabelMetadata.parse_entry_point( + babelized_class, library_name, class_name = BabelMetadata.parse_entry_point( entry_point ) libraries[babelized_class] = { "language": language, - "library": library, - "header": library + _header_ext(language), + "library": library_name, + "header": library_name + _header_ext(language), "entry_point": class_name, } return libraries @staticmethod - def _handle_old_style_info(info): + def _handle_old_style_info(info: dict[str, Any]) -> dict[str, Any]: return { "package_author": info["plugin_author"], "package_author_email": info["plugin_author_email"], @@ -298,7 +300,7 @@ def _handle_old_style_info(info): } @staticmethod - def norm(config): + def norm(config: dict[str, Any]) -> dict[str, Any]: """Ensure current style metadata are used in babelizer configuration. Parameters @@ -311,7 +313,7 @@ def norm(config): dict A dict of babelizer configuration metadata. """ - build = defaultdict(list) + build: dict[str, list[str]] = defaultdict(list) with suppress(KeyError): build.update(config["build"]) @@ -349,7 +351,7 @@ def norm(config): }, } - def dump(self, fp, fmt="toml"): + def dump(self, fp: io.TextIOBase, fmt: str = "toml") -> None: """Write serialized metadata to a file. Parameters @@ -361,7 +363,7 @@ def dump(self, fp, fmt="toml"): """ print(self.format(fmt=fmt), file=fp, end="") - def format(self, fmt="toml"): + def format(self, fmt: str = "toml") -> str: """Serialize metadata to output format. Parameters @@ -376,7 +378,7 @@ def format(self, fmt="toml"): """ return getattr(self, f"format_{fmt}")() - def format_toml(self): + def format_toml(self) -> str: """Serialize metadata as TOML. Returns @@ -387,7 +389,7 @@ def format_toml(self): return tomli_w.dumps(self._meta, multiline_strings=True) @staticmethod - def parse_entry_point(specifier): + def parse_entry_point(specifier: str) -> tuple[str, str, str]: """Parse an entry point specifier into its parts. Parameters @@ -413,7 +415,7 @@ def parse_entry_point(specifier): >>> BabelMetadata.parse_entry_point("bar:Baz") Traceback (most recent call last): - ,,, + ... babelizer.errors.ValidationError: bad entry point specifier (bar:Baz). specifier must be of the form name=module:class """ try: @@ -426,7 +428,7 @@ def parse_entry_point(specifier): return name, module, obj - def as_cookiecutter_context(self): + def as_cookiecutter_context(self) -> dict[str, Any]: """Format metadata in cookiecutter context. Returns diff --git a/babelizer/render.py b/babelizer/render.py index 48ccb17..bd2e8d5 100644 --- a/babelizer/render.py +++ b/babelizer/render.py @@ -1,14 +1,19 @@ """Render a new babelized project.""" +from __future__ import annotations + import contextlib import os -import pathlib import sys +from collections.abc import Generator +from typing import Any import git from cookiecutter.exceptions import OutputDirExistsException from cookiecutter.main import cookiecutter +from babelizer.metadata import BabelMetadata + try: import black as blk import isort @@ -21,11 +26,8 @@ import tomllib else: # pragma: no cover (= (3, 12): # pragma: no cover (PY12+) - import importlib.resources as importlib_resources -else: # pragma: no cover ( str: """Generate a babelized library. Parameters @@ -71,7 +73,7 @@ def render( Raised if output directory exists and clobber is not set. """ if template is None: - template = str(importlib_resources.files("babelizer") / "data") + template = get_datadir() context = plugin_metadata.as_cookiecutter_context() context["files"] = { @@ -92,16 +94,21 @@ def render( except OutputDirExistsException as err: raise OutputDirExistsError(", ".join(err.args)) - with open(path / "babel.toml", "w") as fp: + with open(os.path.join(path, "babel.toml"), "w") as fp: plugin_metadata.dump(fp, fmt="toml") if make_pretty and MAKE_PRETTY: prettify_python(path) - return path.resolve() + return os.path.realpath(path) -def render_plugin_repo(template, context=None, output_dir=".", clobber=False): +def render_plugin_repo( + template: str, + context: dict[str, Any] | None = None, + output_dir: str = ".", + clobber: bool = False, +) -> str: """Render a repository for a pymt plugin. Parameters @@ -120,7 +127,6 @@ def render_plugin_repo(template, context=None, output_dir=".", clobber=False): path Absolute path to the newly-created repository. """ - output_dir = pathlib.Path(output_dir) context = context or {} try: @@ -138,8 +144,8 @@ def render_plugin_repo(template, context=None, output_dir=".", clobber=False): # path = os.path.join(output_dir, "{}".format(context["package_name"])) # if not os.path.isdir(path): - path = output_dir / f"{name}" - if not path.is_dir(): + path = os.path.join(output_dir, name) + if not os.path.isdir(path): raise RenderError(f"error creating {path}") git.Repo.init(path) @@ -148,7 +154,7 @@ def render_plugin_repo(template, context=None, output_dir=".", clobber=False): @contextlib.contextmanager -def as_cwd(path): +def as_cwd(path: str) -> Generator[None, None, None]: """Change directory context. Parameters @@ -162,7 +168,7 @@ def as_cwd(path): os.chdir(prev_cwd) -def blacken_file(filepath): +def blacken_file(filepath: str) -> None: """Format a Python file with ``black``. Parameters @@ -182,7 +188,7 @@ def blacken_file(filepath): fp.write(new_contents) -def prettify_python(path_to_repo): +def prettify_python(path_to_repo: str) -> None: """Format files in babelized project with ``black``. Parameters @@ -190,15 +196,14 @@ def prettify_python(path_to_repo): path_to_repo : str Path-like object to babelized project. """ - path_to_repo = pathlib.Path(path_to_repo) - with open(path_to_repo / "babel.toml") as fp: + with open(os.path.join(path_to_repo, "babel.toml")) as fp: meta = tomllib.loads(fp.read()) module_name = meta["package"]["name"] files_to_fix = [ - path_to_repo / module_name / "_bmi.py", - path_to_repo / module_name / "__init__.py", - path_to_repo / "docs" / "conf.py", + os.path.join(path_to_repo, module_name, "_bmi.py"), + os.path.join(path_to_repo, module_name, "__init__.py"), + os.path.join(path_to_repo, "docs", "conf.py"), ] config = isort.Config(quiet=True) diff --git a/babelizer/utils.py b/babelizer/utils.py index eaa6dc4..887c038 100644 --- a/babelizer/utils.py +++ b/babelizer/utils.py @@ -5,14 +5,16 @@ import pathlib import subprocess import sys -from collections.abc import Iterator +from collections.abc import Generator +from collections.abc import Iterable +from collections.abc import Sequence from contextlib import contextmanager from contextlib import suppress from babelizer.errors import SetupPyError -def execute(args): +def execute(args: Sequence[str]) -> subprocess.CompletedProcess[bytes]: """Run a command through the ``subprocess`` module. Parameters @@ -28,7 +30,7 @@ def execute(args): return subprocess.run(args, capture_output=True, check=True) -def setup_py(*args): +def setup_py(*args: str) -> list[str]: """Format the command to build/install the babelized package. Returns @@ -67,7 +69,7 @@ def get_setup_py_version() -> str | None: @contextmanager -def save_files(files: Iterator[str]): +def save_files(files: Iterable[str]) -> Generator[dict[str, str], None, None]: """Generate repository files through a context. Parameters diff --git a/news/94.misc b/news/94.misc new file mode 100644 index 0000000..2624de8 --- /dev/null +++ b/news/94.misc @@ -0,0 +1,2 @@ + +Added type annotations to the *babelizer*. diff --git a/pyproject.toml b/pyproject.toml index 2ff094e..47a72c4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -148,6 +148,14 @@ skip = [ "babelizer/data", ] +[tool.mypy] +check_untyped_defs = true +disallow_any_generics = true +disallow_incomplete_defs = true +disallow_untyped_defs = true +warn_redundant_casts = true +warn_unused_ignores = true + [tool.pytest.ini_options] minversion = "6.0" testpaths = [