On Wed, Jul 8, 2015 at 1:33 PM, Steven D'Aprano <steve@pearwood.info> wrote:
On Wed, Jul 08, 2015 at 11:03:42AM +0200, Todd wrote:
> On Jul 8, 2015 10:02 AM, "Stephen J. Turnbull" <stephen@xemacs.org> wrote:
> >
> > Nick Coghlan writes:
> >
> >  > While I have no idea how we could implement it, I'm wondering if that
> >  > might be clearer if the error message instead looked more like this:
> >  >
> >  >     File "/home/me/myfile.py", line 11
> >  >         data = func()
> >  >         ^
> >  >     SyntaxError: invalid syntax (Unmatched '(' on line 10)
> >
> > I think I would prefer "Expected ')'".  I think that typos like
> >
> >     a = ((1, "one"),
> >          (2, "two)",
> >          (3, "three"))
> >     data = func()
> >
> > are likely to be fairly common (I make them often enough!), but I
> > don't see how you're going to get the parser to identify the line
> > containing "couple #2" as the source of the error (without a *really*
> > dubious heuristic).
>
> True, but we can definitely say it occurs on or after the first line in
> your example. So could we do something like:
>
>      File "/home/me/myfile.py", line 11
>          data = func()
>          ^
>    SyntaxError: Unmatched '(' starting somewhere after line 7
>
> That would at least allow you to narrow down where to look for the problem.

Even if you can't report a line number, you could report "on this or a
previous line".

The way I see it, if the parser knows enough to point the ^ before the
first token on the line, it can report that there is a missing ) on a
previous line, otherwise it may have to hedge.

SyntaxError: Unmatched '(' before this line

SyntaxError: Unmatched '(' on this or a previous line

I believe that this would be a big help to beginners and casual users
such as sys admins. Experienced programmers have learned the hard way
that a SyntaxError may mean an unmatched bracket of some kind, but I
think it would help even experienced coders to be explicit about the
error.


I think it should always be possible to report a range of line numbers within which the problem must occur.  The start would be the outermost unclosed parenthesis.  The end would the first statement that cannot be in a parentheses or the end of the file, whichever comes first (the latter is currently listed as the location of the exception).  Although we can't say exactly where the problem occurs in this range, I think we can say that it must be somewhere in this range.

So it should be possible to do something like this (I don't like the error message, this is just an example):

      File "/home/me/myfile.py", line 8:12
          a = ((1, "one"),
                ^
          ...
          data = func()
          ^
    SyntaxError: Unmatched '(' in line range

However, I don't know if this exception message structure could be a problem.  Hence my original proposal, which would keep a simpler exception message.