Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/changes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ all releases are available on `PyPI <https://pypi.org/project/pytask>`_ and
- :gh:`87` fixes that dirty versions are displayed in the documentation.
- :gh:`88` adds a ``profile`` command to show information on tasks like duration and
file size of products.
- :gh:`93` fixes the display of parametrized arguments in the console.


0.0.14 - 2021-03-23
Expand Down
17 changes: 17 additions & 0 deletions src/_pytask/console.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,20 @@ def format_strings_as_flat_tree(strings: List[str], title: str, icon: str) -> st
)

return text


def escape_squared_brackets(string: str) -> str:
"""Escape squared brackets which would be accidentally parsed by rich.

An example are the ids of parametrized tasks which are suffixed with squared
brackets surrounding string representations of the parametrized arguments.

Example
-------
>>> escape_squared_brackets("Hello!")
'Hello!'
>>> escape_squared_brackets("task_dummy[arg1-arg2]")
'task_dummy\\\\[arg1-arg2]'

"""
return string.replace("[", "\\[")
4 changes: 3 additions & 1 deletion src/_pytask/nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from typing import Union

import attr
from _pytask.console import escape_squared_brackets
from _pytask.exceptions import NodeNotCollectedError
from _pytask.exceptions import NodeNotFoundError
from _pytask.mark import get_marks_from_obj
Expand Down Expand Up @@ -389,7 +390,8 @@ def reduce_node_name(node, paths: List[Path]):

if isinstance(node, MetaTask):
shortened_path = relative_to(node.path, ancestor)
name = create_task_name(shortened_path, node.base_name)
raw_name = create_task_name(shortened_path, node.base_name)
name = escape_squared_brackets(raw_name)
elif isinstance(node, MetaNode):
name = relative_to(node.path, ancestor).as_posix()
else:
Expand Down
22 changes: 22 additions & 0 deletions tests/test_collect_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,28 @@ def task_dummy():
assert "out.txt>" in captured


@pytest.mark.end_to_end
def test_collect_parametrized_tasks(runner, tmp_path):
source = """
import pytask

@pytask.mark.depends_on("in.txt")
@pytask.mark.parametrize("arg, produces", [(0, "out_0.txt"), (1, "out_1.txt")])
def task_dummy(arg):
pass
"""
tmp_path.joinpath("task_dummy.py").write_text(textwrap.dedent(source))

result = runner.invoke(cli, ["collect", tmp_path.as_posix()])

captured = result.output.replace("\n", "").replace(" ", "").replace("\u2502", "")
assert "<Module" in captured
assert "task_dummy.py>" in captured
assert "<Function" in captured
assert "[0-out_0.txt]>" in captured
assert "[1-out_1.txt]>" in captured


@pytest.mark.end_to_end
def test_collect_task_with_expressions(runner, tmp_path):
source = """
Expand Down