##// END OF EJS Templates
Handle OSError cases where traceback frames occur from built files (#13964)...
Handle OSError cases where traceback frames occur from built files (#13964) I've been using the `_render_traceback_` method of the traceback object, provided by the `IPython.core.interactiveshell.InteractiveShell` object that you created, in the `showtraceback` method. Thanks to this, I was able to create better error messages. I appreciate it. The following issue is related to the use of this method. ```python try: # Exception classes can customise their traceback - we # use this in IPython.parallel for exceptions occurring # in the engines. This should return a list of strings. if hasattr(value, "_render_traceback_"): stb = value._render_traceback_() else: stb = self.InteractiveTB.structured_traceback( etype, value, tb, tb_offset=tb_offset ) ``` I noticed that in the recent `8.11` version, code was added to generate a traceback when the source code is too long. In this case, if the `etb.tb_frame` object is a built file or something similar, the `inspect.getsourcelines(etb.tb_frame)` method may raise an error. So I implemented a change to set the `max_len` to the minimum value and avoid the following condition when an `OSError` occurs. I think this approach can handle cases where errors occur while using the `inspect.getsourcelines()` method. If there is anything I have done wrong or any procedures I should follow, please let me know. I would greatly appreciate it if you could leave a comment and I will make the necessary changes immediately. Thank you.

File last commit:

r26504:a9c5e02a
r28196:92027083 merge
Show More
editorhooks.py
127 lines | 3.9 KiB | text/x-python | PythonLexer
""" 'editor' hooks for common editors that work well with ipython
They should honor the line number argument, at least.
Contributions are *very* welcome.
"""
import os
import shlex
import subprocess
import sys
from IPython import get_ipython
from IPython.core.error import TryNext
from IPython.utils import py3compat
def install_editor(template, wait=False):
"""Installs the editor that is called by IPython for the %edit magic.
This overrides the default editor, which is generally set by your EDITOR
environment variable or is notepad (windows) or vi (linux). By supplying a
template string `run_template`, you can control how the editor is invoked
by IPython -- (e.g. the format in which it accepts command line options)
Parameters
----------
template : basestring
run_template acts as a template for how your editor is invoked by
the shell. It should contain '{filename}', which will be replaced on
invocation with the file name, and '{line}', $line by line number
(or 0) to invoke the file with.
wait : bool
If `wait` is true, wait until the user presses enter before returning,
to facilitate non-blocking editors that exit immediately after
the call.
"""
# not all editors support $line, so we'll leave out this check
# for substitution in ['$file', '$line']:
# if not substitution in run_template:
# raise ValueError(('run_template should contain %s'
# ' for string substitution. You supplied "%s"' % (substitution,
# run_template)))
def call_editor(self, filename, line=0):
if line is None:
line = 0
cmd = template.format(filename=shlex.quote(filename), line=line)
print(">", cmd)
# shlex.quote doesn't work right on Windows, but it does after splitting
if sys.platform.startswith('win'):
cmd = shlex.split(cmd)
proc = subprocess.Popen(cmd, shell=True)
if proc.wait() != 0:
raise TryNext()
if wait:
py3compat.input("Press Enter when done editing:")
get_ipython().set_hook('editor', call_editor)
get_ipython().editor = template
# in these, exe is always the path/name of the executable. Useful
# if you don't have the editor directory in your path
def komodo(exe=u'komodo'):
""" Activestate Komodo [Edit] """
install_editor(exe + u' -l {line} {filename}', wait=True)
def scite(exe=u"scite"):
""" SciTE or Sc1 """
install_editor(exe + u' {filename} -goto:{line}')
def notepadplusplus(exe=u'notepad++'):
""" Notepad++ http://notepad-plus.sourceforge.net """
install_editor(exe + u' -n{line} {filename}')
def jed(exe=u'jed'):
""" JED, the lightweight emacsish editor """
install_editor(exe + u' +{line} {filename}')
def idle(exe=u'idle'):
""" Idle, the editor bundled with python
Parameters
----------
exe : str, None
If none, should be pretty smart about finding the executable.
"""
if exe is None:
import idlelib
p = os.path.dirname(idlelib.__filename__)
# i'm not sure if this actually works. Is this idle.py script
# guaranteed to be executable?
exe = os.path.join(p, 'idle.py')
install_editor(exe + u' {filename}')
def mate(exe=u'mate'):
""" TextMate, the missing editor"""
# wait=True is not required since we're using the -w flag to mate
install_editor(exe + u' -w -l {line} {filename}')
# ##########################################
# these are untested, report any problems
# ##########################################
def emacs(exe=u'emacs'):
install_editor(exe + u' +{line} {filename}')
def gnuclient(exe=u'gnuclient'):
install_editor(exe + u' -nw +{line} {filename}')
def crimson_editor(exe=u'cedt.exe'):
install_editor(exe + u' /L:{line} {filename}')
def kate(exe=u'kate'):
install_editor(exe + u' -u -l {line} {filename}')