Skip to content

Commit

Permalink
DEV: Allow streams to not be context managers
Browse files Browse the repository at this point in the history
Many existing stdio capture and wrapper streams are only partial
implementations, most commonly missing `__enter__` and `__exit__`.
When StdioManager needs to integrate those streams into its service
it needs to suppress exceptions caused by those missing methods.
  • Loading branch information
jayvdb committed Sep 7, 2019
1 parent 1463e2e commit 0385218
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 1 deletion.
3 changes: 2 additions & 1 deletion src/stdio_mgr/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,8 @@ class _MultiCloseContextManager(StdioTuple):
def __enter__(self):
"""Enter context of all members."""
with ExitStack() as stack:
all(map(stack.enter_context, self))
# If not all items are TextIOBase, they may not have __exit__
self.suppress_all(AttributeError, stack.enter_context)

self._close_files = stack.pop_all().close

Expand Down
19 changes: 19 additions & 0 deletions tests/test_stdiomgr_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@

from stdio_mgr import stdio_mgr, StdioManager
from stdio_mgr.stdio_mgr import _Tee
from stdio_mgr.types import _MultiCloseContextManager, StdioTuple, TextIOTuple

_WARNING_ARGS_ERROR = "Please use pytest -p no:warnings or pytest --W error::Warning"

Expand Down Expand Up @@ -549,6 +550,24 @@ def test_tee_type():
assert str(err.value) == "tee must be a TextIOBase."


def test_non_closing_type():
"""Test that incorrect type doesnt raise exceptions."""
# Ensure the type used has no __exit__ or close()
assert not hasattr("", "__exit__")
assert not hasattr("", "close")

with StdioTuple(("", "", "")):
pass

with _MultiCloseContextManager(("", "", "")):
pass

with pytest.raises(AssertionError) as err:
TextIOTuple(("", "", ""))

assert str(err.value) == "iterable must contain only TextIOBase"


@pytest.mark.xfail(reason="Want to ensure 'real' warnings aren't suppressed")
def test_bare_warning(
enable_warnings_plugin, warnings_are_errors, check_warnings_plugin_enabled
Expand Down

0 comments on commit 0385218

Please sign in to comment.