diff --git a/AUTHORS b/AUTHORS index 7206125c8..3a2c3b39d 100644 --- a/AUTHORS +++ b/AUTHORS @@ -31,6 +31,7 @@ Eduardo Schettino Elizaveta Shashkova Eric Hunsberger Eric Siegerman +Erik M. Bray Florian Bruhin Floris Bruynooghe Gabriel Reis diff --git a/CHANGELOG b/CHANGELOG index b0d66d976..b35aae163 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -5,6 +5,10 @@ this was a regression failing plugins combinations like pytest-pep8 + pytest-flakes +- Workaround for exception that occurs in pyreadline when using + ``--pdb`` with standard I/O capture enabled. + Thanks Erik M. Bray for the PR. + 2.8.5 ----- diff --git a/_pytest/capture.py b/_pytest/capture.py index f0fa72f46..3895a714a 100644 --- a/_pytest/capture.py +++ b/_pytest/capture.py @@ -31,6 +31,7 @@ def pytest_addoption(parser): @pytest.hookimpl(hookwrapper=True) def pytest_load_initial_conftests(early_config, parser, args): + _readline_workaround() ns = early_config.known_args_namespace pluginmanager = early_config.pluginmanager capman = CaptureManager(ns.capture) @@ -442,3 +443,30 @@ class DontReadFromInput: def close(self): pass + + +def _readline_workaround(): + """ + Ensure readline is imported so that it attaches to the correct stdio + handles on Windows. + + Pdb uses readline support where available--when not running from the Python + prompt, the readline module is not imported until running the pdb REPL. If + running py.test with the --pdb option this means the readline module is not + imported until after I/O capture has been started. + + This is a problem for pyreadline, which is often used to implement readline + support on Windows, as it does not attach to the correct handles for stdout + and/or stdin if they have been redirected by the FDCapture mechanism. This + workaround ensures that readline is imported before I/O capture is setup so + that it can attach to the actual stdin/out for the console. + + See https://github.com/pytest-dev/pytest/pull/1281 + """ + + if not sys.platform.startswith('win32'): + return + try: + import readline # noqa + except ImportError: + pass