Skip to content

Loading…

Dedent prefix bugfix + tests: #142 #346

Merged
merged 2 commits into from

3 participants

@dwf
dwf commented

Re: issue #142, this expands the inputsplitter regex for 'dedentation' to correctly handle ignore lines such as "passes += 1", which should not dedent even though it begins with "pass". It's fine with arbitrary trailing whitespace and a few other wacky corner cases (return() is valid Python, as is return(0), same with raise(TypeError()), etc. -- these only dedent if you at least have a close paren after the open paren.)

Also adds tests for these new behaviours.

@takluyver
IPython member

Works for me. Thanks, David.

@dwf

Okay, I think I've got the hang of it. It appears you can have a period afterward and it will still work (tested in a dummy project). Sorry if anyone got flooded with email. :P

@fperez fperez merged commit 2b92905 into ipython:master
@fperez
IPython member

Thanks a lot David! Merged and pushed. Good luck with those exams :)

@dwf
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Apr 9, 2011
  1. @dwf

    New tests related to issue #142.

    dwf committed
Commits on Apr 10, 2011
  1. @dwf
Showing with 40 additions and 5 deletions.
  1. +7 −1 IPython/core/inputsplitter.py
  2. +33 −4 IPython/core/tests/test_inputsplitter.py
View
8 IPython/core/inputsplitter.py
@@ -103,7 +103,13 @@
# while developing.
# compiled regexps for autoindent management
-dedent_re = re.compile(r'^\s+raise|^\s+return|^\s+pass')
+dedent_re = re.compile('|'.join([
+ r'^\s+raise(\s.*)?$', # raise statement (+ space + other stuff, maybe)
+ r'^\s+raise\([^\)]*\).*$', # wacky raise with immediate open paren
+ r'^\s+return(\s.*)?$', # normal return (+ space + other stuff, maybe)
+ r'^\s+return\([^\)]*\).*$', # wacky return with immediate open paren
+ r'^\s+pass\s*$' # pass (optionally followed by trailing spaces)
+]))
ini_spaces_re = re.compile(r'^([ \t\r\f\v]+)')
# regexp to match pure comment lines so we don't accidentally insert 'if 1:'
View
37 IPython/core/tests/test_inputsplitter.py
@@ -192,13 +192,42 @@ def test_indent3(self):
isp.push(" x = (1+\n 2)")
self.assertEqual(isp.indent_spaces, 4)
- def test_dedent(self):
+ def test_dedent_pass(self):
isp = self.isp # shorthand
- isp.push('if 1:')
+ # should NOT cause dedent
+ isp.push('if 1:\n passes = 5')
self.assertEqual(isp.indent_spaces, 4)
- isp.push(' pass')
+ isp.push('if 1:\n pass')
self.assertEqual(isp.indent_spaces, 0)
-
+ isp.push('if 1:\n pass ')
+ self.assertEqual(isp.indent_spaces, 0)
+
+ def test_dedent_raise(self):
+ isp = self.isp # shorthand
+ # should NOT cause dedent
+ isp.push('if 1:\n raised = 4')
+ self.assertEqual(isp.indent_spaces, 4)
+ isp.push('if 1:\n raise TypeError()')
+ self.assertEqual(isp.indent_spaces, 0)
+ isp.push('if 1:\n raise')
+ self.assertEqual(isp.indent_spaces, 0)
+ isp.push('if 1:\n raise ')
+ self.assertEqual(isp.indent_spaces, 0)
+
+ def test_dedent_return(self):
+ isp = self.isp # shorthand
+ # should NOT cause dedent
+ isp.push('if 1:\n returning = 4')
+ self.assertEqual(isp.indent_spaces, 4)
+ isp.push('if 1:\n return 5 + 493')
+ self.assertEqual(isp.indent_spaces, 0)
+ isp.push('if 1:\n return')
+ self.assertEqual(isp.indent_spaces, 0)
+ isp.push('if 1:\n return ')
+ self.assertEqual(isp.indent_spaces, 0)
+ isp.push('if 1:\n return(0)')
+ self.assertEqual(isp.indent_spaces, 0)
+
def test_push(self):
isp = self.isp
self.assertTrue(isp.push('x=1'))
Something went wrong with that request. Please try again.