@@ -11,11 +11,6 @@ You find a tutorial on type hints {doc}`here <../type_hints>`.
11
11
12
12
If you want to avoid type annotations for now, look at the tab named ` produces ` .
13
13
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
-
19
14
``` {seealso}
20
15
In this tutorial, we only deal with local files. If you want to use pytask with files
21
16
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
89
84
path as the default argument.
90
85
91
86
````
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
-
112
87
`````
113
88
114
89
``` {tip}
@@ -170,24 +145,6 @@ pytask assumes that all function arguments that are not passed to the argument
170
145
:emphasize-lines: 9
171
146
```
172
147
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
-
191
148
````
192
149
`````
193
150
@@ -228,25 +185,6 @@ are assumed to point to a location relative to the task module.
228
185
:emphasize-lines: 4
229
186
```
230
187
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
-
250
188
````
251
189
`````
252
190
@@ -286,7 +224,7 @@ structures if needed.
286
224
287
225
````
288
226
289
- ````{tab-item} prodouces
227
+ ````{tab-item} produces
290
228
:sync: produces
291
229
292
230
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.
300
238
```{literalinclude} ../../../docs_src/tutorials/defining_dependencies_products_multiple2_produces.py
301
239
```
302
240
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
-
414
241
````
415
242
`````
416
243
0 commit comments