Skip to content

Commit 95f5f1d

Browse files
authored
Remove depends_on and produces markers. (#551)
1 parent b821af9 commit 95f5f1d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+417
-1709
lines changed

docs/source/_static/md/markers.md

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,6 @@ $ pytask markers
66
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
77
┃ Marker ┃ Description ┃
88
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
9-
│ pytask.mark.depends_on │ Add dependencies to a task. See this │
10-
│ │ tutorial for more information: │
11-
│ │ <a href="https://bit.ly/3JlxylS">https://bit.ly/3JlxylS</a>. │
12-
│ │ │
139
│ pytask.mark.persist │ Prevent execution of a task if all │
1410
│ │ products exist and even ifsomething has │
1511
│ │ changed (dependencies, source file, │
@@ -21,10 +17,6 @@ $ pytask markers
2117
│ │ another run will skip the task with │
2218
│ │ success. │
2319
│ │ │
24-
│ pytask.mark.produces │ Add products to a task. See this │
25-
│ │ tutorial for more information: │
26-
│ │ <a href="https://bit.ly/3JlxylS">https://bit.ly/3JlxylS</a>. │
27-
│ │ │
2820
│ pytask.mark.skip │ Skip a task and all its dependent tasks.│
2921
│ │ │
3022
│ pytask.mark.skip_ancestor_failed │ Internal decorator applied to tasks if │

docs/source/changes.md

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

8-
## 0.4.6
8+
## 0.5.0 - 2024-xx-xx
99

1010
- {pull}`548` fixes the type hints for {meth}`~pytask.Task.execute` and
1111
{meth}`~pytask.TaskWithoutPath.execute`. Thanks to {user}`Ostheer`.
12+
- {pull}`551` removes the deprecated `@pytask.mark.depends_on` and
13+
`@pytask.mark.produces`.
1214

1315
## 0.4.5 - 2024-01-09
1416

docs/source/how_to_guides/interfaces_for_dependencies_products.md

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@ In general, pytask regards everything as a task dependency if it is not marked a
1616
product. Thus, you can also think of the following examples as how to inject values into
1717
a task. When we talk about products later, the same interfaces will be used.
1818

19-
| | `def task(arg: ... = ...)` | `Annotated[..., value]` | `@task(kwargs=...)` | `@pytask.mark.depends_on(...)` |
20-
| --------------------------------------- | :------------------------: | :---------------------: | :-----------------: | :----------------------------: |
21-
| Not deprecated |||||
22-
| No type annotations required |||||
23-
| Flexible choice of argument name |||||
24-
| Supports third-party functions as tasks |||||
19+
| | `def task(arg: ... = ...)` | `Annotated[..., value]` | `@task(kwargs=...)` |
20+
| --------------------------------------- | :------------------------: | :---------------------: | :-----------------: |
21+
| Not deprecated ||||
22+
| No type annotations required ||||
23+
| Flexible choice of argument name ||||
24+
| Supports third-party functions as tasks ||||
2525

2626
(default-argument)=
2727

@@ -58,13 +58,13 @@ dictionary. It applies to dependencies and products alike.
5858

5959
## Products
6060

61-
| | `def task(arg: Annotated[..., Product] = ...)` | `Annotated[..., value, Product]` | `produces` | `@task(produces=...)` | `def task() -> Annotated[..., value]` | `@pytask.mark.produces(...)` |
62-
| --------------------------------------------------------- | :--------------------------------------------: | :------------------------------: | :--------: | :-------------------: | :-----------------------------------: | :--------------------------: |
63-
| Not deprecated |||||||
64-
| No type annotations required |||||||
65-
| Flexible choice of argument name |||||||
66-
| Supports third-party functions as tasks |||||||
67-
| Allows to pass custom node while preserving type of value |||||||
61+
| | `def task(arg: Annotated[..., Product] = ...)` | `Annotated[..., value, Product]` | `produces` | `@task(produces=...)` | `def task() -> Annotated[..., value]` |
62+
| --------------------------------------------------------- | :--------------------------------------------: | :------------------------------: | :--------: | :-------------------: | :-----------------------------------: |
63+
| Not deprecated ||||||
64+
| No type annotations required ||||||
65+
| Flexible choice of argument name ||||||
66+
| Supports third-party functions as tasks ||||||
67+
| Allows to pass custom node while preserving type of value ||||||
6868

6969
### `Product` annotation
7070

docs/source/reference_guides/api.md

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -63,36 +63,16 @@ The remaining exceptions convey specific errors.
6363

6464
## Marks
6565

66-
pytask uses marks to attach additional information to task functions which is processed
67-
by the host or by plugins. The following marks are available by default.
66+
pytask uses marks to attach additional information to task functions that the host or
67+
plugins process. The following marks are available by default.
6868

6969
### Built-in marks
7070

7171
```{eval-rst}
72-
.. function:: pytask.mark.depends_on(objects: Any | Iterable[Any] | dict[Any, Any])
73-
74-
Specify dependencies for a task.
75-
76-
:type objects: Any | Iterable[Any] | dict[Any, Any]
77-
:param objects:
78-
Can be any valid Python object or an iterable of any Python objects. To be
79-
valid, it must be parsed by some hook implementation for the
80-
:func:`_pytask.hookspecs.pytask_collect_node` entry-point.
81-
8272
.. function:: pytask.mark.persist()
8373
8474
A marker for a task which should be persisted.
8575
86-
.. function:: pytask.mark.produces(objects: Any | Iterable[Any] | dict[Any, Any])
87-
88-
Specify products of a task.
89-
90-
:type objects: Any | Iterable[Any] | dict[Any, Any]
91-
:param objects:
92-
Can be any valid Python object or an iterable of any Python objects. To be
93-
valid, it must be parsed by some hook implementation for the
94-
:func:`_pytask.hookspecs.pytask_collect_node` entry-point.
95-
9676
.. function:: pytask.mark.skipif(condition: bool, *, reason: str)
9777
9878
Skip a task based on a condition and provide a necessary reason.
@@ -251,10 +231,8 @@ Nodes are the interface for different kinds of dependencies or products.
251231
To parse dependencies and products from nodes, use the following functions.
252232

253233
```{eval-rst}
254-
.. autofunction:: pytask.depends_on
255234
.. autofunction:: pytask.parse_dependencies_from_task_function
256235
.. autofunction:: pytask.parse_products_from_task_function
257-
.. autofunction:: pytask.produces
258236
```
259237

260238
## Tasks

docs/source/tutorials/configuration.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ configuration file.
2121

2222
```toml
2323
[tool.pytask.ini_options]
24-
paths = "src"
24+
paths = ["src"]
2525
```
2626

2727
## The location

docs/source/tutorials/defining_dependencies_products.md

Lines changed: 1 addition & 174 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,6 @@ You find a tutorial on type hints {doc}`here <../type_hints>`.
1111

1212
If you want to avoid type annotations for now, look at the tab named `produces`.
1313

14-
```{warning}
15-
The `Decorators` tab documents the deprecated approach that should not be used anymore
16-
and will be removed in version v0.5.
17-
```
18-
1914
```{seealso}
2015
In this tutorial, we only deal with local files. If you want to use pytask with files
2116
online, S3, GCP, Azure, etc., read the
@@ -89,26 +84,6 @@ passed to this argument is automatically treated as a task product. Here, we pas
8984
path as the default argument.
9085
9186
````
92-
93-
````{tab-item} Decorators
94-
:sync: decorators
95-
96-
```{warning}
97-
This approach is deprecated and will be removed in v0.5
98-
```
99-
100-
```{literalinclude} ../../../docs_src/tutorials/defining_dependencies_products_products_decorators.py
101-
:emphasize-lines: 9, 10
102-
```
103-
104-
The {func}`@pytask.mark.produces <pytask.mark.produces>` marker attaches a product to a
105-
task. After the task has finished, pytask will check whether the file exists.
106-
107-
Add `produces` as an argument of the task function to get access to the same path inside
108-
the task function.
109-
110-
````
111-
11287
`````
11388

11489
```{tip}
@@ -170,24 +145,6 @@ pytask assumes that all function arguments that are not passed to the argument
170145
:emphasize-lines: 9
171146
```
172147
173-
````
174-
175-
````{tab-item} Decorators
176-
:sync: decorators
177-
178-
```{warning}
179-
This approach is deprecated and will be removed in v0.5
180-
```
181-
182-
Equivalent to products, you can use the
183-
{func}`@pytask.mark.depends_on <pytask.mark.depends_on>` decorator to specify that
184-
`data.pkl` is a dependency of the task. Use `depends_on` as a function argument to
185-
access the dependency path inside the function and load the data.
186-
187-
```{literalinclude} ../../../docs_src/tutorials/defining_dependencies_products_dependencies_decorators.py
188-
:emphasize-lines: 9, 11
189-
```
190-
191148
````
192149
`````
193150

@@ -228,25 +185,6 @@ are assumed to point to a location relative to the task module.
228185
:emphasize-lines: 4
229186
```
230187
231-
````
232-
233-
````{tab-item} Decorators
234-
:sync: decorators
235-
236-
```{warning}
237-
This approach is deprecated and will be removed in v0.5
238-
```
239-
240-
You can also use absolute and relative paths as strings that obey the same rules as the
241-
{class}`pathlib.Path`.
242-
243-
```{literalinclude} ../../../docs_src/tutorials/defining_dependencies_products_relative_decorators.py
244-
:emphasize-lines: 6
245-
```
246-
247-
If you use `depends_on` or `produces` as arguments for the task function, you will have
248-
access to the paths of the targets as {class}`pathlib.Path`.
249-
250188
````
251189
`````
252190

@@ -286,7 +224,7 @@ structures if needed.
286224
287225
````
288226
289-
````{tab-item} prodouces
227+
````{tab-item} produces
290228
:sync: produces
291229
292230
If your task has multiple products, group them in one container like a dictionary
@@ -300,117 +238,6 @@ You can do the same with dependencies.
300238
```{literalinclude} ../../../docs_src/tutorials/defining_dependencies_products_multiple2_produces.py
301239
```
302240
303-
````
304-
305-
````{tab-item} Decorators
306-
:sync: decorators
307-
308-
```{warning}
309-
This approach is deprecated and will be removed in v0.5
310-
```
311-
312-
The easiest way to attach multiple dependencies or products to a task is to pass a
313-
{class}`dict` (highly recommended), {class}`list`, or another iterator to the marker
314-
containing the paths.
315-
316-
To assign labels to dependencies or products, pass a dictionary. For example,
317-
318-
```python
319-
from typing import Dict
320-
321-
322-
@pytask.mark.produces({"first": BLD / "data_0.pkl", "second": BLD / "data_1.pkl"})
323-
def task_create_random_data(produces: Dict[str, Path]) -> None:
324-
...
325-
```
326-
327-
Then, use `produces` inside the task function.
328-
329-
```pycon
330-
>>> produces["first"]
331-
BLD / "data_0.pkl"
332-
333-
>>> produces["second"]
334-
BLD / "data_1.pkl"
335-
```
336-
337-
You can also use lists and other iterables.
338-
339-
```python
340-
@pytask.mark.produces([BLD / "data_0.pkl", BLD / "data_1.pkl"])
341-
def task_create_random_data(produces):
342-
...
343-
```
344-
345-
Inside the function, the arguments `depends_on` or `produces` become a dictionary where
346-
keys are the positions in the list.
347-
348-
```pycon
349-
>>> produces
350-
{0: BLD / "data_0.pkl", 1: BLD / "data_1.pkl"}
351-
```
352-
353-
Why does pytask recommend dictionaries and convert lists, tuples, or other
354-
iterators to dictionaries? First, dictionaries with positions as keys behave very
355-
similarly to lists.
356-
357-
Secondly, dictionary keys are more descriptive and do not assume a fixed
358-
ordering. Both attributes are especially desirable in complex projects.
359-
360-
**Multiple decorators**
361-
362-
pytask merges multiple decorators of one kind into a single dictionary. This might help
363-
you to group dependencies and apply them to multiple tasks.
364-
365-
```python
366-
common_dependencies = pytask.mark.depends_on(
367-
{"first_text": "text_1.txt", "second_text": "text_2.txt"}
368-
)
369-
370-
371-
@common_dependencies
372-
@pytask.mark.depends_on("text_3.txt")
373-
def task_example(depends_on):
374-
...
375-
```
376-
377-
Inside the task, `depends_on` will be
378-
379-
```pycon
380-
>>> depends_on
381-
{"first_text": ... / "text_1.txt", "second_text": "text_2.txt", 0: "text_3.txt"}
382-
```
383-
384-
**Nested dependencies and products**
385-
386-
Dependencies and products can be nested containers consisting of tuples, lists, and
387-
dictionaries. It is beneficial if you want more structure and nesting.
388-
389-
Here is an example of a task that fits some model on data. It depends on a module
390-
containing the code for the model, which is not actively used but ensures that the task
391-
is rerun when the model is changed. And it depends on the data.
392-
393-
```python
394-
@pytask.mark.depends_on(
395-
{
396-
"model": [SRC / "models" / "model.py"],
397-
"data": {"a": SRC / "data" / "a.pkl", "b": SRC / "data" / "b.pkl"},
398-
}
399-
)
400-
@pytask.mark.produces(BLD / "models" / "fitted_model.pkl")
401-
def task_fit_model(depends_on, produces):
402-
...
403-
```
404-
405-
`depends_on` within the function will be
406-
407-
```python
408-
{
409-
"model": [SRC / "models" / "model.py"],
410-
"data": {"a": SRC / "data" / "a.pkl", "b": SRC / "data" / "b.pkl"},
411-
}
412-
```
413-
414241
````
415242
`````
416243

0 commit comments

Comments
 (0)