Skip to content

BUG: task.execute returns None despite the function returning a value #547

@Ostheer

Description

@Ostheer
  • I have checked that this issue has not already been reported.
  • I have confirmed this bug exists on the latest version of pytask.
  • (optional) I have confirmed this bug exists on the main branch of pytask.

Code Sample, a copy-pastable example

import pytask
from pathlib import Path
from bandgetouw.config import BLD

for id_ in ("unique_id", "another_one"):
    def some_fun(some_data):
        assert isinstance(some_data, str)
        print(some_data)
        return some_data

    pytask.task(
        id=id_, 
        produces=Path(BLD / "test" / f"{id_}.txt"),
        kwargs={"some_data": "stuff"}
    )(some_fun)

Problem description

This is the output when I run pytask -s:

Collected 10 tasks.

stuff
stuff
╭─────────────────────────────────────┬─────────╮
│ Task                                │ Outcome │
├─────────────────────────────────────┼─────────┤
│ task_test.py::some_fun[another_one] │ F       │
│ task_test.py::some_fun[unique_id]   │ F       │
╰─────────────────────────────────────┴─────────╯

──────────────────────────────────────── Failures ────────────────────────────────────────

──────────────────── Task task_test.py::some_fun[another_one] failed ─────────────────────

TypeError: 'PathNode' can only save 'str' and 'bytes', not <class 'NoneType'>

───────────────────── Task task_test.py::some_fun[unique_id] failed ──────────────────────

TypeError: 'PathNode' can only save 'str' and 'bytes', not <class 'NoneType'>

──────────────────────────────────────────────────────────────────────────────────────────
╭──────────────── Summary ─────────────────╮
│  10  Collected tasks                     │
│  8   Skipped because unchanged  (80.0%)  │
│  2   Failed                     (20.0%)  │
╰──────────────────────────────────────────╯
───────────────────────────────── Failed in 0.03 seconds ─────────────────────────────────

Expected Output

The tasks should succeed and the PathNode should've save "stuff" to the two output files.
Instead, PathNode.save fails because it cannot save the NoneType.

I've traced back the problem to the execute method of the Task class in _pytask.nodes:
There, the function (in this case some_fun) is called: return self.function(**kwargs).
I inspected the return value of self.function(**kwargs)), and it is indeed None. Obviously, I was expecting that value to be the string from some_fun.

In my particular case, my function is a simple lambda wrapper around a function (related to this issue) defined elsewhere called xrn_task. I have been able to work around this issue with the following hack in the Task class:

    def execute(self, **kwargs: Any) -> None:
        """Execute the task."""
        if "xrn_task" in inspect.getsource(self.function):
            from bandgetouw.tasks import xrn_task
            return xrn_task(**kwargs)
        else:
            return self.function(**kwargs)

Additionally, I'm not sure why the return type hint of the execute method is None.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions