Context manager for mocking/wrapping stdin/stdout/stderr
Project description
stdio-mgr: Context manager for mocking/wrapping stdin/stdout/stderr
Current Development Version:
Most Recent Stable Release
Info
Have a CLI Python application?
Want to automate testing of the actual console input & output of your user-facing components?
stdio-mgr can help
stdio-mgr is a context manager for mocking/managing all three standard I/O
streams: stdout, stderr, and stdin. While some functionality here is more
or less duplicative of redirect_stdout and redirect_stderr in
contextlib within the standard library,
it provides (i) a much more concise way to mock both stdout and stderr
at the same time, and (ii) a mechanism for mocking stdin, which is not
available in contextlib.
First, install:
$ pip install stdio-mgr
Then use!
All of the below examples assume stdio_mgr has already been imported via:
from stdio_mgr import stdio_mgr
Mock stdout:
>>> with stdio_mgr() as (in_, out_, err_):
... print('foobar')
... out_cap = out_.getvalue()
>>> out_cap
'foobar\n'
>>> in_.closed and out_.closed and err_.closed
True
By default print appends a newline after each argument, which
is why out_cap is 'foobar\n' and not just 'foobar'.
As currently implemented, stdio_mgr closes all three mocked streams upon
exiting the managed context.
Mock stderr:
>>> import warnings
>>> with stdio_mgr() as (in_, out_, err_):
... warnings.warn("'foo' has no 'bar'")
... err_cap = err_.getvalue()
>>> err_cap
'... UserWarning: \'foo\' has no \'bar\'\n...'
Mock stdin:
The simulated user input has to be pre-loaded to the mocked stream. Be sure to
include newlines in the input to correspond to each mocked Enter
keypress! Otherwise, input will hang, waiting for a newline that will
never come.
If the entirety of the input is known in advance, it can just be provided as an
argument to stdio_mgr. Otherwise, .append() mocked input to in_ within the
managed context as needed:
>>> with stdio_mgr('foobar\n') as (in_, out_, err_):
... print('baz')
... in_cap = input('??? ')
...
... _ = in_.append(in_cap[:3] + '\n')
... in_cap2 = input('??? ')
...
... out_cap = out_.getvalue()
>>> in_cap
'foobar'
>>> in_cap2
'foo'
>>> out_cap
'baz\n??? foobar\n??? foo\n'
The _ = assignment suppresses printing of the return value from the
in_.append() call—otherwise, it would be interleaved in out_cap, since this
example is shown for an interactive context. For non-interactive execution, as
with unittest, pytest, etc., these 'muting' assignments should not be
necessary.
Both the '??? ' prompts for input and the mocked input strings are
echoed to out_, mimicking what a CLI user would see.
A subtlety: While the trailing newline on, e.g., 'foobar\n' is stripped by
input, it is retained in out_. This is because in_ tees the content read
from it to out_ before that content is passed to input.
Want to modify internal print calls within a function or method?
In addition to mocking, stdio_mgr can also be used to wrap functions that
directly output to stdout/stderr. A stdout example:
>>> def emboxen(func):
... def func_wrapper(s):
... from stdio_mgr import stdio_mgr
...
... with stdio_mgr() as (in_, out_, err_):
... func(s)
... content = out_.getvalue()
...
... max_len = max(map(len, content.splitlines()))
... fmt_str = '| {{: <{0}}} |\n'.format(max_len)
...
... newcontent = '=' * (max_len + 4) + '\n'
... for line in content.splitlines():
... newcontent += fmt_str.format(line)
... newcontent += '=' * (max_len + 4)
...
... print(newcontent)
...
... return func_wrapper
>>> @emboxen
... def testfunc(s):
... print(s)
>>> testfunc("""\
... Foo bar baz quux.
... Lorem ipsum dolor sit amet.""")
===============================
| Foo bar baz quux. |
| Lorem ipsum dolor sit amet. |
===============================
Available on PyPI (pip install stdio-mgr).
Source on GitHub. Bug reports and feature requests are welcomed at the Issues page there.
Copyright (c) 2018-2025 Brian Skinn
The stdio-mgr documentation (currently docstrings and README) is licensed
under a Creative Commons Attribution 4.0 International License (CC-BY).
The stdio-mgr codebase is released under the MIT License. See
LICENSE.txt for full license terms.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file stdio_mgr-1.0.1.1.tar.gz.
File metadata
- Download URL: stdio_mgr-1.0.1.1.tar.gz
- Upload date:
- Size: 13.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ed620fc4e4cd034d486a9de1c388507f913b3a1fc8e13f3a041edfc0be2eaa87
|
|
| MD5 |
85d60f3019c8a544eaeb3794540103d6
|
|
| BLAKE2b-256 |
ee8454060a3cc3d1c5282e18c400ae45b603c33ef92b93c0c4a77b0883451db8
|
File details
Details for the file stdio_mgr-1.0.1.1-py3-none-any.whl.
File metadata
- Download URL: stdio_mgr-1.0.1.1-py3-none-any.whl
- Upload date:
- Size: 7.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
21699dad3ab77c443b8178ebc6c924af1945896ca1a0f922ee7927f1d156ea23
|
|
| MD5 |
13736a20054340ca292cd1a4cbb85086
|
|
| BLAKE2b-256 |
5384d3dfc2102409c77b43aacada751e0b23cd49c8b8d44aedce42f4fb339e9e
|