Skip to content

Commit f602462

Browse files
authored
Capture stdout and stderr with the CaptureManager. (#35)
1 parent 60c2fc6 commit f602462

20 files changed

+1721
-33
lines changed

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ repos:
33
rev: v3.2.0
44
hooks:
55
- id: check-added-large-files
6-
args: ['--maxkb=10']
6+
args: ['--maxkb=25']
77
- id: check-merge-conflict
88
- id: check-yaml
99
exclude: meta.yaml

docs/changes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ all releases are available on `Anaconda.org <https://anaconda.org/pytask/pytask>
1313
- :gh:`32` fixes ``pytask clean``.
1414
- :gh:`33` adds a module to apply common parameters to the command line interface.
1515
- :gh:`34` skips ``pytask_collect_task_teardown`` if task is None.
16+
- :gh:`35` adds the ability to capture stdout and stderr with the CaptureManager.
1617

1718

1819
0.0.8 - 2020-10-04

docs/explanations/why_another_build_system.rst

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,27 +5,20 @@ There are a lot of build systems out there with existing communities who accumul
55
lot of experience over time. So why go through the hassle of creating another build
66
system?
77

8-
One reason was pure curiosity. `Waf <https://waf.io>`_ has been used for some time as a
9-
build system for research projects. Although, it has several limitations (difficult
10-
interface, no debugging, cryptic error messages, a bus factor of one), it is also a
11-
mature library. At some point annoyance won over comfort and I (`@tobiasraabe
12-
<https://github.com/tobiasraabe>`_) started to write pytask.
13-
14-
Another reason is that pytask is created having a particular audience in mind. Many
15-
researchers are not computer scientists first, but acquired some programming skills
16-
throughout their careers. This means a build system must be extremely user-friendly or
17-
provide a `steep learning curve <https://english.stackexchange.com/a/6226>`_, because it
18-
is only a tool. Since pytask resembles pytest in some ways, users have an easier time
19-
switching to pytask and feel more comfortable.
20-
21-
The third reason is that pytest seems to provide the ideal architecture for a build
8+
pytask is created having a particular audience in mind. Many researchers are not
9+
computer scientists first, but acquired some programming skills throughout their
10+
careers. This means a build system must be extremely user-friendly or provide a `steep
11+
learning curve <https://english.stackexchange.com/a/6226>`_, because it is only a tool.
12+
Since pytask resembles pytest in some ways, users have an easier time switching to
13+
pytask and feel more comfortable.
14+
15+
The second reason is that pytest seems to provide the ideal architecture for a build
2216
system. Its plugin-based design allows for customization at every level. A build system
2317
is a tool which can be deployed in many different environments whose requirements are
2418
not foreseeable by the developer. If it is easy for users / developers to write plugins
2519
which extend the functionality of pytask it is more valuable. If there is any question
2620
whether pytest's architecture is really suited for this, one should look at the success
27-
of pytest, its wide-spread adoption, and its over 800 plugins (even if most of them
28-
might be dead).
21+
of pytest, its wide-spread adoption, and its over 800 plugins.
2922

3023

3124
Alternatives

docs/tutorials/how_to_capture.rst

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
How to capture
2+
==============
3+
4+
Default stdout/stderr/stdin capturing behavior
5+
----------------------------------------------
6+
7+
During task execution any output sent to ``stdout`` and ``stderr`` is captured. If a
8+
task its according captured output will usually be shown along with the failure
9+
traceback.
10+
11+
In addition, ``stdin`` is set to a "null" object which will fail on attempts to read
12+
from it because it is rarely desired to wait for interactive input when running
13+
automated tasks.
14+
15+
By default capturing is done by intercepting writes to low level file descriptors. This
16+
allows to capture output from simple print statements as well as output from a
17+
subprocess started by a task.
18+
19+
20+
Setting capturing methods or disabling capturing
21+
------------------------------------------------
22+
23+
There are three ways in which ``pytask`` can perform capturing:
24+
25+
* ``fd`` (file descriptor) level capturing (default): All writes going to the operating
26+
system file descriptors 1 and 2 will be captured.
27+
28+
* ``sys`` level capturing: Only writes to Python files ``sys.stdout`` and ``sys.stderr``
29+
will be captured. No capturing of writes to file descriptors is performed.
30+
31+
* ``tee-sys`` capturing: Python writes to ``sys.stdout`` and ``sys.stderr`` will be
32+
captured, however the writes will also be passed-through to the actual ``sys.stdout``
33+
and ``sys.stderr``.
34+
35+
You can influence output capturing mechanisms from the command line:
36+
37+
.. code-block:: console
38+
39+
pytask -s # disable all capturing
40+
pytask --capture=sys # replace sys.stdout/stderr with in-mem files
41+
pytask --capture=fd # also point filedescriptors 1 and 2 to temp file
42+
pytask --capture=tee-sys # combines 'sys' and '-s', capturing sys.stdout/stderr
43+
# and passing it along to the actual sys.stdout/stderr
44+
45+
46+
Using print statements for debugging
47+
------------------------------------
48+
49+
One primary benefit of the default capturing of stdout/stderr output is that you can use
50+
print statements for debugging:
51+
52+
.. code-block:: python
53+
54+
# content of task_capture.py
55+
56+
57+
def task_func1():
58+
assert True
59+
60+
61+
def task_func2():
62+
print("Debug statement")
63+
assert False
64+
65+
and running this module will show you precisely the output of the failing function and
66+
hide the other one:
67+
68+
.. code-block:: console
69+
70+
$ pytask -s
71+
========================= Start pytask session =========================
72+
Platform: win32 -- Python 3.x.x, pytask 0.x.x, pluggy 0.13.x
73+
Root: .
74+
Collected 2 task(s).
75+
76+
F.
77+
=============================== Failures ===============================
78+
_________________ Task task_capture.py::task_func2 failed ______________
79+
80+
Traceback (most recent call last):
81+
File "task_capture.py", line 7, in task_func2
82+
assert False
83+
AssertionError
84+
85+
---------------------- Captured stdout during call ---------------------
86+
Debug statement.
87+
88+
==================== 1 succeeded, 1 failed in 0.01s ====================

docs/tutorials/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,4 @@ organize and start your own project.
1818
how_to_clean
1919
how_to_collect
2020
how_to_make_tasks_persist
21+
how_to_capture

0 commit comments

Comments
 (0)