Fix display of SyntaxError in Python 3 #1229

Merged
merged 6 commits into from Jan 13, 2012

3 participants

@takluyver
IPython member

Closes #1225

The code handling exceptions is quite old, and I've cleaned it up a bit. There may be more cleanup that can be done.

The current situation with exceptions:

  • String exceptions were removed in Python 2.6, so we no longer need to worry about them.
  • In Python 2.6 & 2.7, any old style class can be used as an exception.
  • New style classes used as exceptions must inherit from BaseException (on Python 3, this is therefore all exceptions)
@takluyver takluyver commented on the diff Jan 4, 2012
IPython/core/ultratb.py
@@ -548,44 +548,40 @@ def _format_exception_only(self, etype, value):
have_filedata = False
Colors = self.Colors
list = []
- try:
- stype = Colors.excName + etype.__name__ + Colors.Normal
- except AttributeError:
- stype = etype # String exceptions don't get special coloring
@takluyver
IPython member

String exceptions are illegal in Python 2.6 and above - trying to raise one gives a TypeError.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@takluyver takluyver commented on the diff Jan 4, 2012
IPython/core/ultratb.py
if value is None:
+ # Not sure if this can still happen in Python 2.6 and above
list.append( str(stype) + '\n')
else:
if etype is SyntaxError:
@takluyver
IPython member

According to the docs, a SyntaxError will always have the relevant attributes (although they may be None): http://docs.python.org/library/exceptions.html#exceptions.SyntaxError

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@fperez fperez and 1 other commented on an outdated diff Jan 5, 2012
IPython/core/ultratb.py
- s = s + ' '
- list.append('%s%s^%s\n' % (Colors.caret, s,
- Colors.Normal) )
- value = msg
- s = self._some_str(value)
+ have_filedata = True
+ #print 'filename is',filename # dbg
+ if not value.filename: value.filename = "<string>"
+ list.append('%s File %s"%s"%s, line %s%d%s\n' % \
+ (Colors.normalEm,
+ Colors.filenameEm, value.filename, Colors.normalEm,
+ Colors.linenoEm, value.lineno, Colors.Normal ))
+ if value.text is not None:
+ i = 0
+ while i < len(value.text) and value.text[i].isspace():
+ i = i+1
@fperez
IPython member
fperez added a note Jan 5, 2012

we might as well update this and other similar assignments below to be in-place i += 1. This code was originally written for Python 2.0, which didn't have in-place operators.

@takluyver
IPython member

Good point. Done.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@takluyver
IPython member

Ultratb also monkeypatches inspect.findsource(), for Python 2.5 and above, seemingly to fix a bug where codeobj.co_firstlineno can be greater than the number of lines in the file. It's not clear when that bug occurs, or whether it has since been fixed. I think it might make sense to drop the monkeypatch, and catch exceptions from findsource().

@fperez
IPython member

I'd be ok with that, go for it.

@takluyver
IPython member

I've removed the monkeypatch, but it doesn't seem we actually call that function anywhere. I don't know if anything else, such as the debugger, might call it.

@fperez
IPython member

Mmh, if the calls aren't made by us, then it may be necessary to keep the monkeypatch then. I'm just worried that it was added to protect against errors seen in the field, and we may get those back if we remove it.

It's a bummer that a while back, we added so many of these things without a corresponding test to validate the problem, so we could know whether the patch was still required. For all we know, python 2.6 or 2.7 may have fixed this issue...

Absent a place to catch the exception ourselves, I'm inclined to back off that last commit, what do you think?

@takluyver
IPython member

We could do, but I'm a bit concerned that, since we don't know exactly what caused the bug, we're left with a monkeypatch that can never be removed, while we may be missing improvements in the Python findsource() code.

What about this: I leave the modified function in the file, but comment out the line monkeypatching it into inspect, with an explanatory note. I imagine there's a few months before we release 0.13, so if no-one's seen the bug by then, it's either fixed, or a very rare occurrence. If we do see it, then we'll either put the monkeypatch back with a more detailed description, or work out a better fix.

@fperez
IPython member
@takluyver
IPython member

OK, I've done that. Note that I chopped off the previous commit, so if you've got the branch, you'll need to pull -f it.

@takluyver
IPython member

I'm seeing a problem with exception reporting in verbose mode on Python 2.7. I'll investigate it now.

@takluyver
IPython member

Found it - we were trying to read the line where the error occurred using from the .pyc file, rather than the .py file. That's been an irritation for a while.

@takluyver
IPython member

Done a bit more cleanup - in particular, simplifying the code that finds variable names from the source line.

@fperez fperez merged commit 3782b5c into ipython:master Jan 13, 2012
@fperez
IPython member

Merged, thanks!

@juliantaylor

there is a syntax error here:
byte-compiling /scratch/jtaylor/progs/localinst//lib/python2.6/site-packages/IPython/utils/pyfile.py to pyfile.pyc
SyntaxError: ('invalid syntax', ('/scratch/jtaylor/progs/localinst//lib/python2.6/site-packages/IPython/utils/pyfile.py', 14, 30, " if ext not in {'.pyc', '.pyo'}:\n"))

IPython member

Oh yes, I forgot set literals were new in 2.7. I'll make it a tuple instead.

IPython member

Fixed using GIthub's web editor!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment