Context manager for mocking/wrapping stdin/stdout/stderr
Project description
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 Manager can help.
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-2019 Brian Skinn
License: 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
File details
Details for the file stdio-mgr-1.0.1.tar.gz
.
File metadata
- Download URL: stdio-mgr-1.0.1.tar.gz
- Upload date:
- Size: 7.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/1.12.1 pkginfo/1.5.0.1 requests/2.21.0 setuptools/40.8.0 requests-toolbelt/0.9.1 tqdm/4.31.1 CPython/3.6.6
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 781c3b51632a5e098ecad316e1fa64959ae540e1d66d8ea8a9db9c9b7b9f4186 |
|
MD5 | 027b7e83918676ce44698883cab3d37c |
|
BLAKE2b-256 | dce25a1e907d5ecdcadaca69663d50426a19e513dc1cdbaefbfab9e6212009b4 |
File details
Details for the file stdio_mgr-1.0.1-py3-none-any.whl
.
File metadata
- Download URL: stdio_mgr-1.0.1-py3-none-any.whl
- Upload date:
- Size: 7.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/1.12.1 pkginfo/1.5.0.1 requests/2.21.0 setuptools/40.8.0 requests-toolbelt/0.9.1 tqdm/4.31.1 CPython/3.6.6
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | c8e6c9568709560dfc3e57fa322fe6d72c505ac7e666b12f22aea1589006da95 |
|
MD5 | 81625e1bbacb2b0e4016330f93838f40 |
|
BLAKE2b-256 | f5495a7e6b42fb3b2bca6cc3dedc6e935f224bf0e4ac9fdd1e368d16d540fa7f |