Skip to content

Commit 453faf0

Browse files
authored
Make .from_annot an optional feature of nodes. (#409)
1 parent 477e49e commit 453faf0

File tree

4 files changed

+31
-18
lines changed

4 files changed

+31
-18
lines changed

docs/source/changes.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ releases are available on [PyPI](https://pypi.org/project/pytask) and
2626
- {pull}`404` allows to use function returns to define task products.
2727
- {pull}`405` allows to match function returns to node annotations with prefix trees.
2828
- {pull}`406` removes `.value` from `Node` protocol.
29+
- {pull}`407` make `.from_annot` an optional feature of nodes.
2930

3031
## 0.3.2 - 2023-06-07
3132

src/_pytask/collect_utils.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -601,5 +601,11 @@ def _evolve_instance(x: Any, instance_from_annot: Node | None) -> Any:
601601
if not instance_from_annot:
602602
return x
603603

604-
instance_from_annot.from_annot(x)
604+
if not hasattr(instance_from_annot, "from_annot"):
605+
raise AttributeError(
606+
f"The node {instance_from_annot!r} does not define '.from_annot' which is "
607+
f"necessary to complete the node with the value {x!r}."
608+
)
609+
610+
instance_from_annot.from_annot(x) # type: ignore[attr-defined]
605611
return instance_from_annot

src/_pytask/node_protocols.py

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -37,21 +37,6 @@ def save(self, value: Any) -> Any:
3737
"""Save the value that was returned from a task."""
3838
...
3939

40-
def from_annot(self, value: Any) -> Any:
41-
"""Complete the node by setting the value from an default argument.
42-
43-
Use it, if you want to add information on how a node handles an argument while
44-
keeping the type of the value unrelated to pytask.
45-
46-
.. codeblock: python
47-
48-
def task_example(value: Annotated[Any, PythonNode(hash=True)], produces):
49-
...
50-
51-
52-
"""
53-
...
54-
5540

5641
@runtime_checkable
5742
class PPathNode(Node, Protocol):

src/_pytask/nodes.py

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,17 @@ class PathNode(PPathNode):
111111
"""The path to the file."""
112112

113113
def from_annot(self, value: Path) -> None:
114-
"""Set path and if other attributes are not set, set sensible defaults."""
114+
"""Set path and if other attributes are not set, set sensible defaults.
115+
116+
Use it, if you want to control the name of the node.
117+
118+
.. codeblock: python
119+
120+
def task_example(value: Annotated[Any, PathNode(name="value")]):
121+
...
122+
123+
124+
"""
115125
if not isinstance(value, Path):
116126
raise TypeError("'value' must be a 'pathlib.Path'.")
117127
if not self.name:
@@ -176,7 +186,18 @@ def save(self, value: Any) -> None:
176186
self.value = value
177187

178188
def from_annot(self, value: Any) -> None:
179-
"""Set the value from a function annotation."""
189+
"""Set the value from a function annotation.
190+
191+
Use it, if you want to add information on how a node handles an argument while
192+
keeping the type of the value unrelated to pytask. For example, the node could
193+
be hashed.
194+
195+
.. codeblock: python
196+
197+
def task_example(value: Annotated[Any, PythonNode(hash=True)]):
198+
...
199+
200+
"""
180201
self.value = value
181202

182203
def state(self) -> str | None:

0 commit comments

Comments
 (0)