Capturing output#
What is capturing? Some of your tasks may use print()
statements, have progress
bars, require user input, or the libraries you are using show information during
execution.
Since the output would pollute the terminal and the information shown by pytask, it captures all the output during execution and attaches it to the report of this task by default.
If the task fails, the output is shown along with the traceback to help you track down the error.
Default stdout/stderr/stdin capturing behavior#
Any output sent to stdout
and stderr
is captured during task execution. pytask
displays it only if the task fails in addition to the traceback.
In addition, stdin
is set to a “null” object which will fail on attempts to read from
it because it is rarely desired to wait for interactive input when running automated
tasks.
By default, capturing is done by intercepting writes to low-level file descriptors. This
allows capturing output from simple print()
statements as well as output from a
subprocess started by a task.
Setting capturing methods or disabling capturing#
There are three ways in which pytask
can perform capturing:
fd
(file descriptor) level capturing (default): All writes going to the operating system file descriptors 1 and 2 will be captured.sys
level capturing: Only writes to Python filessys.stdout
andsys.stderr
will be captured. No capturing of writes to file descriptors is performed.tee-sys
capturing: Python writes tosys.stdout
andsys.stderr
will be captured. However, the writes will also be passed through to the actualsys.stdout
andsys.stderr
.
You can influence output-capturing mechanisms from the command line:
$ pytask -s # disable all capturing
$ pytask --capture=sys # replace sys.stdout/stderr with in-mem files
$ pytask --capture=fd # also point filedescriptors 1 and 2 to temp file
$ pytask --capture=tee-sys # combines 'sys' and '-s', capturing sys.stdout/stderr
# and passing it along to the actual sys.stdout/stderr
Using print statements for debugging#
One primary benefit of the default capturing of stdout/stderr output is that you can use print statements for debugging:
# content of task_capture.py
def task_func1():
assert True
def task_func2():
print("Debug statement")
assert False
And running this module will show you precisely the output of the failing function and hide the other one:
$ pytask
──────────────────────────── Start pytask session ────────────────────────────
Platform: win32 -- Python <span style="color: var(--termynal-blue)">3.10.0</span>, pytask <span style="color: var(--termynal-blue)">0.4.0</span>, pluggy <span style="color: var(--termynal-blue)">1.0.0</span>
Root: C:\Users\pytask-dev\git\my_project
Collected <span style="color: var(--termynal-blue)">2</span> tasks.
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━┓
┃ Task ┃ Outcome ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━┩
│ <span class="termynal-dim">task_capture.py::</span>task_func1 │ <span class="termynal-success">. </span> │
│ <span class="termynal-dim">task_capture.py::</span>task_func2 │ <span class="termynal-failed">F </span> │
└──────────────────────────────┴─────────┘
<span style="color: #bf2d2d">────────────────────────────────── Failures ──────────────────────────────────</span>
<span style="color: #bf2d2d">─────────────────── Task </span><span style="color: #6c1e1e; font-weight: bold">task_capture.py::</span><span style="color: #bf2d2d">task_func2</span><span style="color: #bf2d2d"> failed ──────────────────</span>
<span style="color: #f14c4c">╭─────────────────────</span><span style="color: #f14c4c; font-weight: bold;"> Traceback </span><span style="color: #6c1e1e; font-weight: bold">(most recent call last)</span><span style="color: #f14c4c"> ────────────────────╮</span>
<span style="color: #cd3131">│</span> <span style="color: #cd3131">│</span>
<span style="color: #cd3131">│</span> <span style="color: #e5e510">...\git\pytask-examples\task_capture.py</span>:<span style="color: #3b8eea">13</span> in <span style="color: #23d18b">task_func2</span> <span style="color: #cd3131">│</span>
<span style="color: #cd3131">│</span> <span style="color: #cd3131">│</span>
<span style="color: #cd3131">│</span> 10 <span style="color: #cd3131">│</span>
<span style="color: #cd3131">│</span> 11 <span style="color: #3b8eea">def</span> <span style="color: #23d18b">task_func2</span>(): <span style="color: #cd3131">│</span>
<span style="color: #cd3131">│</span> 12 │ <span style="color: #29b8db">print</span>(<span style="color: #e5e510">"Debug statement"</span>) <span style="color: #cd3131">│</span>
<span style="color: #cd3131">│</span> <span style="color: #cd3131">❱ </span>13 <span style="font-size: .2em;"> </span>│ <span style="color: #3b8eea">assert</span> <span style="color: #3b8eea">False</span> <span style="color: #cd3131">│</span>
<span style="color: #cd3131">│</span> 14 <span style="color: #cd3131">│</span>
<span style="color: #cd3131">│</span> 15 <span style="color: #cd3131">│</span>
<span style="color: #cd3131">╰────────────────────────────────────────────────────────────────────────────╯</span>
<span style="color: #f14c4c; font-weight: bold;">AssertionError</span>
──────────────────────── Captured stdout during call ─────────────────────────
Debug Statement
<span class="termynal-dim">──────────────────────────────────────────────────────────────────────────────</span>
<span style="color: #bf2d2d">╭─────────── </span><span style="font-weight: bold;">Summary</span><span style="color: #bf2d2d"> ───────────╮</span>
<span style="color: #bf2d2d">│</span> <span style="font-weight: bold"> 2 Collected tasks </span> <span style="color: #bf2d2d">│</span>
<span style="color: #bf2d2d">│</span> <span class="termynal-success-textonly"> 1 Succeeded (50.0%) </span> <span style="color: #bf2d2d">│</span>
<span style="color: #bf2d2d">│</span> <span class="termynal-failed-textonly"> 1 Failed (50.0%) </span> <span style="color: #bf2d2d">│</span>
<span style="color: #bf2d2d">╰───────────────────────────────╯</span>
<span style="color: #bf2d2d">─────────────────────────── Failed in 0.03 seconds ───────────────────────────</span>