Skip to content

[pre-commit.ci] pre-commit autoupdate #25

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

Merged
merged 6 commits into from
Mar 29, 2024
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
26 changes: 6 additions & 20 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
rev: v4.5.0
hooks:
- id: check-added-large-files
args: ['--maxkb=100']
Expand All @@ -24,28 +24,19 @@ repos:
- id: python-no-log-warn
- id: python-use-type-annotations
- id: text-unicode-replacement-char
- repo: https://github.com/asottile/reorder-python-imports
rev: v3.12.0
hooks:
- id: reorder-python-imports
args: [--py38-plus, --add-import, 'from __future__ import annotations']
- repo: https://github.com/asottile/setup-cfg-fmt
rev: v2.5.0
hooks:
- id: setup-cfg-fmt
- repo: https://github.com/psf/black
rev: 23.9.1
hooks:
- id: black
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.0.292
rev: v0.3.4
hooks:
- id: ruff
- id: ruff-format
- repo: https://github.com/dosisod/refurb
rev: v1.21.0
rev: v2.0.0
hooks:
- id: refurb
args: [--ignore, FURB126]
- repo: https://github.com/executablebooks/mdformat
rev: 0.7.17
hooks:
Expand All @@ -55,13 +46,8 @@ repos:
mdformat-black,
]
args: [--wrap, "88"]
- repo: https://github.com/econchick/interrogate
rev: 1.5.0
hooks:
- id: interrogate
args: [-v, --fail-under=40, src]
- repo: https://github.com/pre-commit/mirrors-mypy
rev: 'v1.5.1'
rev: 'v1.9.0'
hooks:
- id: mypy
additional_dependencies: [
Expand All @@ -81,7 +67,7 @@ repos:
hooks:
- id: check-manifest
args: [--no-build-isolation]
additional_dependencies: [setuptools-scm, toml]
additional_dependencies: [setuptools-scm, toml, wheel]
- repo: meta
hooks:
- id: check-hooks-apply
Expand Down
6 changes: 2 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -213,8 +213,7 @@ Use the `serializer` keyword arguments of the `@pytask.mark.julia` decorator wit

```python
@pytask.mark.julia(script="script.jl", serializer="yaml")
def task_example():
...
def task_example(): ...
```

And in your Julia script use
Expand All @@ -236,8 +235,7 @@ import json


@pytask.mark.julia(script="script.jl", serializer=json.dumps, suffix=".json")
def task_example():
...
def task_example(): ...
```

### Configuration
Expand Down
43 changes: 11 additions & 32 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@
requires = ["setuptools>=45", "wheel", "setuptools_scm[toml]>=6.0"]
build-backend = "setuptools.build_meta"


[tool.setuptools_scm]
write_to = "src/pytask_julia/_version.py"


[tool.mypy]
files = ["src", "tests"]
check_untyped_defs = true
Expand All @@ -17,50 +15,31 @@ no_implicit_optional = true
warn_redundant_casts = true
warn_unused_ignores = true


[[tool.mypy.overrides]]
module = "tests.*"
disallow_untyped_defs = false
ignore_errors = true


[tool.ruff]
target-version = "py38"
select = ["ALL"]
fix = true
unsafe-fixes = true

[tool.ruff.lint]
extend-ignore = [
"I", # ignore isort
"TRY", # ignore tryceratops
# Numpy docstyle
"D107",
"D203",
"D212",
"D213",
"D402",
"D413",
"D415",
"D416",
"D417",
# Others.
"D404", # Do not start module docstring with "This".
"RET504", # unnecessary variable assignment before return.
"S101", # raise errors for asserts.
"B905", # strict parameter for zip that was implemented in py310.
"ANN101", # type annotating self
"ANN102", # type annotating cls
"FBT", # flake8-boolean-trap
"EM", # flake8-errmsg
"ANN401", # flake8-annotate typing.Any
"PD", # pandas-vet
"COM812", # trailing comma missing, but black takes care of that
"COM812", # Comply with ruff-format.
"ISC001", # Comply with ruff-format.
]
select = ["ALL"]

[tool.ruff.lint.per-file-ignores]
"tests/*" = ["D", "ANN", "S101"]

[tool.ruff.per-file-ignores]
"tests/*" = ["D", "ANN", "PLR2004", "PLR0913"]

[tool.ruff.lint.isort]
force-single-line = true

[tool.ruff.pydocstyle]
[tool.ruff.lint.pydocstyle]
convention = "numpy"

[tool.pytest.ini_options]
Expand Down
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ project_urls =
packages = find:
install_requires =
pluggy>=1.0.0
pytask>=0.4.0
pytask>=0.4.5
python_requires = >=3.8
include_package_data = True
package_dir = =src
Expand Down
3 changes: 2 additions & 1 deletion src/pytask_julia/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""This module contains the main namespace."""
"""Contains the main namespace."""

from __future__ import annotations

try:
Expand Down
30 changes: 17 additions & 13 deletions src/pytask_julia/collect.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Collect tasks."""

from __future__ import annotations

import subprocess
Expand All @@ -7,26 +8,26 @@
from typing import Any
from typing import Callable

from pytask import has_mark
from pytask import hookimpl
from pytask import is_task_function
from pytask import Mark
from pytask import NodeInfo
from pytask import parse_dependencies_from_task_function
from pytask import parse_products_from_task_function
from pytask import PathNode
from pytask import PTask
from pytask import PythonNode
from pytask import remove_marks
from pytask import Session
from pytask import Task
from pytask import TaskWithoutPath
from pytask_julia.serialization import create_path_to_serialized
from pytask import has_mark
from pytask import hookimpl
from pytask import is_task_function
from pytask import parse_dependencies_from_task_function
from pytask import parse_products_from_task_function
from pytask import remove_marks

from pytask_julia.serialization import SERIALIZERS
from pytask_julia.serialization import create_path_to_serialized
from pytask_julia.shared import julia
from pytask_julia.shared import parse_relative_path


_SEPARATOR: str = "--"
"""str: Separates options for the Julia executable and arguments to the file."""

Expand Down Expand Up @@ -62,9 +63,12 @@ def pytask_collect_task(
# Parse the @pytask.mark.julia decorator.
obj, marks = remove_marks(obj, "julia")
if len(marks) > 1:
raise ValueError(
msg = (
f"Task {name!r} has multiple @pytask.mark.julia marks, but only one is "
"allowed.",
"allowed."
)
raise ValueError(
msg,
)

mark = _parse_julia_mark(
Expand Down Expand Up @@ -98,10 +102,11 @@ def pytask_collect_task(
)

if not (isinstance(script_node, PathNode) and script_node.path.suffix == ".jl"):
raise ValueError(
msg = (
"The 'script' keyword of the @pytask.mark.julia decorator must point "
f"to Julia file with the .jl suffix, but it is {script_node}."
)
raise ValueError(msg)

options_node = session.hook.pytask_collect_node(
session=session,
Expand Down Expand Up @@ -211,8 +216,7 @@ def _parse_julia_mark(
else:
parsed_kwargs["project"] = default_project

mark = Mark("julia", (), parsed_kwargs)
return mark
return Mark("julia", (), parsed_kwargs)


def _parse_project(project: str | Path | None, root: Path) -> list[str]:
Expand Down
12 changes: 9 additions & 3 deletions src/pytask_julia/config.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
"""Configure pytask."""

from __future__ import annotations

from typing import Any

from pytask import hookimpl

from pytask_julia.serialization import SERIALIZERS
from pytask_julia.shared import parse_relative_path

Expand All @@ -14,9 +16,12 @@ def pytask_parse_config(config: dict[str, Any]) -> None:
config["markers"]["julia"] = "Tasks which are executed with Julia."
config["julia_serializer"] = config.get("julia_serializer", "json")
if config["julia_serializer"] not in SERIALIZERS:
raise ValueError(
msg = (
f"'julia_serializer' is {config['julia_serializer']} and not one of "
f"{list(SERIALIZERS)}.",
f"{list(SERIALIZERS)}."
)
raise ValueError(
msg,
)
config["julia_suffix"] = config.get("julia_suffix", "")
config["julia_options"] = _parse_value_or_whitespace_option(
Expand All @@ -35,4 +40,5 @@ def _parse_value_or_whitespace_option(value: Any) -> None | list[str]:
return None
if isinstance(value, list):
return list(map(str, value))
raise ValueError(f"'julia_options' is {value} and not a list.")
msg = f"'julia_options' is {value} and not a list."
raise ValueError(msg)
32 changes: 18 additions & 14 deletions src/pytask_julia/execute.py
Original file line number Diff line number Diff line change
@@ -1,41 +1,45 @@
"""Execute tasks."""

from __future__ import annotations

import shutil
from typing import TYPE_CHECKING
from typing import Any

from pytask import get_marks
from pytask import hookimpl
from pytask import PPathNode
from pytask import PTask
from pytask import PythonNode
from pytask import get_marks
from pytask import hookimpl
from pytask.tree_util import tree_map

from pytask_julia.serialization import serialize_keyword_arguments
from pytask_julia.shared import julia

if TYPE_CHECKING:
from pathlib import Path


@hookimpl
def pytask_execute_task_setup(task: PTask) -> None:
"""Check whether environment allows executing Julia files."""
marks = get_marks(task, "julia")
if marks:
if shutil.which("julia") is None:
raise RuntimeError(
msg = (
"julia is needed to run Julia scripts, but it is not found on your "
"PATH.",
"PATH."
)
raise RuntimeError(
msg,
)

assert len(marks) == 1

_, _, serializer, suffix, _ = julia(**marks[0].kwargs)

assert serializer
assert suffix is not None
_, _, serializer, _, _ = julia(**marks[0].kwargs)

serialized_node: PythonNode = task.depends_on["_serialized"] # type: ignore[assignment]
serialized_node.value.parent.mkdir(parents=True, exist_ok=True)
serialized_node = task.depends_on["_serialized"]
path: Path = serialized_node.value # type: ignore[attr-defined]
path.parent.mkdir(parents=True, exist_ok=True)
kwargs = collect_keyword_arguments(task)
serialize_keyword_arguments(serializer, serialized_node.value, kwargs)
serialize_keyword_arguments(serializer, path, kwargs)


def collect_keyword_arguments(task: PTask) -> dict[str, Any]:
Expand Down
2 changes: 2 additions & 0 deletions src/pytask_julia/plugin.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
"""Register hook specifications and implementations."""

from __future__ import annotations

from typing import TYPE_CHECKING

from pytask import hookimpl

from pytask_julia import collect
from pytask_julia import config
from pytask_julia import execute
Expand Down
Loading