Skip to content

Commit a3c3c6d

Browse files
authored
Parametrization becomes a real plugin. (#10)
1 parent 08d20e2 commit a3c3c6d

File tree

11 files changed

+131
-104
lines changed

11 files changed

+131
-104
lines changed

.pre-commit-config.yaml

Lines changed: 3 additions & 3 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: v3.1.0
3+
rev: v3.2.0
44
hooks:
55
- id: check-added-large-files
66
args: ['--maxkb=10']
@@ -11,12 +11,12 @@ repos:
1111
exclude: (debugging\.py|main\.py)
1212
- id: end-of-file-fixer
1313
- repo: https://github.com/asottile/pyupgrade
14-
rev: v2.7.1
14+
rev: v2.7.2
1515
hooks:
1616
- id: pyupgrade
1717
args: [--py36-plus]
1818
- repo: https://github.com/asottile/reorder_python_imports
19-
rev: v2.3.0
19+
rev: v2.3.5
2020
hooks:
2121
- id: reorder-python-imports
2222
- repo: https://github.com/psf/black

docs/conf.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import sys
1010

1111

12-
sys.path.insert(0, os.path.abspath(".."))
12+
sys.path.insert(0, os.path.abspath("../src"))
1313

1414

1515
# -- Project information ---------------------------------------------------------------
@@ -51,6 +51,8 @@
5151

5252
# Configuration for autodoc
5353
autosummary_generate = True
54+
add_module_names = False
55+
autodoc_mock_imports = ["attr", "click", "networkx", "pluggy", "pony"]
5456

5557
copybutton_prompt_text = r"\\$ |>>> "
5658
copybutton_prompt_is_regexp = True
@@ -61,12 +63,12 @@
6163
}
6264

6365
intersphinx_mapping = {
64-
"python": ("https://docs.python.org/3.7", None),
66+
"python": ("https://docs.python.org/3.8", None),
6567
}
6668

6769
# Configuration for numpydoc
6870
numpydoc_xref_param_type = True
69-
numpydoc_xref_ignore = {"type", "optional", "default"}
71+
numpydoc_xref_ignore = {"type", "optional", "default", "of"}
7072

7173

7274
# -- Options for HTML output -----------------------------------------------------------

docs/index.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ The documentation has currently one of four planned parts.
8585
</div>
8686
</a>
8787
</div>
88+
-->
8889
<div class="col-lg-6 col-md-6 col-sm-6 col-xs-12 d-flex">
8990
<a href="reference_guides/index.html" id="index-link">
9091
<div class="card text-center intro-card shadow">
@@ -102,7 +103,6 @@ The documentation has currently one of four planned parts.
102103
</div>
103104
</a>
104105
</div>
105-
-->
106106
</div>
107107
</div>
108108

docs/reference_guides/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@ additional details on the inner workings of pytask.
1414
:maxdepth: 1
1515

1616
summary
17+
marks

docs/reference_guides/marks.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
Marks
2+
=====
3+
4+
pytask uses marks to attach additional information to task functions which is processed
5+
in the host or in plugins. The following marks are available by default.
6+
7+
8+
pytask.mark.parametrize
9+
-----------------------
10+
11+
.. autofunction:: pytask.parametrize.parametrize

docs/tutorials/how_to_parametrize_a_task.rst

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
How to parametrize a task
22
=========================
33

4-
Often times, you define a task which should be repeated over a range of inputs. Just
5-
like pytest, pytask has a parametrize decorator for this reason.
4+
Often times, you define a task which should be repeated over a range of inputs. pytask
5+
has a parametrize decorator for this reason.
66

77
Since pytask needs to track dependencies and products of tasks, there is a little bit
88
more logic bound to the parametrize decorator which is explained in this section.
@@ -20,10 +20,9 @@ First, we write the task for one number.
2020
.. code-block:: python
2121
2222
import pytask
23-
from pathlib import Path
2423
2524
26-
@pytask.mark.produces(Path("0.txt"))
25+
@pytask.mark.produces("0.txt")
2726
def task_save_number(produces, i=0):
2827
produces.write_text(str(i))
2928
@@ -32,10 +31,9 @@ In the next step, we parametrize the task.
3231
.. code-block:: python
3332
3433
import pytask
35-
from pathlib import pathlib
3634
3735
38-
@pytask.mark.parametrize("produces, i", [(Path(f"{i}.txt"), i) for i in range(5)])
36+
@pytask.mark.parametrize("produces, i", [(f"{i}.txt", i) for i in range(5)])
3937
def task_save_number(produces, i):
4038
produces.write_text(str(i))
4139
@@ -68,7 +66,7 @@ mapped to the argument ``produces`` and ``i`` receives the number.
6866

6967
.. code-block:: python
7068
71-
@pytask.mark.produces(Path("1.txt"))
69+
@pytask.mark.produces("1.txt")
7270
def task_save_number(produces, i=1):
7371
produces.write_text(str(i))
7472
@@ -82,7 +80,10 @@ example is equivalent to the former example.
8280

8381
.. code-block:: python
8482
85-
@pytask.mark.parametrize("produces, i", [(Path(f"{i}.txt"), i) for i in range(5)])
83+
from pathlib import Path
84+
85+
86+
@pytask.mark.parametrize("produces, i", [(f"{i}.txt", i) for i in range(5)])
8687
def task_save_number(i):
8788
Path(__file__).parent.joinpath(f"{i}.txt").write_text(str(i))
8889
@@ -107,7 +108,7 @@ all generated tasks and save it along a generated number to a file.
107108
.. code-block:: python
108109
109110
@pytask.mark.depends_on(Path("additional_text.txt"))
110-
@pytask.mark.parametrize("produces, i", [(Path(f"{i}.txt"), i) for i in range(5)])
111+
@pytask.mark.parametrize("produces, i", [(f"{i}.txt", i) for i in range(5)])
111112
def task_save_number(depends_on, produces, i):
112113
additional_text = depends_on.read_text()
113114
produces.write_text(additional_text + str(i))

src/pytask/collect.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ def pytask_collect_file(session, path, reports):
9090
collected_reports = []
9191
for name, obj in inspect.getmembers(mod):
9292
if has_marker(obj, "parametrize"):
93-
names_and_objects = session.hook.pytask_generate_tasks(
93+
names_and_objects = session.hook.pytask_parametrize_task(
9494
session=session, name=name, obj=obj
9595
)
9696
else:

src/pytask/hookspecs.py

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -81,23 +81,6 @@ def pytask_collect_file(session, path, reports):
8181
"""Collect tasks from files."""
8282

8383

84-
@hookspec(firstresult=True)
85-
def pytask_generate_tasks(session, name, obj):
86-
"""Generate multiple tasks from name and object with parametrization."""
87-
88-
89-
@hookspec(firstresult=True)
90-
def generate_product_of_names_and_functions(
91-
session, name, obj, base_arg_names, arg_names, arg_values
92-
):
93-
"""Generate names and functions from Cartesian product."""
94-
95-
96-
@hookspec
97-
def pytask_generate_tasks_add_marker(obj, kwargs):
98-
"""Add some keyword arguments as markers to task."""
99-
100-
10184
@hookspec(firstresult=True)
10285
def pytask_collect_task_protocol(session, reports, path, name, obj):
10386
"""Start protocol to collect tasks."""
@@ -118,6 +101,19 @@ def pytask_collect_node(path, node):
118101
"""Collect a single node which is a dependency or a product."""
119102

120103

104+
# Hooks to parametrize tasks.
105+
106+
107+
@hookspec(firstresult=True)
108+
def pytask_parametrize_task(session, name, obj):
109+
"""Generate multiple tasks from name and object with parametrization."""
110+
111+
112+
@hookspec
113+
def pytask_parametrize_kwarg_to_marker(obj, kwargs):
114+
"""Add some keyword arguments as markers to object."""
115+
116+
121117
# Hooks for resolving dependencies.
122118

123119

src/pytask/nodes.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
from abc import ABCMeta
44
from abc import abstractmethod
55
from pathlib import Path
6+
from typing import Type
7+
from typing import TypeVar
68

79
import attr
810
from pytask.exceptions import NodeNotCollectedError
@@ -97,14 +99,17 @@ def state(self):
9799
pass
98100

99101

102+
_FilePathNodeType = TypeVar("_FilePathNodeType", bound="FilePathNode")
103+
104+
100105
@attr.s
101106
class FilePathNode(MetaNode):
102107
name = attr.ib()
103108
value = attr.ib()
104109

105110
@classmethod
106111
@functools.lru_cache()
107-
def from_path(cls, path):
112+
def from_path(cls: "Type[_FilePathNodeType]", path: Path) -> _FilePathNodeType:
108113
"""Instantiate class from path to file.
109114
110115
The `lru_cache` decorator ensures that the same object is not collected twice.

0 commit comments

Comments
 (0)