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

Fix issues flagged by mypy strict #3490

Merged
merged 33 commits into from
Jan 12, 2024
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
2314e6f
Move mypy setup from pre-commit
merelcht Jan 4, 2024
3b08d60
Fix no implicit optionals
merelcht Jan 4, 2024
817559a
Fix Optional[...] must have exactly one type argument
merelcht Jan 4, 2024
6b328aa
Fix mypy type incompatibility errors
merelcht Jan 4, 2024
c61c0e2
Fix remaining mypy issues
merelcht Jan 5, 2024
dffc216
Fix starter list
merelcht Jan 5, 2024
188d698
Fix lint + docs
merelcht Jan 5, 2024
770398a
Fix mypy errors cli/cli.py and cli/hooks/manager.py
merelcht Jan 5, 2024
5c5c329
Fix mypy errors in micropkg.py
merelcht Jan 5, 2024
003a771
Fix mypy errors + allow any generics
merelcht Jan 5, 2024
41a6e63
Fix mypy strict issues
merelcht Jan 8, 2024
f95109a
Fix all solveable error + ignore the ones that are not valid in kedro…
merelcht Jan 8, 2024
33d867a
Make all ignored types specific for error
merelcht Jan 8, 2024
d961ff9
Make all ignored types specific for error
merelcht Jan 8, 2024
e1a1d96
Suggestion from review
merelcht Jan 8, 2024
7965be3
Address review comment
merelcht Jan 9, 2024
0bdcc6a
Merge branch 'main' into revisit-mypy-setup
merelcht Jan 9, 2024
71b69a1
Merge branch 'main' into revisit-mypy-setup
merelcht Jan 9, 2024
b3f08ef
Address comment about order of type | None
merelcht Jan 11, 2024
6ad1029
Merge branch 'main' into revisit-mypy-setup
merelcht Jan 11, 2024
5d021ea
Fix `mypy` strict issues #2 (#3497)
merelcht Jan 11, 2024
057fde9
Merge branch 'revisit-mypy-setup' into fix-issues-flagged-by-mypy-strict
merelcht Jan 11, 2024
1a88588
Merge branch 'main' into fix-issues-flagged-by-mypy-strict
merelcht Jan 11, 2024
e4e476b
Fix error about | typing requires python 3.10
merelcht Jan 11, 2024
bf2cbf1
Fix `mypy` error postitional only (#3498)
merelcht Jan 11, 2024
5158198
Fix lint
merelcht Jan 11, 2024
f485dfc
Fix TypeError: 'type' object is not subscriptable
merelcht Jan 11, 2024
4613506
Fix incorrect position for positional arguments
merelcht Jan 11, 2024
31a8a39
Add test for coverage
merelcht Jan 11, 2024
2d0c73f
Merge branch 'main' into fix-issues-flagged-by-mypy-strict
merelcht Jan 11, 2024
e7f5765
Merge branch 'main' into fix-issues-flagged-by-mypy-strict
merelcht Jan 12, 2024
5a25a1e
Fix mypy strict
merelcht Jan 12, 2024
8be9093
Address review comments
merelcht Jan 12, 2024
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
44 changes: 0 additions & 44 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,27 +32,6 @@ repos:
- id: requirements-txt-fixer # Sorts entries in requirements.txt
exclude: "^kedro/templates/|^features/steps/test_starter/"

- repo: https://github.com/pre-commit/mirrors-mypy
rev: v0.961
hooks:
- id: mypy
args: [--allow-redefinition, --ignore-missing-imports]
exclude: |
(?x)(
^kedro/templates/|
^docs/|
^features/steps/test_starter/
)
additional_dependencies:
- types-cachetools
- types-filelock
- types-PyYAML
- types-redis
- types-requests
- types-setuptools
- types-toml
- attrs

- repo: https://github.com/asottile/blacken-docs
rev: v1.12.1
hooks:
Expand All @@ -69,29 +48,8 @@ repos:
pass_filenames: false
entry: lint-imports

- repo: https://github.com/pre-commit/mirrors-mypy
rev: v0.961
hooks:
- id: mypy
args: [--allow-redefinition, --ignore-missing-imports]
exclude: |
(?x)(
^kedro/templates/|
^docs/|
^features/steps/test_starter/
)
additional_dependencies:
- types-cachetools
- types-filelock
- types-PyYAML
- types-redis
- types-requests
- types-setuptools
- types-toml
- attrs
- repo: local
hooks:
# Slow lintint
- id: secret_scan
name: "Secret scan"
language: system
Expand All @@ -104,5 +62,3 @@ repos:
types: [file, python]
exclude: ^kedro/templates/|^tests/|^features/steps/test_starter
entry: bandit -ll

# Manual only
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ clean:

lint:
pre-commit run -a --hook-stage manual $(hook)
mypy kedro --strict --allow-any-generics
test:
pytest --numprocesses 4 --dist loadfile

Expand Down
1 change: 1 addition & 0 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@
"D.get(k,d), also set D[k]=d if k not in D",
"D[k] if k in D, else d. d defaults to None.",
"None. Update D from mapping/iterable E and F.",
"Patterns",
),
"py:data": (
"typing.Any",
Expand Down
2 changes: 1 addition & 1 deletion docs/source/hooks/examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,7 @@ class NodeInputReplacementHook:
@hook_impl
def before_node_run(
self, node: Node, catalog: DataCatalog
) -> Optional[Dict[str, Any]]:
) -> Optional | Dict[str, Any]:
"""Replace `first_input` for `my_node`"""
if node.name == "my_node":
# return the string filepath to the `first_input` dataset
Expand Down
2 changes: 1 addition & 1 deletion features/steps/sh_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ def __init__(self, cmd: list[str], **kwargs) -> None:
**kwargs: keyword arguments such as env and cwd

"""
super().__init__( # type: ignore
super().__init__(
cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, **kwargs
)

Expand Down
4 changes: 2 additions & 2 deletions kedro/config/abstract_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ class AbstractConfigLoader(UserDict):
def __init__(
self,
conf_source: str,
env: str = None,
runtime_params: dict[str, Any] = None,
env: None | str = None,
runtime_params: None | dict[str, Any] = None,
**kwargs,
):
super().__init__()
Expand Down
32 changes: 17 additions & 15 deletions kedro/config/omegaconf_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@
import io
import logging
import mimetypes
import typing
from pathlib import Path
from typing import Any, Callable, Iterable

import fsspec
from omegaconf import OmegaConf
from omegaconf import DictConfig, ListConfig, OmegaConf
from omegaconf.errors import InterpolationResolutionError, UnsupportedInterpolationType
from omegaconf.resolvers import oc
from yaml.parser import ParserError
Expand Down Expand Up @@ -76,14 +77,14 @@ class OmegaConfigLoader(AbstractConfigLoader):
def __init__( # noqa: PLR0913
self,
conf_source: str,
env: str = None,
runtime_params: dict[str, Any] = None,
env: None | str = None,
runtime_params: None | dict[str, Any] = None,
*,
config_patterns: dict[str, list[str]] = None,
base_env: str = None,
default_run_env: str = None,
custom_resolvers: dict[str, Callable] = None,
merge_strategy: dict[str, str] = None,
config_patterns: None | dict[str, list[str]] = None,
base_env: None | str = None,
default_run_env: None | str = None,
custom_resolvers: None | dict[str, Callable] = None,
merge_strategy: None | dict[str, str] = None,
):
"""Instantiates a ``OmegaConfigLoader``.

Expand Down Expand Up @@ -251,6 +252,7 @@ def __repr__(self): # pragma: no cover
f"config_patterns={self.config_patterns})"
)

@typing.no_type_check
def load_and_merge_dir_config( # noqa: PLR0913
self,
conf_path: str,
Expand Down Expand Up @@ -431,7 +433,7 @@ def _check_duplicates(seen_files_to_keys: dict[Path, set[Any]]):
raise ValueError(f"{dup_str}")

@staticmethod
def _resolve_environment_variables(config: dict[str, Any]) -> None:
def _resolve_environment_variables(config: DictConfig | ListConfig) -> None:
"""Use the ``oc.env`` resolver to read environment variables and replace
them in-place, clearing the resolver after the operation is complete if
it was not registered beforehand.
Expand Down Expand Up @@ -466,16 +468,16 @@ def _soft_merge(config, env_config):
# Soft merge the two env dirs. The chosen env will override base if keys clash.
return OmegaConf.to_container(OmegaConf.merge(config, env_config))

def _is_hidden(self, path: str):
def _is_hidden(self, path_str: str):
"""Check if path contains any hidden directory or is a hidden file"""
path = Path(path)
path = Path(path_str)
conf_path = Path(self.conf_source).resolve().as_posix()
if self._protocol == "file":
path = path.resolve()
path = path.as_posix()
if path.startswith(conf_path):
path = path.replace(conf_path, "")
parts = path.split(self._fs.sep) # filesystem specific separator
posix_path = path.as_posix()
if posix_path.startswith(conf_path):
posix_path = posix_path.replace(conf_path, "")
parts = posix_path.split(self._fs.sep) # filesystem specific separator
HIDDEN = "."
# Check if any component (folder or file) starts with a dot (.)
return any(part.startswith(HIDDEN) for part in parts)
27 changes: 16 additions & 11 deletions kedro/framework/cli/catalog.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
import copy
from collections import defaultdict
from itertools import chain
from pathlib import Path
from typing import Any

import click
import yaml
Expand All @@ -11,21 +13,22 @@
from kedro.framework.project import pipelines, settings
from kedro.framework.session import KedroSession
from kedro.framework.startup import ProjectMetadata
from kedro.io import AbstractDataset


def _create_session(package_name: str, **kwargs):
def _create_session(package_name: str, **kwargs: Any) -> KedroSession:
kwargs.setdefault("save_on_close", False)
return KedroSession.create(**kwargs)


# noqa: missing-function-docstring
@click.group(name="Kedro")
def catalog_cli(): # pragma: no cover
def catalog_cli() -> None: # pragma: no cover
pass


@catalog_cli.group()
def catalog():
def catalog() -> None:
"""Commands for working with catalog."""


Expand All @@ -42,7 +45,7 @@ def catalog():
callback=split_string,
)
@click.pass_obj
def list_datasets(metadata: ProjectMetadata, pipeline, env):
def list_datasets(metadata: ProjectMetadata, pipeline: str, env: str) -> None:
"""Show datasets per type."""
title = "Datasets in '{}' pipeline"
not_mentioned = "Datasets not mentioned in pipeline"
Expand Down Expand Up @@ -111,11 +114,13 @@ def list_datasets(metadata: ProjectMetadata, pipeline, env):
secho(yaml.dump(result))


def _map_type_to_datasets(datasets, datasets_meta):
def _map_type_to_datasets(
datasets: set[str], datasets_meta: dict[str, AbstractDataset]
) -> dict:
"""Build dictionary with a dataset type as a key and list of
datasets of the specific type as a value.
"""
mapping = defaultdict(list)
mapping = defaultdict(list) # type: ignore[var-annotated]
for dataset in datasets:
is_param = dataset.startswith("params:") or dataset == "parameters"
if not is_param:
Expand All @@ -136,7 +141,7 @@ def _map_type_to_datasets(datasets, datasets_meta):
help="Name of a pipeline.",
)
@click.pass_obj
def create_catalog(metadata: ProjectMetadata, pipeline_name, env):
def create_catalog(metadata: ProjectMetadata, pipeline_name: str, env: str) -> None:
"""Create Data Catalog YAML configuration with missing datasets.

Add ``MemoryDataset`` datasets to Data Catalog YAML configuration
Expand Down Expand Up @@ -185,7 +190,7 @@ def create_catalog(metadata: ProjectMetadata, pipeline_name, env):
click.echo("All datasets are already configured.")


def _add_missing_datasets_to_catalog(missing_ds, catalog_path):
def _add_missing_datasets_to_catalog(missing_ds: list[str], catalog_path: Path) -> None:
if catalog_path.is_file():
catalog_config = yaml.safe_load(catalog_path.read_text()) or {}
else:
Expand All @@ -204,7 +209,7 @@ def _add_missing_datasets_to_catalog(missing_ds, catalog_path):
@catalog.command("rank")
@env_option
@click.pass_obj
def rank_catalog_factories(metadata: ProjectMetadata, env):
def rank_catalog_factories(metadata: ProjectMetadata, env: str) -> None:
"""List all dataset factories in the catalog, ranked by priority by which they are matched."""
session = _create_session(metadata.package_name, env=env)
context = session.load_context()
Expand All @@ -219,7 +224,7 @@ def rank_catalog_factories(metadata: ProjectMetadata, env):
@catalog.command("resolve")
@env_option
@click.pass_obj
def resolve_patterns(metadata: ProjectMetadata, env):
def resolve_patterns(metadata: ProjectMetadata, env: str) -> None:
"""Resolve catalog factories against pipeline datasets. Note that this command is runner
agnostic and thus won't take into account any default dataset creation defined in the runner."""

Expand Down Expand Up @@ -268,5 +273,5 @@ def resolve_patterns(metadata: ProjectMetadata, env):
secho(yaml.dump(explicit_datasets))


def _trim_filepath(project_path: str, file_path: str):
def _trim_filepath(project_path: str, file_path: str) -> str:
return file_path.replace(project_path, "", 1)
22 changes: 11 additions & 11 deletions kedro/framework/cli/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import sys
from collections import defaultdict
from pathlib import Path
from typing import Sequence
from typing import Any, Sequence

import click

Expand Down Expand Up @@ -42,7 +42,7 @@

@click.group(context_settings=CONTEXT_SETTINGS, name="Kedro")
@click.version_option(version, "--version", "-V", help="Show version and exit")
def cli(): # pragma: no cover
def cli() -> None: # pragma: no cover
"""Kedro is a CLI for creating and using Kedro projects. For more
information, type ``kedro info``.

Expand All @@ -51,7 +51,7 @@ def cli(): # pragma: no cover


@cli.command()
def info():
def info() -> None:
"""Get more information about kedro."""
click.secho(LOGO, fg="green")
click.echo(
Expand Down Expand Up @@ -104,12 +104,12 @@ def __init__(self, project_path: Path):

def main(
self,
args=None,
prog_name=None,
complete_var=None,
standalone_mode=True,
**extra,
):
args: Any | None = None,
prog_name: Any | None = None,
complete_var: Any | None = None,
standalone_mode: bool = True,
**extra: Any,
) -> Any:
if self._metadata:
extra.update(obj=self._metadata)

Expand Down Expand Up @@ -182,13 +182,13 @@ def project_groups(self) -> Sequence[click.MultiCommand]:
raise KedroCliError(
f"Cannot load commands from {self._metadata.package_name}.cli"
)
user_defined = project_cli.cli # type: ignore
user_defined = project_cli.cli
# return built-in commands, plugin commands and user defined commands
# (overriding happens as follows built-in < plugins < cli.py)
return [*built_in, *plugins, user_defined]


def main(): # pragma: no cover
def main() -> None: # pragma: no cover
"""Main entry point. Look for a ``cli.py``, and, if found, add its
commands to `kedro`'s before invoking the CLI.
"""
Expand Down
2 changes: 1 addition & 1 deletion kedro/framework/cli/hooks/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
_CLI_PLUGIN_HOOKS = "kedro.cli_hooks"


def get_cli_hook_manager():
def get_cli_hook_manager() -> PluginManager:
"""Create or return the global _hook_manager singleton instance."""
global _cli_hook_manager # noqa: PLW0603
if _cli_hook_manager is None:
Expand Down
Loading