Skip to main content

Context manager for mocking/wrapping stdin/stdout/stderr

Project description

stdio-mgr: Context manager for mocking/wrapping stdin/stdout/stderr

Current Development Version:

GitHub Workflow Status

Most Recent Stable Release

PyPI Version Python Versions

Info

MIT License black formatted PePY stats


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


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.1.tar.gz (13.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

stdio_mgr-1.0.1.1-py3-none-any.whl (7.9 kB view details)

Uploaded Python 3

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

Hashes for stdio_mgr-1.0.1.1.tar.gz
Algorithm Hash digest
SHA256 ed620fc4e4cd034d486a9de1c388507f913b3a1fc8e13f3a041edfc0be2eaa87
MD5 85d60f3019c8a544eaeb3794540103d6
BLAKE2b-256 ee8454060a3cc3d1c5282e18c400ae45b603c33ef92b93c0c4a77b0883451db8

See more details on using hashes here.

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

Hashes for stdio_mgr-1.0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 21699dad3ab77c443b8178ebc6c924af1945896ca1a0f922ee7927f1d156ea23
MD5 13736a20054340ca292cd1a4cbb85086
BLAKE2b-256 5384d3dfc2102409c77b43aacada751e0b23cd49c8b8d44aedce42f4fb339e9e

See more details on using hashes here.

Supported by

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