click.testing.CliRunner.invoke prevents use of pdb

Created on 9 Jun 2014  路  11Comments  路  Source: pallets/click

Here's another one (related to #136). I wanted to explore the contents of the context object passed to a command decorated with @click.pass_context.

But when I try dropping a pdb.set_trace into the invoked command, it immediately quits...but only when invoked via the CliRunner.

if I actually invoke the command from the command line, the debugger works as expected.

Maybe something to do with the handling of stdin and stdout by CliRunner.invoke?

Here's an example:

"""
(click)(master ? =)[~/projects/click]$ python click_bdb_swallow.py 
F
======================================================================
FAIL: test_noarguments (__main__.FooTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "click_bdb_swallow.py", line 21, in test_noarguments
    result = runner.invoke(foo)
AssertionError: <object object at 0x7fb7d0f9f1b0> != <Result BdbQuit()>

----------------------------------------------------------------------
Ran 1 test in 0.006s

FAILED (failures=1)
"""

import unittest

import click
from click.testing import CliRunner

@click.command()
@click.pass_context
def foo(context):
    """
    I want to drop to pdb in here so that I can explore the context object, but
    pdb just exits, maybe because of the way CliRunner.invoke changes stdin,
    stdout.
    """
    import pdb; pdb.set_trace()



class FooTests(unittest.TestCase):
    def test_noarguments(self):
        runner = CliRunner()
        result = runner.invoke(foo)
        # And again it's confusing that BdbQuit has been swallowed by invoke
        # (see https://github.com/mitsuhiko/click/issues/136)
        self.assertEqual(object(), result)



if __name__ == '__main__':
    unittest.main()

Most helpful comment

It seems like calling with catch_exceptions=False makes invoke() raise a bdb.BdbQuit exception.
Here is a gist which trigger the behaviors I'm seeing. I'm on Python 2.7.3 on Debian stable.
https://gist.github.com/anonymous/1f1ea59bac42e8ea6b2b

Could this be happening due to CliRunner.isolation() replacing sys.stdin with a StringIO(), which is empty by default. pdb then reads the empty buffer and gets a EOF ?

All 11 comments

There is a way to prevent this with Click 3.0

@mitsuhiko, could you explain how to prevent pdb from quiting when started under CliRunner.invoke ?
I have tried to provide the input argument to invoke(), and that seems to let me pass input to a running pdb, however, the output seems to get eaten by invoke().
Looking at the code, it's not clear to me how to avoid this effect when using invoke().
I'm on click 3.3.

call invoke with catch_exceptions=False

runner.invoke(loader.loader, ["-t", "rdr", fname], catch_exceptions=False)

It seems like calling with catch_exceptions=False makes invoke() raise a bdb.BdbQuit exception.
Here is a gist which trigger the behaviors I'm seeing. I'm on Python 2.7.3 on Debian stable.
https://gist.github.com/anonymous/1f1ea59bac42e8ea6b2b

Could this be happening due to CliRunner.isolation() replacing sys.stdin with a StringIO(), which is empty by default. pdb then reads the empty buffer and gets a EOF ?

+1

Click can provide lightweight method that just calls cli.main and catches SystemExit. I'm not sure why catch_exceptions is True by default. From my perspective it's better to get failed test and see default traceback.

getting this in Click 6.6 - anyone ever find a workaround? When setting catch_exceptions=False i still get dumped in

```

/usr/local/Cellar/python3/3.5.2_1/Frameworks/Python.framework/Versions/3.5/lib/python3.5/bdb.py(67)dispatch_line()
-> if self.quitting: raise BdbQuit```

also getting this on click==6.6

would love to get a solution to this, making it really hard to debug this issue i'm having

I am using rpdb until this is fixed. Not ideal but serves a need.

Hey
Name: click
Version: 6.7

Still having this issue. This occurs on python 3.5.3 i didn't observe this on python 2.7.

as well with b471d346e93b818d7c8a87d8cee9e0705435ac19 and python 3.5.2

I have provided a workaround that worked for me in #843.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

flying-sheep picture flying-sheep  路  34Comments

mbrancato picture mbrancato  路  24Comments

mahmoudimus picture mahmoudimus  路  25Comments

Diaoul picture Diaoul  路  27Comments

ivankravets picture ivankravets  路  27Comments