Will someone please re-open #138. It's still a problem with Click 6.7. In particular, my stack trace ends with:
File "/home/rsyring/projects/agari-adm-src/agariadm/cli.py", line 64, in batch
import pdb; pdb.set_trace()
File "/usr/lib/python3.5/bdb.py", line 52, in trace_dispatch
return self.dispatch_return(frame, arg)
File "/usr/lib/python3.5/bdb.py", line 96, in dispatch_return
if self.quitting: raise BdbQuit
bdb.BdbQuit
And there is explanation about why this is happening in the related issue.
@rsyring Perhaps you've figured this out in the interim, but the workaround that I've come up for this is to mock out click.testing.make_input_stream and replace the returned value with the original sys.stdin.
For example:
import sys
from mock import patch
patcher = patch('click.testing.make_input_stream')
m_make_input_stream = patcher.start()
m_make_input_stream.return_value = sys.stdin
# ...
patcher.stop()
Please let me know if you have any more questions.
Since CliRunner overrides sys.{stdin,stdout} and pdb depends on them, it's quite expected that this doesn't just work. pytest, which also does IO redirection, monkey patches the global pdb.set_trace so that it disables IO redirection when called allowing it work even if IO redirection is enabled. But I think click generally tries to avoid affecting global state...
You can try this workaround:
import sys
import pdb
import click
from click.testing import CliRunner
stdin, stdout = sys.stdin, sys.stdout
def set_trace():
pdb.Pdb(stdin=stdin, stdout=stdout).set_trace()
@click.command()
def main():
set_trace()
if __name__ == '__main__':
runner = CliRunner()
print(runner.invoke(main))
How click should be handling this issue is left open for discussion.
This might be useful for some:
Click CliRunner with PDB working better under pytest
https://gist.github.com/rcoup/2566c92a1c47d66cfb429a6e3cb0cca2
I use this snipped and it works basically always (argsparse, click, sys.argv):
import unittest
import pytest
from thing.__main__ import cli
class TestCli(unittest.TestCase):
@pytest.fixture(autouse=True)
def capsys(self, capsys):
self.capsys = capsys
def test_cli(self):
with pytest.raises(SystemExit) as ex:
cli(["create", "--name", "test"])
self.assertEqual(ex.value.code, 0)
out, err = self.capsys.readouterr()
self.assertEqual(out, "Succesfully created test\n")
Most helpful comment
Since
CliRunneroverridessys.{stdin,stdout}and pdb depends on them, it's quite expected that this doesn't just work.pytest, which also does IO redirection, monkey patches the globalpdb.set_traceso that it disables IO redirection when called allowing it work even if IO redirection is enabled. But I thinkclickgenerally tries to avoid affecting global state...You can try this workaround:
How click should be handling this issue is left open for discussion.