Skip to content
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
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ jobs:

- name: Install core dependencies.
shell: bash -l {0}
run: conda install -c conda-forge tox-conda coverage mamba
run: mamba install -c conda-forge tox-conda coverage mamba

# Unit, integration, and end-to-end tests.

Expand Down
4 changes: 4 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ chronological order. Releases follow [semantic versioning](https://semver.org/)
releases are available on [PyPI](https://pypi.org/project/pytask-julia) and
[Anaconda.org](https://anaconda.org/conda-forge/pytask-julia).

## 0.3.0 - 2023-xx-xx

- {pull}`18` deprecates INI configurations and aligns the package with pytask v0.3.

## 0.2.1 - 2022-04-16

- {pull}`12` includes `pyproject.toml` in the package.
Expand Down
41 changes: 31 additions & 10 deletions Manifest.toml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 14 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
[![image](https://img.shields.io/conda/vn/conda-forge/pytask-julia.svg)](https://anaconda.org/conda-forge/pytask-julia)
[![image](https://img.shields.io/conda/pn/conda-forge/pytask-julia.svg)](https://anaconda.org/conda-forge/pytask-julia)
[![PyPI - License](https://img.shields.io/pypi/l/pytask-julia)](https://pypi.org/project/pytask-julia)
[![image](https://img.shields.io/github/workflow/status/pytask-dev/pytask-julia/main/main)](https://github.com/pytask-dev/pytask-julia/actions?query=branch%3Amain)
[![image](https://img.shields.io/github/actions/workflow/status/pytask-dev/pytask-julia/main.yml?branch=main)](https://github.com/pytask-dev/pytask-julia/actions?query=branch%3Amain)
[![image](https://codecov.io/gh/pytask-dev/pytask-julia/branch/main/graph/badge.svg)](https://codecov.io/gh/pytask-dev/pytask-julia)
[![pre-commit.ci status](https://results.pre-commit.ci/badge/github/pytask-dev/pytask-julia/main.svg)](https://results.pre-commit.ci/latest/github/pytask-dev/pytask-julia/main)
[![image](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black)
Expand Down Expand Up @@ -296,3 +296,16 @@ julia_project = "environment"
## Changes

Consult the [release notes](CHANGES.md) to find out about what is new.

## Development

After setting up the environment, enter

```console
$ julia
$ ]
$ pkg> activate .
$ pkg> instantiate
```

to set up the Julia environment.
4 changes: 2 additions & 2 deletions environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ dependencies:

# Package dependencies
- julia
- pytask >=0.2
- pytask-parallel >=0.1
- pytask >=0.3
- pytask-parallel >=0.3

# Optional package dependencies
- pyyaml
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 =
pybaum>=0.1.1
pytask>=0.2
pytask>=0.3
python_requires = >=3.7
include_package_data = True
package_dir = =src
Expand Down
6 changes: 3 additions & 3 deletions src/pytask_julia/collect.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from pytask import produces
from pytask import remove_marks
from pytask import Task
from pytask_julia.serialization import SERIALIZER
from pytask_julia.serialization import SERIALIZERS
from pytask_julia.shared import julia
from pytask_julia.shared import parse_relative_path

Expand Down Expand Up @@ -122,9 +122,9 @@ def _parse_julia_mark(

if (
isinstance(parsed_kwargs["serializer"], str)
and parsed_kwargs["serializer"] in SERIALIZER
and parsed_kwargs["serializer"] in SERIALIZERS
):
proposed_suffix = SERIALIZER[parsed_kwargs["serializer"]]["suffix"]
proposed_suffix = SERIALIZERS[parsed_kwargs["serializer"]]["suffix"]
else:
proposed_suffix = default_suffix
parsed_kwargs["suffix"] = suffix if suffix else proposed_suffix
Expand Down
28 changes: 17 additions & 11 deletions src/pytask_julia/config.py
Original file line number Diff line number Diff line change
@@ -1,33 +1,39 @@
"""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


@hookimpl
def pytask_parse_config(config, config_from_file):
def pytask_parse_config(config):
"""Register the julia marker."""
config["markers"]["julia"] = "Tasks which are executed with Julia."
config["julia_serializer"] = config_from_file.get("julia_serializer", "json")
config["julia_suffix"] = config_from_file.get("julia_suffix", "")
config["julia_serializer"] = config.get("julia_serializer", "json")
if config["julia_serializer"] not in SERIALIZERS:
raise ValueError(
f"'julia_serializer' is {config['julia_serializer']} and not one of "
f"{list(SERIALIZERS)}."
)
config["julia_suffix"] = config.get("julia_suffix", "")
config["julia_options"] = _parse_value_or_whitespace_option(
config_from_file.get("julia_options")
config.get("julia_options")
)
project = config_from_file.get("julia_project")
project = config.get("julia_project")
if project is None:
config["julia_project"] = project
else:
config["julia_project"] = parse_relative_path(project, config["root"])


def _parse_value_or_whitespace_option(value: str | None) -> None | str | list[str]:
def _parse_value_or_whitespace_option(value: Any) -> None | list[str]:
"""Parse option which can hold a single value or values separated by new lines."""
if value in ["none", "None", None, ""]:
if value is None:
return None
elif isinstance(value, list):
if isinstance(value, list):
return list(map(str, value))
elif isinstance(value, str):
return [v.strip() for v in value.split(" ") if v.strip()]
else:
raise ValueError(f"Input {value!r} is neither a 'str' nor 'None'.")
raise ValueError(f"'julia_options' is {value} and not a list.")
10 changes: 5 additions & 5 deletions src/pytask_julia/serialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
_HIDDEN_FOLDER = ".pytask"


SERIALIZER = {
SERIALIZERS = {
"json": {"serializer": json.dumps, "suffix": ".json"},
}

Expand All @@ -21,8 +21,8 @@
except ImportError: # pragma: no cover
pass
else:
SERIALIZER["yaml"] = {"serializer": yaml.dump, "suffix": ".yaml"}
SERIALIZER["yml"] = {"serializer": yaml.dump, "suffix": ".yml"}
SERIALIZERS["yaml"] = {"serializer": yaml.dump, "suffix": ".yaml"}
SERIALIZERS["yml"] = {"serializer": yaml.dump, "suffix": ".yml"}


def create_path_to_serialized(task: Task, suffix: str) -> Path:
Expand Down Expand Up @@ -57,8 +57,8 @@ def serialize_keyword_arguments(
) -> None:
if callable(serializer):
serializer_func = serializer
elif isinstance(serializer, str) and serializer in SERIALIZER:
serializer_func = SERIALIZER[serializer]["serializer"]
elif isinstance(serializer, str) and serializer in SERIALIZERS:
serializer_func = SERIALIZERS[serializer]["serializer"]
else: # pragma: no cover
raise ValueError(f"Serializer {serializer!r} is not known.")

Expand Down
44 changes: 2 additions & 42 deletions src/pytask_julia/shared.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,45 +6,8 @@
from typing import Sequence


_ERROR_MSG = """The old syntax for @pytask.mark.julia was suddenly deprecated starting \
with pytask-julia v0.2 to provide a better user experience. Thank you for your \
understanding!

It is recommended to upgrade to the new syntax, so you enjoy all the benefits of v0.2 of
pytask and pytask-julia which are

- Access to 'depends_on' and 'produces', and other kwargs inside the Julia script.
- Support for Julia environments for running scripts with certain packages.

You can find a manual here: \
https://github.com/pytask-dev/pytask-julia/blob/v0.2.0/README.md

Upgrading can be as easy as rewriting your current task from

@pytask.mark.julia(["--threads", 2, "--", "path_to_dependency.txt"])
@pytask.mark.depends_on("script.jl")
@pytask.mark.produces("out.csv")
def task_julia():
...

to

@pytask.mark.julia(script="script.jl", options=("--threads", 2))
@pytask.mark.depends_on("path_to_dependency.txt")
@pytask.mark.produces("out.csv")
def task_julia():
...

You can also fix the version of pytask and pytask-julia to <0.2, so you do not have to \
to upgrade. At the same time, you will not enjoy the improvements released with \
version v0.2 of pytask and pytask-julia.

"""


def julia(
*args,
script: str | Path | None = None,
script: str | Path,
options: str | Iterable[str] | None = None,
serializer: str | Callable[..., str] | str | None = None,
suffix: str | None = None,
Expand All @@ -60,7 +23,7 @@ def julia(

Parameters
----------
script : str | Path | None
script : str | Path
The path to the Julia script which is executed.
options : str | Iterable[str] | None
One or multiple command line options passed to the interpreter for Julia.
Expand All @@ -76,9 +39,6 @@ def julia(
A path to an Julia environment used to execute this task.

"""
if args or script is None:
raise RuntimeError(_ERROR_MSG)

options = [] if options is None else list(map(str, _to_list(options)))
return script, options, serializer, suffix, project

Expand Down
Loading