Backslash (\) at the end of the line behavior different from default Python #2108

Closed
asmeurer opened this Issue Jul 6, 2012 · 17 comments

2 participants

@asmeurer

Quite often, I miss the Enter/Return key and press \. In regular Python, I can enter two newlines, and the expression will be evaluated, like

>>> 1\
... 
1

But in IPython, no amount of newlines will terminate it. And if I do finally terminate it by entering a ;, the output is not printed (also different from Python).

In [1]: 1\
   ...: 
   ...: 
   ...: 
   ...: 
   ...: ;

In [2]: 
>>> 1\
... ;
1

Is this an intended feature caused by some more advanced multiline editing capabilities of IPython, or just a bug?

@fperez
IPython member

It's just a bug in how our inputsplitter handles backslash-terminated code. I'm afraid it won't be an easy one to fix, as that code is rather subtle, so don't hold your breath. But it's a valid bug, marking as such.

@asmeurer

I found the source of the error. The input splitter is checking for source.rstrip().endswith('\\') instead of just source.endswith('\\'). Note that this also causes it to treat 1 \ with an extra space at the end the same as just 1\, which also differs from regular Python (it treats that as a SyntaxError).

So my question now is, how well is that code tested? Can I trust that the fix is OK if tests pass?

@fperez
IPython member

The tests for that code are fairly robust, actually. Though obviously, if you've found a problem here, I would like any PR fixing it to also include a test that fails with the current code, so that we ensure it doesn't return afterwards.

@asmeurer

OK, I'll send one, as soon as I figure out how to add a test for this (and also as soon as I figure out how to actually run the tests :-)

By the way, as I go through the code, I'm also noticing random other things that need fixing. Should I submit these as separate PRs or are you guys OK with one grab-bag PR?

@asmeurer

Sorry, it should actually be endswith('\\\n'). I didn't realize that the source included the newline (which explains why the rstrip() was there in the first place).

@fperez
IPython member
@asmeurer

Thanks. I figured that out just as you posted it.

One last question: what's the way to make GitHub automatically close an issue? I think it's something like closes #2108 at the bottom of the commit message, but I always forget the exact format and it doesn't always work.

@fperez
IPython member

That works, 'fixes' also works, and you can use either # or gh- as the prefix.

Still, it's good practice to add which issues are fixed in the description of the PR, so that the summary messages (which are the ones that really get read when scanning development history) have direct links to the relevant bugs.

@asmeurer

OK, a question. What's the correct way to test that 1 \ (with a space at the end) produces a SyntaxError?

@asmeurer

For now I'm just going to test that it doesn't accept any more input. Let me know if I should test something more. I don't know how the exececution works in IPython, so I don't know we should actually test that it gives the SyntaxError or if that is the job of Python itself.

@asmeurer

Oh, I forgot about the semicolon thing. Is that actually a bug? It seems that the semicolon always suppresses output in IPython. I could easily see that being intended behavior anyway.

@fperez
IPython member
@asmeurer

Yes, I remember this now. I actually thought it was part of regular Python until now.

So what about the space after the line continuation SyntaxError thing?

@asmeurer asmeurer added a commit to asmeurer/ipython that referenced this issue Jul 8, 2012
@asmeurer asmeurer Line continuations now terminate after one blank line (#2108)
Previously, we had

In [1]: 1\
...:
...:
...:
...:

In other words, no amount of blank lines would terminate after a line
continuation, in contrast with regular Python:

>>> 1\
...
1

This made things really annoying when I typed \ instead of a newline--quite
easy to do since they are right next to each other on the keyboard.

Now, we have

In [1]: 1\
...:
Out[1]: 1

This also fixes another related behavioral difference between IPython.  If a
space follows a line continuation character, it should be a
SyntaxError("unexpected character after line continuation character"), even if
the line is otherwise continuable, according to regular Python (e.g., `1 \ `
or `(1 + \ `).  This now consistent between the two.

Closes #2108
9bd0c90
@fperez
IPython member

For space after \, we should conform to whatever python does. If we don't, it's a bug.

@asmeurer

Right, I figured that. I meant, how should we test it? The input splitter tests just test that the input doesn't accept any new lines, not that it gives the SyntaxError. I don't know if that's something that should be tested beyond that (and if so, where and how), or if that would just be testing Python itself.

@asmeurer

OK, PR #2110 submitted.

By the way, if anyone ever comes around looking for an easy to fix issue, your docs have a ton of build errors.

@fperez
IPython member

Great, thanks. Yup, our docs are in serious need of a solid maintenance pass. Good topic for a scipy 2012 sprint, actually...

@fperez fperez pushed a commit that closed this issue Jul 8, 2012
@asmeurer asmeurer Line continuations now terminate after one blank line (#2108)
Previously, we had

In [1]: 1\
...:
...:
...:
...:

In other words, no amount of blank lines would terminate after a line
continuation, in contrast with regular Python:

>>> 1\
...
1

This made things really annoying when I typed \ instead of a newline--quite
easy to do since they are right next to each other on the keyboard.

Now, we have

In [1]: 1\
...:
Out[1]: 1

This also fixes another related behavioral difference between IPython.  If a
space follows a line continuation character, it should be a
SyntaxError("unexpected character after line continuation character"), even if
the line is otherwise continuable, according to regular Python (e.g., `1 \ `
or `(1 + \ `).  This now consistent between the two.

Closes #2108
9bd0c90
@fperez fperez closed this in 9bd0c90 Jul 8, 2012
@mattvonrocketstein mattvonrocketstein pushed a commit to mattvonrocketstein/ipython that referenced this issue Nov 3, 2014
@asmeurer asmeurer Line continuations now terminate after one blank line (#2108)
Previously, we had

In [1]: 1\
...:
...:
...:
...:

In other words, no amount of blank lines would terminate after a line
continuation, in contrast with regular Python:

>>> 1\
...
1

This made things really annoying when I typed \ instead of a newline--quite
easy to do since they are right next to each other on the keyboard.

Now, we have

In [1]: 1\
...:
Out[1]: 1

This also fixes another related behavioral difference between IPython.  If a
space follows a line continuation character, it should be a
SyntaxError("unexpected character after line continuation character"), even if
the line is otherwise continuable, according to regular Python (e.g., `1 \ `
or `(1 + \ `).  This now consistent between the two.

Closes #2108
0dc6902
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment