2

I followed (actually, I authored) the instructions in this gist in order to modify the ipy_repl.py file that ships with SublimeREPL in order to get it working with more recent versions of IPython at the time. However, I recently pip upgraded my IPython and Jupyter packages

pip3 install -U ipython jupyter

to the latest versions, and now I'm getting this error when trying to start an IPython session from Sublime:

Traceback (most recent call last):
  File "/home/mattdmo/.config/sublime-text-3/Packages/SublimeREPL/config/Python/ipy_repl.py", line 66, in <module>
    embedded_shell.initialize()
  File "<decorator-gen-113>", line 2, in initialize
  File "/usr/local/lib/python3.5/dist-packages/traitlets/config/application.py", line 74, in catch_config_error
    return method(app, *args, **kwargs)
  File "/usr/local/lib/python3.5/dist-packages/jupyter_console/app.py", line 137, in initialize
    self.init_shell()
  File "/usr/local/lib/python3.5/dist-packages/jupyter_console/app.py", line 110, in init_shell
    client=self.kernel_client,
  File "/usr/local/lib/python3.5/dist-packages/traitlets/config/configurable.py", line 412, in instance
    inst = cls(*args, **kwargs)
  File "/usr/local/lib/python3.5/dist-packages/jupyter_console/ptshell.py", line 252, in __init__
    self.init_prompt_toolkit_cli()
  File "/usr/local/lib/python3.5/dist-packages/jupyter_console/ptshell.py", line 404, in init_prompt_toolkit_cli
    self.pt_cli = CommandLineInterface(app, eventloop=self._eventloop)
  File "/usr/local/lib/python3.5/dist-packages/prompt_toolkit/interface.py", line 80, in __init__
    self.output = output or create_output()
  File "/usr/local/lib/python3.5/dist-packages/prompt_toolkit/shortcuts.py", line 124, in create_output
    ansi_colors_only=ansi_colors_only, term=term)
  File "/usr/local/lib/python3.5/dist-packages/prompt_toolkit/terminal/vt100_output.py", line 425, in from_pty
    assert stdout.isatty()
AssertionError

I did a little digging, and at some point after early February 2016, the prompt_toolkit module came into use in jupyter_console. While I assume this gives some advantages to the overall project, one disadvantage is that all text interfaces communicating with jupyter_console must be TTYs (a rather silly requirement, IMO), which a Sublime view is not.

I was unable to find a way around this bug feature. Does anyone know how to work around this?

MattDMo
  • 100,794
  • 21
  • 241
  • 231

3 Answers3

4

Through a fortuitous series of events, I came upon an old Win7 VM that I hadn't used in several months, and which had not been upgraded, so the IPython REPL still worked. Through a little experimentation, I found that if I downgraded ipython to version 4.1.1 and jupyter_console to 4.1.0, everything worked fine:

pip3 install -U ipython==4.1.1 jupyter_console==4.1.0

This isn't a perfect solution, as I am unable to play with the new features of IPython 5, but it's definitely preferable to staring at tracebacks all the time. I've updated my gist mentioned in the question to reflect this finding, and wanted to post this Q&A here to get the word out, but I'm still looking for a way to get IPython 5 working.

MattDMo
  • 100,794
  • 21
  • 241
  • 231
  • I'm not familiar with SublimeREPL, but we've added a `--simple-prompt` flag to IPython for users of Emacs' 'inferior shell' feature. Maybe SublimeREPL works like that as well? That disables prompt_toolkit and readline entirely. – Thomas K Aug 20 '16 at 22:24
  • @ThomasK do you know how that can be accessed programmatically? I don't know if you took a look at `ipy_repl.py` at the gist, but basically what it's doing is setting up a connection to an instance of `ZMQTerminalIPythonApp`, then using it to communicate with a kernel. Could you access the `--simple-prompt` option via a mechanism like `cfg.InteractiveShell.simple_prompt = True` or something like that? – MattDMo Aug 20 '16 at 23:31
  • @ThomasK I looked through the IPython docs, and used `cfg.TerminalInteractiveShell.simple_prompt = True`, but still got exactly the same error as in my question. We already set `os.environ['TERM'] = 'emacs'` to get the "inferior-shell" behavior, so I'm not sure what else to do. – MattDMo Aug 20 '16 at 23:50
  • The traceback you show is from `jupyter_console`, not IPython. Is there a reason you need to use that? We should add a similar option to jupyter_console, but we haven't yet. – Thomas K Aug 21 '16 at 11:57
  • @ThomasK `jupyter_console.app` contains `ZMQIPythonTerminalApp`, which is the basis of the whole connection system. It was moved out of `IPython.terminal.console.app` starting with IPython 4. – MattDMo Aug 21 '16 at 12:41
  • But is there a reason you need a Jupyter connection rather than running the `ipython` interface directly? – Thomas K Aug 23 '16 at 06:48
  • @ThomasK no particular reason, other than that's the interface that's already been used. The point is we're trying to run IPython *inside* of the text editor, just like emacs does (sort of). Yes, I could just use a Jupyter Notebook in my browser and be done with it, but the editor connection is useful because one can transfer code from the editor to IPython for testing. – MattDMo Aug 23 '16 at 12:33
  • I don't mean the notebook interface. `ipython` is a terminal interface that runs Python code inside the process. `jupyter console` is a very similar terminal interface that talks to a Jupyter kernel to run code in that kernel's language. If you only want to run Python code, `ipython` tends to be more actively developed, so you're better off using that. – Thomas K Aug 24 '16 at 15:30
  • @ThomasK that sounds promising. If you could point me to relevant parts of the API I could use to rewrite the `ipy_repl.py` file I linked to earlier, I'd be quite thankful. Feel free to write up an answer describing it with some detail. – MattDMo Aug 24 '16 at 16:14
  • I'm a bit unsure of what API SublimeREPL expects, but you probably want to instantiate an IPython `InteractiveShell` object. Have a look at the `do_execute` and `do_complete` methods in [ipykernel.ipkernel](https://github.com/ipython/ipykernel/blob/master/ipykernel/ipkernel.py). – Thomas K Aug 26 '16 at 07:27
3

I have modified your gist so it works with the most recent version of Jupyter/IPython 6.1.0.

You only need to insert the additional config
cfg.ZMQTerminalInteractiveShell.simple_prompt = True
somewhere between line 38 and 41.

The hack at line 68 - 73
if os.name == "nt":
is not necessary for me on Win 7/10. It only displays the banner twice if you don't comment it out.

The mandatory use of the simple-prompt option gives only limited shell functionality (e.g. no multi-line entry).
There is the option to use the IPython shell by using IPython.terminal.ipapp.TerminalIPythonApp instead of jupyter_console.app.ZMQTerminalIPythonApp. There, however, you lose the GUI event loop integration (i.e. the %gui magic).

Also, I couldn't figure out how to properly exit the Jupyter shell when closing the shell window in Sublime Text. Without issuing a quit command first, the connection file of the jupyter kernel is not deleted - who knows what else keeps running...

Pybe
  • 133
  • 8
0

I encount the same and I solved it, I also answered this problem here.

There are 2 ways to make it, win10, conda python3.6.7, Ipython7.1.1, Sublime 3.1.1

1.Open \Packages\SublimeREPL\config\Python\Main.sublime-menu, find the line

"windows": ["python", "-u", "${packages}/SublimeREPL/config/Python/ipy_repl.py"]

and change it to where your ipython.exe located, for me is

"windows": ["C:\Python\envs\py37\Scripts\ipython.exe"]

2.Just modified \Packages\SublimeREPL\config\Python\ipy_repl.py to 3 lines,

import os
# change dir to path_to_ipython.exe
os.chdir(r'C:\Python\envs\py37\Scripts')
os.system('ipython')

I prefer the second one, if you encount problems with first way, such as your shortcut about sublimeREPL not work (happens to me:(), try second one.

Animeta
  • 1,241
  • 3
  • 16
  • 30