gregsexton / ob-ipython

org-babel integration with Jupyter for evaluation of (Python by default) code blocks
739 stars 109 forks source link

Eldoc Mode causes IPython SRC blocks to hang #150

Closed tmurph closed 6 years ago

tmurph commented 6 years ago

I'm on Mac OSX with Emacs 25.3.1. ob-ipython version 20171209.634 installed from MELPA. org-plus-contrib version 20171218 installed via package.el from the Org package archive. python.el version 0.25.2 installed from MELPA Stable.

I haven't gotten everything working from a bare minimum setup, so it's possible there's something in my config causing this problem. But I don't think that's what's going on, or at least I hope not.

Issue: With global-eldoc-mode on, I open an IPython SRC block to edit, and I type the parentheses for a function call. Emacs hangs until I C-g a few times. It continues to hang on every character I type inside the parentheses. This goes away if I turn off global-eldoc-mode. It comes back if I enable eldoc-mode just in the SRC buffer.

I traced the issue to the following spot in python-shell-send-string-no-output. Emacs gets into the while loop and never leaves. I’m pretty sure accept-process-output never returns, because when I follow along in edebug it never loops back around to check python-shell-output-filter-in-progress.

   (python-shell-send-string string process)
   (while python-shell-output-filter-in-progress
     ;; `python-shell-output-filter' takes care of setting
     ;; `python-shell-output-filter-in-progress' to NIL after it
     ;; detects end of output.
     (accept-process-output process))

The string that python-shell-send-string sends to the kernel process is the value of python-eldoc-setup-code, which I have not customized from its default value (repeated here for convenience)

def __PYDOC_get_help(obj):
    try:
        import inspect
        try:
            str_type = basestring
        except NameError:
            str_type = str
        if isinstance(obj, str_type):
            obj = eval(obj, globals())
        doc = inspect.getdoc(obj)
        if not doc and callable(obj):
            target = None
            if inspect.isclass(obj) and hasattr(obj, '__init__'):
                target = obj.__init__
                objtype = 'class'
            else:
                target = obj
                objtype = 'def'
            if target:
                args = inspect.formatargspec(
                    *inspect.getargspec(target)
                )
                name = obj.__name__
                doc = '{objtype} {name}{args}'.format(
                    objtype=objtype, name=name, args=args
                )
        else:
            doc = doc.splitlines()[0]
    except:
        doc = ''
    return doc

FWIW, if I pop up the REPL buffer while editing the SRC block, I notice that the eldoc messages do appear over there after I hit C-g. I have no clue what this means, though.

Uh … help?

tmurph commented 6 years ago

It's probably worth mentioning that I don't have this problem in regular python SRC blocks. That tells me it's something to do with ob-ipython, but I can't figure out for the life of me what could be going on.

tmurph commented 6 years ago

Crap, nvm, it was my config >.<. Resolved.