Skip to content

Commit 7b755f7

Browse files
Add mypy, ruff, and refurb. (#16)
Co-authored-by: Tobias Raabe <raabe@posteo.de>
1 parent b8129b8 commit 7b755f7

20 files changed

+183
-102
lines changed

.pre-commit-config.yaml

Lines changed: 29 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
repos:
22
- repo: https://github.com/pre-commit/pre-commit-hooks
3-
rev: v4.3.0
3+
rev: v4.4.0
44
hooks:
55
- id: check-added-large-files
66
args: ['--maxkb=100']
@@ -24,50 +24,33 @@ repos:
2424
- id: python-no-log-warn
2525
- id: python-use-type-annotations
2626
- id: text-unicode-replacement-char
27-
- repo: https://github.com/asottile/pyupgrade
28-
rev: v3.1.0
29-
hooks:
30-
- id: pyupgrade
31-
args: [--py37-plus]
3227
- repo: https://github.com/asottile/reorder_python_imports
33-
rev: v3.8.5
28+
rev: v3.9.0
3429
hooks:
3530
- id: reorder-python-imports
3631
args: [--py37-plus, --add-import, 'from __future__ import annotations']
3732
- repo: https://github.com/asottile/setup-cfg-fmt
38-
rev: v2.1.0
33+
rev: v2.2.0
3934
hooks:
4035
- id: setup-cfg-fmt
4136
- repo: https://github.com/PyCQA/docformatter
42-
rev: v1.5.0
37+
rev: v1.5.1
4338
hooks:
4439
- id: docformatter
4540
args: [--in-place, --wrap-summaries, "88", --wrap-descriptions, "88", --blank]
4641
- repo: https://github.com/psf/black
47-
rev: 22.10.0
42+
rev: 22.12.0
4843
hooks:
4944
- id: black
50-
- repo: https://github.com/PyCQA/flake8
51-
rev: 5.0.4
45+
- repo: https://github.com/charliermarsh/ruff-pre-commit
46+
rev: v0.0.215
5247
hooks:
53-
- id: flake8
54-
types: [python]
55-
additional_dependencies: [
56-
flake8-alfred,
57-
flake8-bugbear,
58-
flake8-builtins,
59-
flake8-comprehensions,
60-
flake8-docstrings,
61-
flake8-eradicate,
62-
flake8-print,
63-
flake8-pytest-style,
64-
flake8-todo,
65-
flake8-typing-imports,
66-
flake8-unused-arguments,
67-
pep8-naming,
68-
pydocstyle,
69-
Pygments,
70-
]
48+
- id: ruff
49+
- repo: https://github.com/dosisod/refurb
50+
rev: v1.9.1
51+
hooks:
52+
- id: refurb
53+
args: [--ignore, FURB126]
7154
- repo: https://github.com/executablebooks/mdformat
7255
rev: 0.7.16
7356
hooks:
@@ -82,12 +65,27 @@ repos:
8265
hooks:
8366
- id: interrogate
8467
args: [-v, --fail-under=40, src]
68+
- repo: https://github.com/pre-commit/mirrors-mypy
69+
rev: 'v0.991'
70+
hooks:
71+
- id: mypy
72+
args: [
73+
--no-strict-optional,
74+
--ignore-missing-imports,
75+
]
76+
additional_dependencies: [
77+
attrs>=21.3.0,
78+
click,
79+
types-PyYAML,
80+
types-setuptools
81+
]
82+
pass_filenames: false
8583
- repo: https://github.com/codespell-project/codespell
8684
rev: v2.2.2
8785
hooks:
8886
- id: codespell
8987
- repo: https://github.com/mgedmin/check-manifest
90-
rev: "0.48"
88+
rev: "0.49"
9189
hooks:
9290
- id: check-manifest
9391
args: [--no-build-isolation]

CHANGES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ releases are available on [PyPI](https://pypi.org/project/pytask-julia) and
77

88
## 0.3.0 - 2023-xx-xx
99

10+
- {pull}`16` adds mypy, refurb, and ruff.
1011
- {pull}`18` deprecates INI configurations and aligns the package with pytask v0.3.
1112

1213
## 0.2.1 - 2022-04-16

MANIFEST.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,5 @@ exclude *.yml
1010
include README.md
1111
include LICENSE
1212
include pyproject.toml
13+
14+
recursive-include src py.typed

pyproject.toml

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,58 @@ build-backend = "setuptools.build_meta"
55

66
[tool.setuptools_scm]
77
write_to = "src/pytask_julia/_version.py"
8+
9+
10+
[tool.mypy]
11+
files = ["src", "tests"]
12+
check_untyped_defs = true
13+
disallow_any_generics = true
14+
disallow_incomplete_defs = true
15+
disallow_untyped_defs = true
16+
no_implicit_optional = true
17+
warn_redundant_casts = true
18+
warn_unused_ignores = true
19+
20+
21+
[[tool.mypy.overrides]]
22+
module = "tests.*"
23+
disallow_untyped_defs = false
24+
ignore_errors = true
25+
26+
27+
[tool.ruff]
28+
target-version = "py37"
29+
select = ["ALL"]
30+
fix = true
31+
extend-ignore = [
32+
# Numpy docstyle
33+
"D107",
34+
"D203",
35+
"D212",
36+
"D213",
37+
"D402",
38+
"D413",
39+
"D415",
40+
"D416",
41+
"D417",
42+
# Others.
43+
"D404", # Do not start module docstring with "This".
44+
"RET504", # unnecessary variable assignment before return.
45+
"S101", # raise errors for asserts.
46+
"B905", # strict parameter for zip that was implemented in py310.
47+
"I", # ignore isort
48+
"ANN101", # type annotating self
49+
"ANN102", # type annotating cls
50+
"FBT", # flake8-boolean-trap
51+
"EM", # flake8-errmsg
52+
"ANN401", # flake8-annotate typing.Any
53+
"PD", # pandas-vet
54+
]
55+
56+
57+
[tool.ruff.per-file-ignores]
58+
"tests/*" = ["D", "ANN"]
59+
60+
61+
[tool.ruff.pydocstyle]
62+
convention = "numpy"

src/pytask_julia/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
"""This module contains the main namespace."""
12
from __future__ import annotations
23

34
try:

src/pytask_julia/collect.py

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
import subprocess
66
import types
77
from pathlib import Path
8+
from typing import Any
9+
from typing import Callable
810

911
from pytask import depends_on
1012
from pytask import has_mark
@@ -13,6 +15,7 @@
1315
from pytask import parse_nodes
1416
from pytask import produces
1517
from pytask import remove_marks
18+
from pytask import Session
1619
from pytask import Task
1720
from pytask_julia.serialization import SERIALIZERS
1821
from pytask_julia.shared import julia
@@ -33,12 +36,15 @@ def run_jl_script(
3336

3437

3538
@hookimpl
36-
def pytask_collect_task(session, path, name, obj):
39+
def pytask_collect_task(
40+
session: Session, path: Path, name: str, obj: Any
41+
) -> Task | None:
3742
"""Collect a task which is a function.
3843
3944
There is some discussion on how to detect functions in this `thread
40-
<https://stackoverflow.com/q/624926/7523785>`_. :class:`types.FunctionType` does not
41-
detect built-ins which is not possible anyway.
45+
46+
<https://stackoverflow.com/q/624926/7523785>`_. :class:`types.FunctionType`
47+
does notdetect built-ins which is not possible anyway.
4248
4349
"""
4450
__tracebackhide__ = True
@@ -76,7 +82,7 @@ def pytask_collect_task(session, path, name, obj):
7682
task = Task(
7783
base_name=name,
7884
path=path,
79-
function=_copy_func(run_jl_script),
85+
function=_copy_func(run_jl_script), # type: ignore[arg-type]
8086
depends_on=dependencies,
8187
produces=products,
8288
markers=markers,
@@ -104,30 +110,34 @@ def pytask_collect_task(session, path, name, obj):
104110
)
105111

106112
return task
113+
return None
107114

108115

109116
def _parse_julia_mark(
110-
mark, default_options, default_serializer, default_suffix, default_project
111-
):
117+
mark: Mark,
118+
default_options: list[str] | None,
119+
default_serializer: Callable[..., str] | str | None,
120+
default_suffix: str | None,
121+
default_project: str | None,
122+
) -> Mark:
112123
"""Parse a Julia mark."""
113124
script, options, serializer, suffix, project = julia(**mark.kwargs)
114125

115126
parsed_kwargs = {}
116-
for arg_name, value, default in [
127+
for arg_name, value, default in (
117128
("script", script, None),
118129
("options", options, default_options),
119130
("serializer", serializer, default_serializer),
120-
]:
121-
parsed_kwargs[arg_name] = value if value else default
131+
):
132+
parsed_kwargs[arg_name] = value or default
122133

123-
if (
124-
isinstance(parsed_kwargs["serializer"], str)
134+
proposed_suffix = (
135+
SERIALIZERS[parsed_kwargs["serializer"]]["suffix"]
136+
if isinstance(parsed_kwargs["serializer"], str)
125137
and parsed_kwargs["serializer"] in SERIALIZERS
126-
):
127-
proposed_suffix = SERIALIZERS[parsed_kwargs["serializer"]]["suffix"]
128-
else:
129-
proposed_suffix = default_suffix
130-
parsed_kwargs["suffix"] = suffix if suffix else proposed_suffix
138+
else default_suffix
139+
)
140+
parsed_kwargs["suffix"] = suffix or proposed_suffix # type: ignore[assignment]
131141

132142
if isinstance(project, (str, Path)):
133143
parsed_kwargs["project"] = project

src/pytask_julia/config.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010

1111
@hookimpl
12-
def pytask_parse_config(config):
12+
def pytask_parse_config(config: dict[str, Any]) -> None:
1313
"""Register the julia marker."""
1414
config["markers"]["julia"] = "Tasks which are executed with Julia."
1515
config["julia_serializer"] = config.get("julia_serializer", "json")
@@ -35,5 +35,4 @@ def _parse_value_or_whitespace_option(value: Any) -> None | list[str]:
3535
return None
3636
if isinstance(value, list):
3737
return list(map(str, value))
38-
else:
39-
raise ValueError(f"'julia_options' is {value} and not a list.")
38+
raise ValueError(f"'julia_options' is {value} and not a list.")

src/pytask_julia/execute.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616

1717
@hookimpl
18-
def pytask_execute_task_setup(task):
18+
def pytask_execute_task_setup(task: Task) -> None:
1919
"""Check whether environment allows executing Julia files."""
2020
marks = get_marks(task, "julia")
2121
if marks:

src/pytask_julia/parametrize.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
"""Parametrize tasks."""
22
from __future__ import annotations
33

4+
from typing import Any
5+
46
import pytask
57
from pytask import hookimpl
68

79

810
@hookimpl
9-
def pytask_parametrize_kwarg_to_marker(obj, kwargs):
11+
def pytask_parametrize_kwarg_to_marker(obj: Any, kwargs: dict[str, Any]) -> None:
1012
"""Attach parametrized Julia arguments to the function with a marker."""
11-
if callable(obj):
12-
if "julia" in kwargs:
13-
pytask.mark.julia(**kwargs.pop("julia"))(obj)
13+
if callable(obj) and "julia" in kwargs:
14+
pytask.mark.julia(**kwargs.pop("julia"))(obj)

src/pytask_julia/plugin.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"""Register hook specifications and implementations."""
22
from __future__ import annotations
33

4+
from pluggy import PluginManager
45
from pytask import hookimpl
56
from pytask_julia import collect
67
from pytask_julia import config
@@ -9,7 +10,7 @@
910

1011

1112
@hookimpl
12-
def pytask_add_hooks(pm):
13+
def pytask_add_hooks(pm: PluginManager) -> None:
1314
"""Register hook implementations."""
1415
pm.register(collect)
1516
pm.register(config)

0 commit comments

Comments
 (0)