Skip to content

Commit 2530c04

Browse files
Make AppSession compatible with pytest's capsys fixture + docs.
1 parent 6a58564 commit 2530c04

File tree

2 files changed

+24
-3
lines changed

2 files changed

+24
-3
lines changed

Diff for: docs/pages/advanced_topics/unit_testing.rst

+15
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,21 @@ single fixture that does it for every test. Something like this:
116116
with create_app_session(input=pipe_input, output=DummyOutput()):
117117
yield pipe_input
118118
119+
For compatibility with pytest's ``capsys`` fixture, we have to create a new
120+
:class:`~prompt_toolkit.application.current.AppSession` for every test. This
121+
can be done in an autouse fixture. Pytest replaces ``sys.stdout`` with a new
122+
object in every test that uses ``capsys`` and the following will ensure that
123+
the new :class:`~prompt_toolkit.application.current.AppSession` will each time
124+
refer to the latest output.
125+
126+
.. code:: python
127+
128+
from prompt_toolkit.application import create_app_session
129+
130+
@fixture(autouse=True, scope="function")
131+
def _pt_app_session()
132+
with create_app_session():
133+
yield
119134
120135
Type checking
121136
-------------

Diff for: src/prompt_toolkit/application/current.py

+9-3
Original file line numberDiff line numberDiff line change
@@ -147,11 +147,17 @@ def create_app_session(
147147
Like in the case of an Telnet/SSH server.
148148
"""
149149
# If no input/output is specified, fall back to the current input/output,
150-
# whatever that is.
150+
# if there was one that was set/created for the current session.
151+
# (Note that we check `_input`/`_output` and not `input`/`output`. This is
152+
# because we don't want to accidently create a new input/output objects
153+
# here and store it in the "parent" `AppSession`. Especially, when
154+
# combining pytest's `capsys` fixture and `create_app_session`, sys.stdin
155+
# and sys.stderr are patched for every test, so we don't want to leak
156+
# those outputs object across `AppSession`s.)
151157
if input is None:
152-
input = get_app_session().input
158+
input = get_app_session()._input
153159
if output is None:
154-
output = get_app_session().output
160+
output = get_app_session()._output
155161

156162
# Create new `AppSession` and activate.
157163
session = AppSession(input=input, output=output)

0 commit comments

Comments
 (0)