Skip to content

Commit fde5668

Browse files
authored
Merge branch 'main' into pending-status
2 parents 53097ce + 225cb19 commit fde5668

30 files changed

+296
-235
lines changed

.github/workflows/main.yml

Lines changed: 16 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ concurrency:
55
group: ${{ github.head_ref || github.run_id }}
66
cancel-in-progress: true
77

8-
env:
9-
CONDA_EXE: mamba
108

119
on:
1210
push:
@@ -25,13 +23,13 @@ jobs:
2523

2624
steps:
2725
- uses: actions/checkout@v4
28-
- uses: actions/setup-python@v5
26+
- uses: astral-sh/setup-uv@v6
2927
with:
30-
python-version-file: .python-version
31-
allow-prereleases: true
32-
cache: pip
33-
- run: pip install tox-uv
34-
- run: tox -e typing
28+
enable-cache: true
29+
- name: Install just
30+
uses: extractions/setup-just@v2
31+
- name: Run type checking
32+
run: just typing
3533

3634
run-tests:
3735

@@ -42,33 +40,18 @@ jobs:
4240
fail-fast: false
4341
matrix:
4442
os: ['ubuntu-latest', 'macos-latest', 'windows-latest']
45-
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12']
43+
python-version: ['3.9', '3.10', '3.11', '3.12', '3.13']
4644

4745
steps:
4846
- uses: actions/checkout@v4
49-
- uses: actions/setup-python@v5
47+
- uses: astral-sh/setup-uv@v6
5048
with:
5149
python-version: ${{ matrix.python-version }}
52-
cache: pip
53-
allow-prereleases: true
54-
- run: pip install tox
55-
56-
# Unit, integration, and end-to-end tests.
57-
58-
- name: Run unit tests and doctests.
59-
shell: bash -l {0}
60-
run: tox -e test -- tests -m "unit or (not integration and not end_to_end)" --cov=src --cov=tests --cov-report=xml
61-
62-
- name: Upload unit test coverage reports to Codecov with GitHub Action
63-
uses: codecov/codecov-action@v4
64-
with:
65-
flags: unit
66-
67-
- name: Run end-to-end tests.
68-
shell: bash -l {0}
69-
run: tox -e test -- tests -m end_to_end --cov=src --cov=tests --cov-report=xml
70-
71-
- name: Upload end_to_end test coverage reports to Codecov with GitHub Action
72-
uses: codecov/codecov-action@v4
73-
with:
74-
flags: end_to_end
50+
enable-cache: true
51+
- name: Install just
52+
uses: extractions/setup-just@v2
53+
- name: Run tests
54+
run: just test
55+
56+
- name: Upload test coverage reports to Codecov with GitHub Action
57+
uses: codecov/codecov-action@v5

.github/workflows/publish-to-pypi.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ jobs:
6767
name: python-package-distributions
6868
path: dist/
6969
- name: Sign the dists with Sigstore
70-
uses: sigstore/gh-action-sigstore-python@v2.1.1
70+
uses: sigstore/gh-action-sigstore-python@v3.0.1
7171
with:
7272
inputs: >-
7373
./dist/*.tar.gz

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,4 @@ tests/test_jupyter/*.txt
2121
.pytest_cache
2222
.ruff_cache
2323
.venv
24+
uv.lock

.pre-commit-config.yaml

Lines changed: 6 additions & 10 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.6.0
3+
rev: v5.0.0
44
hooks:
55
- id: check-added-large-files
66
args: ['--maxkb=25']
@@ -23,20 +23,16 @@ repos:
2323
- id: python-use-type-annotations
2424
- id: text-unicode-replacement-char
2525
- repo: https://github.com/astral-sh/ruff-pre-commit
26-
rev: v0.4.4
26+
rev: v0.12.4
2727
hooks:
2828
- id: ruff
2929
- id: ruff-format
30-
- repo: https://github.com/dosisod/refurb
31-
rev: v2.0.0
32-
hooks:
33-
- id: refurb
3430
- repo: https://github.com/kynan/nbstripout
35-
rev: 0.7.1
31+
rev: 0.8.1
3632
hooks:
3733
- id: nbstripout
3834
- repo: https://github.com/executablebooks/mdformat
39-
rev: 0.7.17
35+
rev: 0.7.22
4036
hooks:
4137
- id: mdformat
4238
additional_dependencies: [
@@ -47,7 +43,7 @@ repos:
4743
args: [--wrap, "88"]
4844
files: (docs/.)
4945
- repo: https://github.com/executablebooks/mdformat
50-
rev: 0.7.17
46+
rev: 0.7.22
5147
hooks:
5248
- id: mdformat
5349
additional_dependencies: [
@@ -57,7 +53,7 @@ repos:
5753
args: [--wrap, "88"]
5854
files: (README\.md)
5955
- repo: https://github.com/codespell-project/codespell
60-
rev: v2.2.6
56+
rev: v2.4.1
6157
hooks:
6258
- id: codespell
6359
- repo: meta

.readthedocs.yaml

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
version: 2
22

33
build:
4-
os: ubuntu-22.04
4+
os: ubuntu-24.04
55
tools:
6-
python: "3.10"
6+
python: "3.12"
7+
jobs:
8+
create_environment:
9+
- asdf plugin add uv
10+
- asdf install uv latest
11+
- asdf global uv latest
12+
- UV_PROJECT_ENVIRONMENT=$READTHEDOCS_VIRTUALENV_PATH uv sync --group docs
13+
install:
14+
- "true"
715

816
sphinx:
917
configuration: docs/source/conf.py
1018
fail_on_warning: true
11-
12-
python:
13-
install:
14-
- method: pip
15-
path: .
16-
extra_requirements:
17-
- docs

docs/source/api.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# API
2+
3+
```{eval-rst}
4+
.. currentmodule:: pytask_parallel
5+
6+
.. autoclass:: ParallelBackend
7+
.. autoclass:: ParallelBackendRegistry
8+
:members:
9+
.. autoclass:: WorkerType
10+
.. autodata:: registry
11+
12+
An instantiated :class:`~pytask_parallel.ParallelBackendRegistry` to register or
13+
overwrite parallel backends.
14+
15+
```

docs/source/changes.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@ chronological order. Releases follow [semantic versioning](https://semver.org/)
55
releases are available on [PyPI](https://pypi.org/project/pytask-parallel) and
66
[Anaconda.org](https://anaconda.org/conda-forge/pytask-parallel).
77

8-
## 0.5.0 - 2024-xx-xx
8+
## 0.5.1 - 2025-03-09
9+
10+
- {pull}`114` drops support for Python 3.8 and adds support for Python 3.13.
11+
12+
## 0.5.0 - 2024-05-26
913

1014
- {pull}`85` simplifies code since loky is a dependency.
1115
- {pull}`86` adds support for dask.
@@ -29,6 +33,8 @@ releases are available on [PyPI](https://pypi.org/project/pytask-parallel) and
2933
- {pull}`106` fixes {pull}`99` such that only when there are coiled functions, all ready
3034
tasks are submitted.
3135
- {pull}`107` removes status from `pytask_execute_task_log_start` hook call.
36+
- {pull}`109` improves the documentation.
37+
- {pull}`110` prepares the release of v0.5.
3238

3339
## 0.4.1 - 2024-01-12
3440

docs/source/coiled.md

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,13 @@ pytask -n 2
5858
pytask --parallel-backend loky
5959
```
6060

61+
```{note}
62+
When you build a project using coiled, you will see a message after pytask's startup
63+
that coiled is creating the remote software environment which takes 1-2m.
64+
```
65+
6166
When you apply the {func}`@task <pytask.task>` decorator to the task, make sure the
62-
{func}`@coiled.function <coiled.function>` decorator is applied first, or is closer to
67+
{func}`@coiled.function <coiled.function>` decorator is applied first or is closer to
6368
the function. Otherwise, it will be ignored. Add more arguments to the decorator to
6469
configure the hardware and software environment.
6570

@@ -71,7 +76,7 @@ By default, {func}`@coiled.function <coiled.function>`
7176
to the workload. It means that coiled infers from the number of submitted tasks and
7277
previous runtimes, how many additional remote workers it should deploy to handle the
7378
workload. It provides a convenient mechanism to scale without intervention. Also,
74-
workers launched by {func}`@coiled.function <coiled.function>` will shutdown quicker
79+
workers launched by {func}`@coiled.function <coiled.function>` will shut down quicker
7580
than a cluster.
7681

7782
```{seealso}
@@ -88,7 +93,8 @@ coiled. Usually, it is not necessary and you are better off using coiled's serve
8893
functions.
8994

9095
If you want to launch a cluster managed by coiled, register a function that builds an
91-
executor using {class}`coiled.Cluster`.
96+
executor using {class}`coiled.Cluster`. Assign a name to the cluster to reuse it when
97+
you build your project again and the cluster has not been shut down.
9298

9399
```python
94100
import coiled
@@ -98,7 +104,11 @@ from concurrent.futures import Executor
98104

99105

100106
def _build_coiled_executor(n_workers: int) -> Executor:
101-
return coiled.Cluster(n_workers=n_workers).get_client().get_executor()
107+
return (
108+
coiled.Cluster(n_workers=n_workers, name="coiled-project")
109+
.get_client()
110+
.get_executor()
111+
)
102112

103113

104114
registry.register_parallel_backend(ParallelBackend.CUSTOM, _build_coiled_executor)
@@ -109,3 +119,12 @@ Then, execute your workflow with
109119
```console
110120
pytask --parallel-backend custom
111121
```
122+
123+
## Tips
124+
125+
When you are changing your project during executions and your cluster is still up and
126+
running, the local and the remote software environment can get out of sync. Then, you
127+
see errors in remote workers you have fixed locally.
128+
129+
A quick solution is to stop the cluster in the coiled dashboard and create a new one
130+
with the next `pytask build`.

docs/source/conf.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
import pytask_parallel
1919

2020
if TYPE_CHECKING:
21-
import sphinx
21+
import sphinx # ty: ignore[unresolved-import]
2222

2323

2424
# -- Project information ---------------------------------------------------------------
@@ -30,7 +30,7 @@
3030
# The version, including alpha/beta/rc tags, but not commit hash and datestamps
3131
release = version("pytask_parallel")
3232
# The short X.Y version.
33-
version = ".".join(release.split(".")[:2])
33+
version = ".".join(release.split(".")[:2]) # ty: ignore[invalid-assignment]
3434

3535
# -- General configuration -------------------------------------------------------------
3636

@@ -100,7 +100,7 @@
100100

101101

102102
# Linkcode, based on numpy doc/source/conf.py
103-
def linkcode_resolve(domain: str, info: dict[str, str]) -> str: # noqa: C901, PLR0912
103+
def linkcode_resolve(domain: str, info: dict[str, str]) -> str | None: # noqa: C901
104104
"""Determine the URL corresponding to Python object."""
105105
if domain != "py":
106106
return None
@@ -123,10 +123,10 @@ def linkcode_resolve(domain: str, info: dict[str, str]) -> str: # noqa: C901, P
123123
return None
124124

125125
try:
126-
fn = inspect.getsourcefile(inspect.unwrap(obj))
126+
fn = inspect.getsourcefile(inspect.unwrap(obj)) # ty: ignore[invalid-argument-type]
127127
except TypeError:
128128
try: # property
129-
fn = inspect.getsourcefile(inspect.unwrap(obj.fget))
129+
fn = inspect.getsourcefile(inspect.unwrap(obj.fget)) # ty: ignore[possibly-unbound-attribute,invalid-argument-type]
130130
except (AttributeError, TypeError):
131131
fn = None
132132
if not fn:
@@ -136,7 +136,7 @@ def linkcode_resolve(domain: str, info: dict[str, str]) -> str: # noqa: C901, P
136136
source, lineno = inspect.getsourcelines(obj)
137137
except TypeError:
138138
try: # property
139-
source, lineno = inspect.getsourcelines(obj.fget)
139+
source, lineno = inspect.getsourcelines(obj.fget) # ty: ignore[possibly-unbound-attribute]
140140
except (AttributeError, TypeError):
141141
lineno = None
142142
except OSError:
@@ -202,7 +202,7 @@ def linkcode_resolve(domain: str, info: dict[str, str]) -> str: # noqa: C901, P
202202
}
203203

204204

205-
def setup(app: sphinx.application.Sphinx) -> None:
205+
def setup(app: sphinx.application.Sphinx) -> None: # ty: ignore[unresolved-attribute]
206206
"""Configure sphinx."""
207207
app.add_object_type(
208208
"confval",

docs/source/custom_executors.md

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,35 @@
11
# Custom Executors
22

3-
```{caution}
4-
The interface for custom executors is rudimentary right now. Please, give some feedback
5-
if you managed to implement a custom executor or have suggestions for improvement.
6-
7-
Please, also consider contributing your executor to pytask-parallel if you believe it
3+
```{note}
4+
Please, consider contributing your executor to pytask-parallel if you believe it
85
could be helpful to other people. Start by creating an issue or a draft PR.
96
```
107

11-
pytask-parallel allows you to use your parallel backend as long as it follows the
12-
interface defined by {class}`~concurrent.futures.Executor`.
8+
pytask-parallel allows you to use any parallel backend as long as it follows the
9+
interface defined by {class}`concurrent.futures.Executor`.
1310

1411
In some cases, adding a new backend can be as easy as registering a builder function
15-
that receives some arguments (currently only `n_workers`) and returns the instantiated
16-
executor.
12+
that receives `n_workers` and returns the instantiated executor.
13+
14+
```{important}
15+
Place the following code in any module that will be imported when you are executing
16+
pytask. For example, the `src/project/config.py` in your project, the
17+
`src/project/__init__.py` or the task module directly.
18+
```
1719

1820
```{literalinclude} ../../docs_src/custom_executors.py
1921
```
2022

21-
Given {class}`pytask_parallel.WorkerType` pytask applies automatic wrappers around the
22-
task function to collect tracebacks, capture stdout/stderr and their like. The `remote`
23-
keyword allows pytask to handle local paths automatically for remote clusters.
23+
Given the optional {class}`~pytask_parallel.WorkerType` pytask applies automatic
24+
wrappers around the task function to collect tracebacks, capture stdout/stderr and their
25+
like. Possible values are `WorkerType.PROCESSES` (default) or `WorkerType.THREADS`.
2426

25-
Now, build the project requesting your custom backend.
27+
The `remote` keyword signals pytask that tasks are executed in remote workers without
28+
access to the local filesystem. pytask will then automatically sync local files to the
29+
workers. By default, pytask assumes workers have access to the local filesystem.
30+
31+
Now, build the project with your custom backend.
2632

2733
```console
2834
pytask --parallel-backend custom
2935
```
30-
31-
```{important}
32-
pytask applies automatic wrappers
33-
```

0 commit comments

Comments
 (0)