Show More
@@ -480,7 +480,7 b' class IPythonInputSplitter(InputSplitter):' | |||||
480 | # List with lines of raw input accumulated so far. |
|
480 | # List with lines of raw input accumulated so far. | |
481 | _buffer_raw = None |
|
481 | _buffer_raw = None | |
482 |
|
482 | |||
483 | def __init__(self, physical_line_transforms=None, |
|
483 | def __init__(self, line_input_checker=False, physical_line_transforms=None, | |
484 | logical_line_transforms=None, python_line_transforms=None): |
|
484 | logical_line_transforms=None, python_line_transforms=None): | |
485 | super(IPythonInputSplitter, self).__init__() |
|
485 | super(IPythonInputSplitter, self).__init__() | |
486 | self._buffer_raw = [] |
|
486 | self._buffer_raw = [] | |
@@ -498,7 +498,7 b' class IPythonInputSplitter(InputSplitter):' | |||||
498 | if logical_line_transforms is not None: |
|
498 | if logical_line_transforms is not None: | |
499 | self.logical_line_transforms = logical_line_transforms |
|
499 | self.logical_line_transforms = logical_line_transforms | |
500 | else: |
|
500 | else: | |
501 | self.logical_line_transforms = [cellmagic(), |
|
501 | self.logical_line_transforms = [cellmagic(end_on_blank_line=line_input_checker), | |
502 | help_end(), |
|
502 | help_end(), | |
503 | escaped_commands(), |
|
503 | escaped_commands(), | |
504 | assign_from_magic(), |
|
504 | assign_from_magic(), |
@@ -60,8 +60,8 b' class InputTransformer(object):' | |||||
60 | will allow instantiation with the decorated object. |
|
60 | will allow instantiation with the decorated object. | |
61 | """ |
|
61 | """ | |
62 | @functools.wraps(func) |
|
62 | @functools.wraps(func) | |
63 | def transformer_factory(): |
|
63 | def transformer_factory(**kwargs): | |
64 | return cls(func) |
|
64 | return cls(func, **kwargs) | |
65 |
|
65 | |||
66 | return transformer_factory |
|
66 | return transformer_factory | |
67 |
|
67 | |||
@@ -84,9 +84,9 b' class StatelessInputTransformer(InputTransformer):' | |||||
84 |
|
84 | |||
85 | class CoroutineInputTransformer(InputTransformer): |
|
85 | class CoroutineInputTransformer(InputTransformer): | |
86 | """Wrapper for an input transformer implemented as a coroutine.""" |
|
86 | """Wrapper for an input transformer implemented as a coroutine.""" | |
87 | def __init__(self, coro): |
|
87 | def __init__(self, coro, **kwargs): | |
88 | # Prime it |
|
88 | # Prime it | |
89 | self.coro = coro() |
|
89 | self.coro = coro(**kwargs) | |
90 | next(self.coro) |
|
90 | next(self.coro) | |
91 |
|
91 | |||
92 | def __repr__(self): |
|
92 | def __repr__(self): | |
@@ -316,7 +316,7 b' def help_end(line):' | |||||
316 |
|
316 | |||
317 |
|
317 | |||
318 | @CoroutineInputTransformer.wrap |
|
318 | @CoroutineInputTransformer.wrap | |
319 | def cellmagic(): |
|
319 | def cellmagic(end_on_blank_line=False): | |
320 | """Captures & transforms cell magics. |
|
320 | """Captures & transforms cell magics. | |
321 |
|
321 | |||
322 | After a cell magic is started, this stores up any lines it gets until it is |
|
322 | After a cell magic is started, this stores up any lines it gets until it is | |
@@ -337,7 +337,8 b' def cellmagic():' | |||||
337 | first = line |
|
337 | first = line | |
338 | body = [] |
|
338 | body = [] | |
339 | line = (yield None) |
|
339 | line = (yield None) | |
340 |
while (line is not None) and |
|
340 | while (line is not None) and \ | |
|
341 | ((line.strip() != '') or not end_on_blank_line): | |||
341 | body.append(line) |
|
342 | body.append(line) | |
342 | line = (yield None) |
|
343 | line = (yield None) | |
343 |
|
344 |
@@ -538,39 +538,35 b' class CellMagicsCommon(object):' | |||||
538 | out = sp.source_reset() |
|
538 | out = sp.source_reset() | |
539 | ref = u"get_ipython().run_cell_magic({u}'cellm', {u}'line', {u}'body')\n" |
|
539 | ref = u"get_ipython().run_cell_magic({u}'cellm', {u}'line', {u}'body')\n" | |
540 | nt.assert_equal(out, py3compat.u_format(ref)) |
|
540 | nt.assert_equal(out, py3compat.u_format(ref)) | |
|
541 | ||||
|
542 | def test_cellmagic_help(self): | |||
|
543 | self.sp.push('%%cellm?') | |||
|
544 | nt.assert_false(self.sp.push_accepts_more()) | |||
541 |
|
545 | |||
542 | def tearDown(self): |
|
546 | def tearDown(self): | |
543 | self.sp.reset() |
|
547 | self.sp.reset() | |
544 |
|
548 | |||
545 |
|
549 | |||
546 | class CellModeCellMagics(CellMagicsCommon, unittest.TestCase): |
|
550 | class CellModeCellMagics(CellMagicsCommon, unittest.TestCase): | |
547 |
sp = isp.IPythonInputSplitter(input_ |
|
551 | sp = isp.IPythonInputSplitter(line_input_checker=False) | |
548 |
|
552 | |||
549 | def test_incremental(self): |
|
553 | def test_incremental(self): | |
550 | sp = self.sp |
|
554 | sp = self.sp | |
551 |
s |
|
555 | sp.push('%%cellm firstline\n') | |
552 | sp.push(src) |
|
|||
553 | nt.assert_true(sp.push_accepts_more()) #1 |
|
556 | nt.assert_true(sp.push_accepts_more()) #1 | |
554 | src += '\n' |
|
557 | sp.push('line2\n') | |
555 | sp.push(src) |
|
558 | nt.assert_true(sp.push_accepts_more()) #2 | |
556 | # Note: if we ever change the logic to allow full blank lines (see |
|
559 | sp.push('\n') | |
557 | # _handle_cell_magic), then the following test should change to true |
|
560 | # This should accept a blank line and carry on until the cell is reset | |
558 |
nt.assert_ |
|
561 | nt.assert_true(sp.push_accepts_more()) #3 | |
559 | # By now, even with full blanks allowed, a second blank should signal |
|
|||
560 | # the end. For now this test is only a redundancy safety, but don't |
|
|||
561 | # delete it in case we change our mind and the previous one goes to |
|
|||
562 | # true. |
|
|||
563 | src += '\n' |
|
|||
564 | sp.push(src) |
|
|||
565 | nt.assert_false(sp.push_accepts_more()) #3 |
|
|||
566 |
|
||||
567 |
|
562 | |||
568 | class LineModeCellMagics(CellMagicsCommon, unittest.TestCase): |
|
563 | class LineModeCellMagics(CellMagicsCommon, unittest.TestCase): | |
569 |
sp = isp.IPythonInputSplitter(input_ |
|
564 | sp = isp.IPythonInputSplitter(line_input_checker=True) | |
570 |
|
565 | |||
571 | def test_incremental(self): |
|
566 | def test_incremental(self): | |
572 | sp = self.sp |
|
567 | sp = self.sp | |
573 | sp.push('%%cellm line2\n') |
|
568 | sp.push('%%cellm line2\n') | |
574 | nt.assert_true(sp.push_accepts_more()) #1 |
|
569 | nt.assert_true(sp.push_accepts_more()) #1 | |
575 | sp.push('\n') |
|
570 | sp.push('\n') | |
|
571 | # In this case, a blank line should end the cell magic | |||
576 | nt.assert_false(sp.push_accepts_more()) #2 |
|
572 | nt.assert_false(sp.push_accepts_more()) #2 |
@@ -19,9 +19,9 b' def transform_and_reset(transformer):' | |||||
19 | return transform |
|
19 | return transform | |
20 |
|
20 | |||
21 | # Transformer tests |
|
21 | # Transformer tests | |
22 | def transform_checker(tests, transformer): |
|
22 | def transform_checker(tests, transformer, **kwargs): | |
23 | """Utility to loop over test inputs""" |
|
23 | """Utility to loop over test inputs""" | |
24 | transformer = transformer() |
|
24 | transformer = transformer(**kwargs) | |
25 | try: |
|
25 | try: | |
26 | for inp, tr in tests: |
|
26 | for inp, tr in tests: | |
27 | if inp is None: |
|
27 | if inp is None: | |
@@ -223,7 +223,7 b' syntax_ml = \\' | |||||
223 | ], |
|
223 | ], | |
224 | [(u'%%bar 123', None), |
|
224 | [(u'%%bar 123', None), | |
225 | (u'hello', None), |
|
225 | (u'hello', None), | |
226 |
( |
|
226 | (None , u_fmt("get_ipython().run_cell_magic({u}'bar', {u}'123', {u}'hello')")), | |
227 | ], |
|
227 | ], | |
228 | ], |
|
228 | ], | |
229 |
|
229 | |||
@@ -348,6 +348,12 b' def test_escaped_paren():' | |||||
348 | def test_cellmagic(): |
|
348 | def test_cellmagic(): | |
349 | for example in syntax_ml['cellmagic']: |
|
349 | for example in syntax_ml['cellmagic']: | |
350 | transform_checker(example, ipt.cellmagic) |
|
350 | transform_checker(example, ipt.cellmagic) | |
|
351 | ||||
|
352 | line_example = [(u'%%bar 123', None), | |||
|
353 | (u'hello', None), | |||
|
354 | (u'' , u_fmt("get_ipython().run_cell_magic({u}'bar', {u}'123', {u}'hello')")), | |||
|
355 | ] | |||
|
356 | transform_checker(line_example, ipt.cellmagic, end_on_blank_line=True) | |||
351 |
|
357 | |||
352 | def test_has_comment(): |
|
358 | def test_has_comment(): | |
353 | tests = [('text', False), |
|
359 | tests = [('text', False), |
General Comments 0
You need to be logged in to leave comments.
Login now