gotcha / ipdb

Integration of IPython pdb
BSD 3-Clause "New" or "Revised" License
1.86k stars 147 forks source link

No auto-completion from docker trace #161

Open AdrienLemaire opened 5 years ago

AdrienLemaire commented 5 years ago

ipdb==0.11 Python 3.7.2 Docker v18.09.1 docker-compose v1.23.2

When setting an ipdb breakpoint via import ipdb; ipdb.set_trace() in a django project running in a docker environment, auto-completion doesn't work (instead, a tabulation char is written).

When adding a .pdbrc file with

import rlcompleter
import pdb
pdb.Pdb.complete = rlcompleter.Completer(locals()).complete

and changing the breakpoint call to import pdb; pdb.set_trace(), auto-completion works fine but I lose all the other ipdb niceties like syntax coloration.

Bug: ipdb autocompletion doesn't work when pdb does Reason: Unknown. All I can think is it's related to using docker. To get the shell accessible, I run the docker image as follow: docker-compose run --service-ports djangocontainer

gotcha commented 5 years ago

That sounds like a IPython issue. Have you checked if you have the same issue when accessing IPython interactive environment through docker ?

AdrienLemaire commented 5 years ago

@gotcha no problem when starting ipython directly within the docker container

ipdb also seems to work fine when set_trace is set in the django project's code, sorry about that. Debugging this a bit further, the issue seems to be specific to Behave (1.2.6) and Behave-django (1.1.0).

@wip
Feature: OGP tags
    I want to spread my love of project on social networks

    Scenario: Meta on other pages
        When I share the url "/"
        …
@when('I share the url "{url}"')
def step_impl(context, url):
    import ipdb; ipdb.set_trace()  # noqa: E702
    context.url = "{}/site{}".format(context.base_url, url)
    context.response = context.test.client.get(context.url)
    assert context.response.status_code == 200
$ docker-compose up -d
$ docker-compose rm -sf backend;
$ docker-compose run --service-ports --name backend backend
$ docker exec -ti backend ./manage.py behave --wip

Whenever I execute behave with the --wip or -w arguments

$ ./manage.py behave --help
  …
  -w, --wip             Only run scenarios tagged with "wip". Additionally:
                        use the "plain" formatter, do not capture stdout or
                        logging output and stop at the first failure.

, when I arrive on an ipdb shell, any press on the key will return a tabulation space instead of either autocompleting or showing the completion tooltip.

@jenisys @bittner might you have any idea regarding the loss of ipdb tabulation feature in a behave step breakpoint ?

stdedos commented 5 years ago

I have a somewhat related problem: Running Robot Framework tests inside an Alpine Docker Container.

I was able to get my completion to somewhat work with

ipdb$ (master *+ u=) git --no-pager diff
diff --git a/ipdb/__main__.py b/ipdb/__main__.py
index 4af88b3..43aaf7e 100644
--- a/ipdb/__main__.py
+++ b/ipdb/__main__.py
@@ -42,11 +42,11 @@ else:
 # This is especially important for tools that fiddle with stdout
 debugger_cls = shell.debugger_cls

-def _init_pdb(context=3, commands=[]):
+def _init_pdb(context=3, commands=[], **kwargs):
     try:
-        p = debugger_cls(context=context)
+        p = debugger_cls(context=context, **kwargs)
     except TypeError:
-        p = debugger_cls()
+        p = debugger_cls(**kwargs)
     p.rcLines.extend(commands)
     return p

@@ -59,11 +59,11 @@ def wrap_sys_excepthook():
         sys.excepthook = BdbQuit_excepthook

-def set_trace(frame=None, context=3):
+def set_trace(frame=None, context=3, **kwargs):
     wrap_sys_excepthook()
     if frame is None:
         frame = sys._getframe().f_back
-    p = _init_pdb(context).set_trace(frame)
+    p = _init_pdb(context, **kwargs).set_trace(frame)
     if p and hasattr(p, 'shell'):
         p.shell.restore_sys_module_state()

diff --git a/ipdb/stdout.py b/ipdb/stdout.py
index 933aa12..051746c 100644
--- a/ipdb/stdout.py
+++ b/ipdb/stdout.py
@@ -11,11 +11,11 @@ def update_stdout():
     io.stdout = sys.stdout = sys.__stdout__

-def sset_trace(frame=None, context=3):
+def sset_trace(frame=None, context=3, **kwargs):
     update_stdout()
     if frame is None:
         frame = sys._getframe().f_back
-    set_trace(frame, context)
+    set_trace(frame, context, **kwargs)

 def spost_mortem(tb=None):

And then call ipdb.sset_trace(completekey='tab') instead. It doesn't have that fancy gray-autocomplete-box, but it works. It does not autocomplete variables in all cases.

(no problem for me as well on a "normal" ipython invocation too; all bells and whistles are fine)


I found a MWE. This works:

Both stop on:

        from util.python_repl import interactive
        interactive()

(an ipdb.sset_trace() wrapper)