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
45 changes: 19 additions & 26 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,46 +23,39 @@ jobs:

steps:
- uses: actions/checkout@v5
- uses: prefix-dev/setup-pixi@v0.9.2
- uses: astral-sh/setup-uv@v7
with:
cache: true
environments: typing
- run: pixi run typing
enable-cache: true
- name: Install just
uses: extractions/setup-just@v3
- name: Run type checking
run: just typing

run-tests:

name: Run tests for ${{ matrix.os }} on ${{ matrix.environment }}
name: Run tests for ${{ matrix.os }} on ${{ matrix.python-version }}
runs-on: ${{ matrix.os }}

strategy:
fail-fast: false
matrix:
os: ['ubuntu-latest', 'macos-latest', 'windows-latest']
environment: ['py310', 'py311', 'py312', 'py313', 'py314']
python-version: ['3.10', '3.11', '3.12', '3.13', '3.14']

steps:
- uses: actions/checkout@v5
- uses: prefix-dev/setup-pixi@v0.9.2
- uses: r-lib/actions/setup-r@v2
- name: Install R packages
run: Rscript -e 'install.packages(c("jsonlite", "yaml"), repos="https://cloud.r-project.org")'
- uses: astral-sh/setup-uv@v7
with:
cache: true
environments: ${{ matrix.environment }}
python-version: ${{ matrix.python-version }}
enable-cache: true
- name: Install just
uses: extractions/setup-just@v3

# Unit, integration, and end-to-end tests.
- name: Run tests
run: just test-cov

- name: Run unit tests and doctests.
shell: bash -l {0}
run: pixi run -e ${{ matrix.environment }} test -m "unit or (not integration and not end_to_end)" --cov-report=xml -n auto

- name: Upload unit test coverage reports to Codecov with GitHub Action
uses: codecov/codecov-action@v5
with:
flags: unit

- name: Run end-to-end tests.
shell: bash -l {0}
run: pixi run -e ${{ matrix.environment }} test -m end_to_end --cov-report=xml -n auto

- name: Upload end_to_end test coverage reports to Codecov with GitHub Action
- name: Upload test coverage reports to Codecov with GitHub Action
uses: codecov/codecov-action@v5
with:
flags: end_to_end
2 changes: 0 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,4 @@ src/pytask_r/_version.py
.mypy_cache
.ruff_cache
.pytest_cache
# pixi environments
.pixi
*.egg-info
1 change: 1 addition & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ repos:
hooks:
- id: check-added-large-files
args: ['--maxkb=25']
exclude: ^uv\.lock$
- id: check-case-conflict
- id: check-merge-conflict
- id: check-vcs-permalinks
Expand Down
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ releases are available on [PyPI](https://pypi.org/project/pytask-r) and

## 0.4.2 - 2024-xx-xx

- {pull}`75` switches CI and development tooling from pixi to uv.
- {pull}`50` uses pixi to install R and uses uuid4 to generate more robust file names
for serialized arguments.
- {pull}`51` reenables testing with different Python versions.
Expand Down
22 changes: 22 additions & 0 deletions justfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Install all dependencies
install:
uv sync --all-groups

# Run tests
test *FLAGS:
uv run --group test pytest {{FLAGS}}

# Run tests with coverage
test-cov *FLAGS:
uv run --group test pytest --cov=src --cov=tests --cov-report=xml -n auto {{FLAGS}}

# Run type checking
typing:
uv run --group typing --group test ty check src/ tests/

# Run linting
lint:
uvx prek run -a

# Run all checks (format, lint, typing, test)
check: lint typing test
13,973 changes: 0 additions & 13,973 deletions pixi.lock

This file was deleted.

55 changes: 1 addition & 54 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Tracker = "https://github.com/pytask-dev/pytask-r/issues"
[project.entry-points.pytask]
pytask_r = "pytask_r.plugin"

[project.optional-dependencies]
[dependency-groups]
test = ["pytask-parallel", "pytest", "pytest-cov", "pytest-xdist", "pyyaml"]
typing = ["ty>=0.0.7"]

Expand All @@ -60,7 +60,6 @@ source = "vcs"
allow-direct-references = true

[tool.ruff]
target-version = "py310"
fix = true
unsafe-fixes = true

Expand Down Expand Up @@ -105,57 +104,5 @@ unused-ignore-comment = "ignore"
[tool.pytest.ini_options]
testpaths = ["tests"]
markers = [
"wip: Tests that are work-in-progress.",
"unit: Flag for unit tests which target mainly a single function.",
"integration: Flag for integration tests which may comprise of multiple unit tests.",
"end_to_end: Flag for tests that cover the whole program.",
]
norecursedirs = [".idea", ".tox"]

[tool.pixi.workspace]
channels = ["conda-forge"]
platforms = ["win-64", "linux-64", "osx-64", "osx-arm64"]

[tool.pixi.target.osx-64.dependencies]
libgfortran5 = ">=14.2.0"

[tool.pixi.target.osx-arm64.dependencies]
libgfortran5 = ">=14.2.0"

[tool.pixi.pypi-dependencies]
pytask_r = { path = ".", editable = true }

[tool.pixi.environments]
default = { solve-group = "default" }
test = { features = ["test"], solve-group = "default" }
typing = { features = ["test", "typing"], solve-group = "default" }
py310 = { features = ["py310", "test"]}
py311 = { features = ["py311", "test"]}
py312 = { features = ["py312", "test"]}
py313 = { features = ["py313", "test"]}
py314 = { features = ["py314", "test"]}

[tool.pixi.feature.py310.dependencies]
python = "3.10.*"
[tool.pixi.feature.py311.dependencies]
python = "3.11.*"
[tool.pixi.feature.py312.dependencies]
python = "3.12.*"
[tool.pixi.feature.py313.dependencies]
python = "3.13.*"
[tool.pixi.feature.py314.dependencies]
python = "3.14.*"

[tool.pixi.feature.test.dependencies]
r-base = ">=4.0.0"
r-jsonlite = "*"
r-yaml = "*"

[tool.pixi.feature.test.tasks]
test = "pytest --cov src --cov tests"

[tool.pixi.feature.typing.dependencies]
ty = ">=0.0.7"

[tool.pixi.feature.typing.tasks]
typing = "ty check src/ tests/"
2 changes: 0 additions & 2 deletions tests/test_collect.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
from pytask_r.serialization import SERIALIZERS


@pytest.mark.unit
@pytest.mark.parametrize(
("args", "kwargs", "expectation", "expected"),
[
Expand Down Expand Up @@ -44,7 +43,6 @@ def test_r(args, kwargs, expectation, expected):
assert result == expected


@pytest.mark.unit
@pytest.mark.parametrize(
(
"mark",
Expand Down
2 changes: 0 additions & 2 deletions tests/test_config.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
from __future__ import annotations

import pytest
from pytask import build


@pytest.mark.end_to_end
def test_marker_is_configured(tmp_path):
session = build(paths=tmp_path)
assert "r" in session.config["markers"]
10 changes: 0 additions & 10 deletions tests/test_execute.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
from tests.conftest import parametrize_parse_code_serializer_suffix


@pytest.mark.unit
def test_pytask_execute_task_setup(monkeypatch):
"""Make sure that the task setup raises errors."""
# Act like r is installed since we do not test this.
Expand All @@ -33,7 +32,6 @@ def test_pytask_execute_task_setup(monkeypatch):


@needs_rscript
@pytest.mark.end_to_end
@parametrize_parse_code_serializer_suffix
@pytest.mark.parametrize(
"depends_on",
Expand Down Expand Up @@ -75,7 +73,6 @@ def task_run_r_script(


@needs_rscript
@pytest.mark.end_to_end
@parametrize_parse_code_serializer_suffix
def test_run_r_script_w_task_decorator(
runner, tmp_path, parse_config_code, serializer, suffix
Expand Down Expand Up @@ -105,7 +102,6 @@ def run_r_script(produces=Path("out.txt")): ...


@needs_rscript
@pytest.mark.end_to_end
@parametrize_parse_code_serializer_suffix
def test_raise_error_if_rscript_is_not_found(
tmp_path, monkeypatch, parse_config_code, serializer, suffix
Expand Down Expand Up @@ -139,7 +135,6 @@ def task_run_r_script(produces=Path("out.txt")): ...


@needs_rscript
@pytest.mark.end_to_end
@parametrize_parse_code_serializer_suffix
def test_run_r_script_w_saving_workspace(
runner, tmp_path, parse_config_code, serializer, suffix
Expand Down Expand Up @@ -174,7 +169,6 @@ def task_run_r_script(produces=Path("out.txt")): ...


@needs_rscript
@pytest.mark.end_to_end
@parametrize_parse_code_serializer_suffix
def test_run_r_script_w_wrong_cmd_option(
runner, tmp_path, parse_config_code, serializer, suffix
Expand Down Expand Up @@ -209,7 +203,6 @@ def task_run_r_script(produces=Path("out.txt")): ...


@needs_rscript
@pytest.mark.end_to_end
def test_run_r_script_w_custom_serializer(runner, tmp_path):
task_source = """
import pytask
Expand Down Expand Up @@ -239,7 +232,6 @@ def task_run_r_script(produces=Path("out.txt")): ...


@needs_rscript
@pytest.mark.end_to_end
def test_run_r_script_fails_w_multiple_markers(runner, tmp_path):
task_source = """
import pytask
Expand All @@ -259,7 +251,6 @@ def task_run_r_script(produces=Path("out.txt")): ...


@needs_rscript
@pytest.mark.end_to_end
def test_run_r_script_with_capital_extension(runner, tmp_path):
task_source = """
import pytask
Expand Down Expand Up @@ -287,7 +278,6 @@ def task_run_r_script(produces=Path("out.txt")): ...


@needs_rscript
@pytest.mark.end_to_end
@parametrize_parse_code_serializer_suffix
def test_run_r_script_w_nested_inputs(
runner, tmp_path, parse_config_code, serializer, suffix
Expand Down
1 change: 0 additions & 1 deletion tests/test_normal_execution_w_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
from pytask import cli


@pytest.mark.end_to_end
@pytest.mark.parametrize(
"dependencies",
[(), ("in.txt",), ("in_1.txt", "in_2.txt")],
Expand Down
3 changes: 0 additions & 3 deletions tests/test_parallel.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@


@needs_rscript
@pytest.mark.end_to_end
@parametrize_parse_code_serializer_suffix
def test_parallel_parametrization_over_source_files_w_loop(
runner, tmp_path, parse_config_code, serializer, suffix
Expand Down Expand Up @@ -69,7 +68,6 @@ def task_execute_r_script(produces=Path(f"{{i}}.rds")):


@needs_rscript
@pytest.mark.end_to_end
@parametrize_parse_code_serializer_suffix
def test_parallel_parametrization_over_source_file_w_loop(
runner, tmp_path, parse_config_code, serializer, suffix
Expand Down Expand Up @@ -106,7 +104,6 @@ def execute_r_script(produces=Path(f"{{i}}.rds")):


@needs_rscript
@pytest.mark.end_to_end
@parametrize_parse_code_serializer_suffix
@pytest.mark.xfail(reason="@task does not support partialed functions.")
def test_parallel_parametrization_over_source_file_w_loop_and_lambda(
Expand Down
3 changes: 0 additions & 3 deletions tests/test_parametrize.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import textwrap

import pytest
from pytask import ExitCode
from pytask import cli

Expand All @@ -11,7 +10,6 @@


@needs_rscript
@pytest.mark.end_to_end
@parametrize_parse_code_serializer_suffix
def test_parametrized_execution_of_r_script_w_loop(
runner, tmp_path, parse_config_code, serializer, suffix
Expand Down Expand Up @@ -53,7 +51,6 @@ def task_run_r_script(produces=Path(f"{{i}}.txt")):


@needs_rscript
@pytest.mark.end_to_end
@parametrize_parse_code_serializer_suffix
def test_parametrize_r_options_and_product_paths_w_loop(
runner, tmp_path, parse_config_code, serializer, suffix
Expand Down
Loading