Skip to main content

Context manager for mocking/wrapping stdin/stdout/stderr

Project description

Current Development Version:

https://travis-ci.org/bskinn/stdio-mgr.svg?branch=dev https://codecov.io/gh/bskinn/stdio-mgr/branch/dev/graph/badge.svg

Most Recent Stable Release:

https://img.shields.io/pypi/v/stdio_mgr.svg https://img.shields.io/pypi/pyversions/stdio-mgr.svg

Info:

https://img.shields.io/github/license/mashape/apistatus.svg https://img.shields.io/badge/code%20style-black-000000.svg

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

stdio-mgr-1.0.1.tar.gz (7.2 kB view details)

Uploaded Source

Built Distribution

stdio_mgr-1.0.1-py3-none-any.whl (7.4 kB view details)

Uploaded Python 3

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

Hashes for stdio-mgr-1.0.1.tar.gz
Algorithm Hash digest
SHA256 781c3b51632a5e098ecad316e1fa64959ae540e1d66d8ea8a9db9c9b7b9f4186
MD5 027b7e83918676ce44698883cab3d37c
BLAKE2b-256 dce25a1e907d5ecdcadaca69663d50426a19e513dc1cdbaefbfab9e6212009b4

See more details on using hashes here.

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

Hashes for stdio_mgr-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 c8e6c9568709560dfc3e57fa322fe6d72c505ac7e666b12f22aea1589006da95
MD5 81625e1bbacb2b0e4016330f93838f40
BLAKE2b-256 f5495a7e6b42fb3b2bca6cc3dedc6e935f224bf0e4ac9fdd1e368d16d540fa7f

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page