##// END OF EJS Templates
Merge pull request #12860 from MrMino/bail_sunken_parentheses...
Matthias Bussonnier -
r26389:e8c35542 merge
parent child Browse files
Show More
@@ -0,0 +1,7 b''
1 Don't start a multiline cell with sunken parenthesis
2 ----------------------------------------------------
3
4 From now on IPython will not ask for the next line of input when given a single
5 line with more closing than opening brackets. For example, this means that if
6 you (mis)type ']]' instead of '[]', a ``SyntaxError`` will show up, instead of
7 the ``...:`` prompt continuation.
@@ -508,6 +508,20 b' def make_tokens_by_line(lines:List[str]):'
508
508
509 return tokens_by_line
509 return tokens_by_line
510
510
511
512 def has_sunken_brackets(tokens: List[tokenize.TokenInfo]):
513 """Check if the depth of brackets in the list of tokens drops below 0"""
514 parenlev = 0
515 for token in tokens:
516 if token.string in {"(", "[", "{"}:
517 parenlev += 1
518 elif token.string in {")", "]", "}"}:
519 parenlev -= 1
520 if parenlev < 0:
521 return True
522 return False
523
524
511 def show_linewise_tokens(s: str):
525 def show_linewise_tokens(s: str):
512 """For investigation and debugging"""
526 """For investigation and debugging"""
513 if not s.endswith('\n'):
527 if not s.endswith('\n'):
@@ -662,6 +676,15 b' class TransformerManager:'
662
676
663 tokens_by_line = make_tokens_by_line(lines)
677 tokens_by_line = make_tokens_by_line(lines)
664
678
679 # Bail if we got one line and there are more closing parentheses than
680 # the opening ones
681 if (
682 len(lines) == 1
683 and tokens_by_line
684 and has_sunken_brackets(tokens_by_line[0])
685 ):
686 return "invalid", None
687
665 if not tokens_by_line:
688 if not tokens_by_line:
666 return 'incomplete', find_last_indent(lines)
689 return 'incomplete', find_last_indent(lines)
667
690
@@ -255,18 +255,18 b' def test_find_assign_op_dedent():'
255
255
256 def test_check_complete():
256 def test_check_complete():
257 cc = ipt2.TransformerManager().check_complete
257 cc = ipt2.TransformerManager().check_complete
258 nt.assert_equal(cc("a = 1"), ('complete', None))
258 nt.assert_equal(cc("a = 1"), ("complete", None))
259 nt.assert_equal(cc("for a in range(5):"), ('incomplete', 4))
259 nt.assert_equal(cc("for a in range(5):"), ("incomplete", 4))
260 nt.assert_equal(cc("for a in range(5):\n if a > 0:"), ('incomplete', 8))
260 nt.assert_equal(cc("for a in range(5):\n if a > 0:"), ("incomplete", 8))
261 nt.assert_equal(cc("raise = 2"), ('invalid', None))
261 nt.assert_equal(cc("raise = 2"), ("invalid", None))
262 nt.assert_equal(cc("a = [1,\n2,"), ('incomplete', 0))
262 nt.assert_equal(cc("a = [1,\n2,"), ("incomplete", 0))
263 nt.assert_equal(cc(")"), ('incomplete', 0))
263 nt.assert_equal(cc("(\n))"), ("incomplete", 0))
264 nt.assert_equal(cc("\\\r\n"), ('incomplete', 0))
264 nt.assert_equal(cc("\\\r\n"), ("incomplete", 0))
265 nt.assert_equal(cc("a = '''\n hi"), ('incomplete', 3))
265 nt.assert_equal(cc("a = '''\n hi"), ("incomplete", 3))
266 nt.assert_equal(cc("def a():\n x=1\n global x"), ('invalid', None))
266 nt.assert_equal(cc("def a():\n x=1\n global x"), ("invalid", None))
267 nt.assert_equal(cc("a \\ "), ('invalid', None)) # Nothing allowed after backslash
267 nt.assert_equal(cc("a \\ "), ("invalid", None)) # Nothing allowed after backslash
268 nt.assert_equal(cc("1\\\n+2"), ('complete', None))
268 nt.assert_equal(cc("1\\\n+2"), ("complete", None))
269 nt.assert_equal(cc("exit"), ('complete', None))
269 nt.assert_equal(cc("exit"), ("complete", None))
270
270
271 example = dedent("""
271 example = dedent("""
272 if True:
272 if True:
@@ -297,6 +297,24 b' def test_check_complete_II():'
297 nt.assert_equal(cc('''def foo():\n """'''), ('incomplete', 4))
297 nt.assert_equal(cc('''def foo():\n """'''), ('incomplete', 4))
298
298
299
299
300 def test_check_complete_invalidates_sunken_brackets():
301 """
302 Test that a single line with more closing brackets than the opening ones is
303 interpretted as invalid
304 """
305 cc = ipt2.TransformerManager().check_complete
306 nt.assert_equal(cc(")"), ("invalid", None))
307 nt.assert_equal(cc("]"), ("invalid", None))
308 nt.assert_equal(cc("}"), ("invalid", None))
309 nt.assert_equal(cc(")("), ("invalid", None))
310 nt.assert_equal(cc("]["), ("invalid", None))
311 nt.assert_equal(cc("}{"), ("invalid", None))
312 nt.assert_equal(cc("]()("), ("invalid", None))
313 nt.assert_equal(cc("())("), ("invalid", None))
314 nt.assert_equal(cc(")[]("), ("invalid", None))
315 nt.assert_equal(cc("()]("), ("invalid", None))
316
317
300 def test_null_cleanup_transformer():
318 def test_null_cleanup_transformer():
301 manager = ipt2.TransformerManager()
319 manager = ipt2.TransformerManager()
302 manager.cleanup_transforms.insert(0, null_cleanup_transformer)
320 manager.cleanup_transforms.insert(0, null_cleanup_transformer)
General Comments 0
You need to be logged in to leave comments. Login now