Show More
@@ -391,85 +391,6 b' class PrefilterTransformer(Configurable):' | |||||
391 | self.__class__.__name__, self.priority, self.enabled) |
|
391 | self.__class__.__name__, self.priority, self.enabled) | |
392 |
|
392 | |||
393 |
|
393 | |||
394 | _assign_system_re = re.compile(r'(?P<lhs>(\s*)([\w\.]+)((\s*,\s*[\w\.]+)*))' |
|
|||
395 | r'\s*=\s*!(?P<cmd>.*)') |
|
|||
396 |
|
||||
397 |
|
||||
398 | class AssignSystemTransformer(PrefilterTransformer): |
|
|||
399 | """Handle the `files = !ls` syntax.""" |
|
|||
400 |
|
||||
401 | priority = Integer(100, config=True) |
|
|||
402 |
|
||||
403 | def transform(self, line, continue_prompt): |
|
|||
404 | m = _assign_system_re.match(line) |
|
|||
405 | if m is not None: |
|
|||
406 | cmd = m.group('cmd') |
|
|||
407 | lhs = m.group('lhs') |
|
|||
408 | expr = "sc =%s" % cmd |
|
|||
409 | new_line = '%s = get_ipython().magic(%r)' % (lhs, expr) |
|
|||
410 | return new_line |
|
|||
411 | return line |
|
|||
412 |
|
||||
413 |
|
||||
414 | _assign_magic_re = re.compile(r'(?P<lhs>(\s*)([\w\.]+)((\s*,\s*[\w\.]+)*))' |
|
|||
415 | r'\s*=\s*%(?P<cmd>.*)') |
|
|||
416 |
|
||||
417 | class AssignMagicTransformer(PrefilterTransformer): |
|
|||
418 | """Handle the `a = %who` syntax.""" |
|
|||
419 |
|
||||
420 | priority = Integer(200, config=True) |
|
|||
421 |
|
||||
422 | def transform(self, line, continue_prompt): |
|
|||
423 | m = _assign_magic_re.match(line) |
|
|||
424 | if m is not None: |
|
|||
425 | cmd = m.group('cmd') |
|
|||
426 | lhs = m.group('lhs') |
|
|||
427 | new_line = '%s = get_ipython().magic(%r)' % (lhs, cmd) |
|
|||
428 | return new_line |
|
|||
429 | return line |
|
|||
430 |
|
||||
431 |
|
||||
432 | _classic_prompt_re = re.compile(r'(^[ \t]*>>> |^[ \t]*\.\.\. )') |
|
|||
433 |
|
||||
434 | class PyPromptTransformer(PrefilterTransformer): |
|
|||
435 | """Handle inputs that start with '>>> ' syntax.""" |
|
|||
436 |
|
||||
437 | priority = Integer(50, config=True) |
|
|||
438 |
|
||||
439 | def transform(self, line, continue_prompt): |
|
|||
440 |
|
||||
441 | if not line or line.isspace() or line.strip() == '...': |
|
|||
442 | # This allows us to recognize multiple input prompts separated by |
|
|||
443 | # blank lines and pasted in a single chunk, very common when |
|
|||
444 | # pasting doctests or long tutorial passages. |
|
|||
445 | return '' |
|
|||
446 | m = _classic_prompt_re.match(line) |
|
|||
447 | if m: |
|
|||
448 | return line[len(m.group(0)):] |
|
|||
449 | else: |
|
|||
450 | return line |
|
|||
451 |
|
||||
452 |
|
||||
453 | _ipy_prompt_re = re.compile(r'(^[ \t]*In \[\d+\]: |^[ \t]*\ \ \ \.\.\.+: )') |
|
|||
454 |
|
||||
455 | class IPyPromptTransformer(PrefilterTransformer): |
|
|||
456 | """Handle inputs that start classic IPython prompt syntax.""" |
|
|||
457 |
|
||||
458 | priority = Integer(50, config=True) |
|
|||
459 |
|
||||
460 | def transform(self, line, continue_prompt): |
|
|||
461 |
|
||||
462 | if not line or line.isspace() or line.strip() == '...': |
|
|||
463 | # This allows us to recognize multiple input prompts separated by |
|
|||
464 | # blank lines and pasted in a single chunk, very common when |
|
|||
465 | # pasting doctests or long tutorial passages. |
|
|||
466 | return '' |
|
|||
467 | m = _ipy_prompt_re.match(line) |
|
|||
468 | if m: |
|
|||
469 | return line[len(m.group(0)):] |
|
|||
470 | else: |
|
|||
471 | return line |
|
|||
472 |
|
||||
473 | #----------------------------------------------------------------------------- |
|
394 | #----------------------------------------------------------------------------- | |
474 | # Prefilter checkers |
|
395 | # Prefilter checkers | |
475 | #----------------------------------------------------------------------------- |
|
396 | #----------------------------------------------------------------------------- | |
@@ -511,15 +432,6 b' class EmacsChecker(PrefilterChecker):' | |||||
511 | return None |
|
432 | return None | |
512 |
|
433 | |||
513 |
|
434 | |||
514 | class ShellEscapeChecker(PrefilterChecker): |
|
|||
515 |
|
||||
516 | priority = Integer(200, config=True) |
|
|||
517 |
|
||||
518 | def check(self, line_info): |
|
|||
519 | if line_info.line.lstrip().startswith(ESC_SHELL): |
|
|||
520 | return self.prefilter_manager.get_handler_by_name('shell') |
|
|||
521 |
|
||||
522 |
|
||||
523 | class MacroChecker(PrefilterChecker): |
|
435 | class MacroChecker(PrefilterChecker): | |
524 |
|
436 | |||
525 | priority = Integer(250, config=True) |
|
437 | priority = Integer(250, config=True) | |
@@ -546,43 +458,6 b' class IPyAutocallChecker(PrefilterChecker):' | |||||
546 | return None |
|
458 | return None | |
547 |
|
459 | |||
548 |
|
460 | |||
549 | class MultiLineMagicChecker(PrefilterChecker): |
|
|||
550 |
|
||||
551 | priority = Integer(400, config=True) |
|
|||
552 |
|
||||
553 | def check(self, line_info): |
|
|||
554 | "Allow ! and !! in multi-line statements if multi_line_specials is on" |
|
|||
555 | # Note that this one of the only places we check the first character of |
|
|||
556 | # ifun and *not* the pre_char. Also note that the below test matches |
|
|||
557 | # both ! and !!. |
|
|||
558 | if line_info.continue_prompt \ |
|
|||
559 | and self.prefilter_manager.multi_line_specials: |
|
|||
560 | if line_info.esc == ESC_MAGIC: |
|
|||
561 | return self.prefilter_manager.get_handler_by_name('magic') |
|
|||
562 | else: |
|
|||
563 | return None |
|
|||
564 |
|
||||
565 |
|
||||
566 | class EscCharsChecker(PrefilterChecker): |
|
|||
567 |
|
||||
568 | priority = Integer(500, config=True) |
|
|||
569 |
|
||||
570 | def check(self, line_info): |
|
|||
571 | """Check for escape character and return either a handler to handle it, |
|
|||
572 | or None if there is no escape char.""" |
|
|||
573 | if line_info.line[-1] == ESC_HELP \ |
|
|||
574 | and line_info.esc != ESC_SHELL \ |
|
|||
575 | and line_info.esc != ESC_SH_CAP: |
|
|||
576 | # the ? can be at the end, but *not* for either kind of shell escape, |
|
|||
577 | # because a ? can be a vaild final char in a shell cmd |
|
|||
578 | return self.prefilter_manager.get_handler_by_name('help') |
|
|||
579 | else: |
|
|||
580 | if line_info.pre: |
|
|||
581 | return None |
|
|||
582 | # This returns None like it should if no handler exists |
|
|||
583 | return self.prefilter_manager.get_handler_by_esc(line_info.esc) |
|
|||
584 |
|
||||
585 |
|
||||
586 | class AssignmentChecker(PrefilterChecker): |
|
461 | class AssignmentChecker(PrefilterChecker): | |
587 |
|
462 | |||
588 | priority = Integer(600, config=True) |
|
463 | priority = Integer(600, config=True) | |
@@ -742,33 +617,6 b' class AliasHandler(PrefilterHandler):' | |||||
742 | return line_out |
|
617 | return line_out | |
743 |
|
618 | |||
744 |
|
619 | |||
745 | class ShellEscapeHandler(PrefilterHandler): |
|
|||
746 |
|
||||
747 | handler_name = Unicode('shell') |
|
|||
748 | esc_strings = List([ESC_SHELL, ESC_SH_CAP]) |
|
|||
749 |
|
||||
750 | def handle(self, line_info): |
|
|||
751 | """Execute the line in a shell, empty return value""" |
|
|||
752 | magic_handler = self.prefilter_manager.get_handler_by_name('magic') |
|
|||
753 |
|
||||
754 | line = line_info.line |
|
|||
755 | if line.lstrip().startswith(ESC_SH_CAP): |
|
|||
756 | # rewrite LineInfo's line, ifun and the_rest to properly hold the |
|
|||
757 | # call to %sx and the actual command to be executed, so |
|
|||
758 | # handle_magic can work correctly. Note that this works even if |
|
|||
759 | # the line is indented, so it handles multi_line_specials |
|
|||
760 | # properly. |
|
|||
761 | new_rest = line.lstrip()[2:] |
|
|||
762 | line_info.line = '%ssx %s' % (ESC_MAGIC, new_rest) |
|
|||
763 | line_info.ifun = 'sx' |
|
|||
764 | line_info.the_rest = new_rest |
|
|||
765 | return magic_handler.handle(line_info) |
|
|||
766 | else: |
|
|||
767 | cmd = line.lstrip().lstrip(ESC_SHELL) |
|
|||
768 | line_out = '%sget_ipython().system(%r)' % (line_info.pre_whitespace, cmd) |
|
|||
769 | return line_out |
|
|||
770 |
|
||||
771 |
|
||||
772 | class MacroHandler(PrefilterHandler): |
|
620 | class MacroHandler(PrefilterHandler): | |
773 | handler_name = Unicode("macro") |
|
621 | handler_name = Unicode("macro") | |
774 |
|
622 | |||
@@ -865,44 +713,6 b' class AutoHandler(PrefilterHandler):' | |||||
865 | return newcmd |
|
713 | return newcmd | |
866 |
|
714 | |||
867 |
|
715 | |||
868 | class HelpHandler(PrefilterHandler): |
|
|||
869 |
|
||||
870 | handler_name = Unicode('help') |
|
|||
871 | esc_strings = List([ESC_HELP]) |
|
|||
872 |
|
||||
873 | def handle(self, line_info): |
|
|||
874 | """Try to get some help for the object. |
|
|||
875 |
|
||||
876 | obj? or ?obj -> basic information. |
|
|||
877 | obj?? or ??obj -> more details. |
|
|||
878 | """ |
|
|||
879 | normal_handler = self.prefilter_manager.get_handler_by_name('normal') |
|
|||
880 | line = line_info.line |
|
|||
881 | # We need to make sure that we don't process lines which would be |
|
|||
882 | # otherwise valid python, such as "x=1 # what?" |
|
|||
883 | try: |
|
|||
884 | codeop.compile_command(line) |
|
|||
885 | except SyntaxError: |
|
|||
886 | # We should only handle as help stuff which is NOT valid syntax |
|
|||
887 | if line[0]==ESC_HELP: |
|
|||
888 | line = line[1:] |
|
|||
889 | elif line[-1]==ESC_HELP: |
|
|||
890 | line = line[:-1] |
|
|||
891 | if line: |
|
|||
892 | #print 'line:<%r>' % line # dbg |
|
|||
893 | self.shell.magic('pinfo %s' % line_info.ifun) |
|
|||
894 | else: |
|
|||
895 | self.shell.show_usage() |
|
|||
896 | return '' # Empty string is needed here! |
|
|||
897 | except: |
|
|||
898 | raise |
|
|||
899 | # Pass any other exceptions through to the normal handler |
|
|||
900 | return normal_handler.handle(line_info) |
|
|||
901 | else: |
|
|||
902 | # If the code compiles ok, we should handle it normally |
|
|||
903 | return normal_handler.handle(line_info) |
|
|||
904 |
|
||||
905 |
|
||||
906 | class EmacsHandler(PrefilterHandler): |
|
716 | class EmacsHandler(PrefilterHandler): | |
907 |
|
717 | |||
908 | handler_name = Unicode('emacs') |
|
718 | handler_name = Unicode('emacs') | |
@@ -924,19 +734,12 b' class EmacsHandler(PrefilterHandler):' | |||||
924 |
|
734 | |||
925 |
|
735 | |||
926 | _default_transformers = [ |
|
736 | _default_transformers = [ | |
927 | AssignSystemTransformer, |
|
|||
928 | AssignMagicTransformer, |
|
|||
929 | PyPromptTransformer, |
|
|||
930 | IPyPromptTransformer, |
|
|||
931 | ] |
|
737 | ] | |
932 |
|
738 | |||
933 | _default_checkers = [ |
|
739 | _default_checkers = [ | |
934 | EmacsChecker, |
|
740 | EmacsChecker, | |
935 | ShellEscapeChecker, |
|
|||
936 | MacroChecker, |
|
741 | MacroChecker, | |
937 | IPyAutocallChecker, |
|
742 | IPyAutocallChecker, | |
938 | MultiLineMagicChecker, |
|
|||
939 | EscCharsChecker, |
|
|||
940 | AssignmentChecker, |
|
743 | AssignmentChecker, | |
941 | AutoMagicChecker, |
|
744 | AutoMagicChecker, | |
942 | AliasChecker, |
|
745 | AliasChecker, | |
@@ -947,10 +750,8 b' _default_checkers = [' | |||||
947 | _default_handlers = [ |
|
750 | _default_handlers = [ | |
948 | PrefilterHandler, |
|
751 | PrefilterHandler, | |
949 | AliasHandler, |
|
752 | AliasHandler, | |
950 | ShellEscapeHandler, |
|
|||
951 | MacroHandler, |
|
753 | MacroHandler, | |
952 | MagicHandler, |
|
754 | MagicHandler, | |
953 | AutoHandler, |
|
755 | AutoHandler, | |
954 | HelpHandler, |
|
|||
955 | EmacsHandler |
|
756 | EmacsHandler | |
956 | ] |
|
757 | ] |
@@ -75,49 +75,8 b' def test_handlers():' | |||||
75 | # line. |
|
75 | # line. | |
76 | run([(i,py3compat.u_format(o)) for i,o in \ |
|
76 | run([(i,py3compat.u_format(o)) for i,o in \ | |
77 | [('"no change"', '"no change"'), # normal |
|
77 | [('"no change"', '"no change"'), # normal | |
78 | (u"!true", "get_ipython().system({u}'true')"), # shell_escapes |
|
|||
79 | (u"!! true", "get_ipython().magic({u}'sx true')"), # shell_escapes + magic |
|
|||
80 | (u"!!true", "get_ipython().magic({u}'sx true')"), # shell_escapes + magic |
|
|||
81 | (u"%lsmagic", "get_ipython().magic({u}'lsmagic ')"), # magic |
|
|||
82 | (u"lsmagic", "get_ipython().magic({u}'lsmagic ')"), # magic |
|
78 | (u"lsmagic", "get_ipython().magic({u}'lsmagic ')"), # magic | |
83 | #("a = b # PYTHON-MODE", '_i'), # emacs -- avoids _in cache |
|
79 | #("a = b # PYTHON-MODE", '_i'), # emacs -- avoids _in cache | |
84 |
|
||||
85 | # post-esc-char whitespace goes inside |
|
|||
86 | (u"! true", "get_ipython().system({u}' true')"), |
|
|||
87 |
|
||||
88 | # handle_help |
|
|||
89 |
|
||||
90 | # These are weak tests -- just looking at what the help handlers |
|
|||
91 | # logs, which is not how it really does its work. But it still |
|
|||
92 | # lets us check the key paths through the handler. |
|
|||
93 |
|
||||
94 | ("x=1 # what?", "x=1 # what?"), # no help if valid python |
|
|||
95 | ]]) |
|
|||
96 |
|
||||
97 | # multi_line_specials |
|
|||
98 | ip.prefilter_manager.multi_line_specials = False |
|
|||
99 | # W/ multi_line_specials off, leading ws kills esc chars/autoexpansion |
|
|||
100 | run([ |
|
|||
101 | (u'if 1:\n !true', u'if 1:\n !true'), |
|
|||
102 | (u'if 1:\n lsmagic', u'if 1:\n lsmagic'), |
|
|||
103 | (u'if 1:\n an_alias', u'if 1:\n an_alias'), |
|
|||
104 | ]) |
|
|||
105 |
|
||||
106 | ip.prefilter_manager.multi_line_specials = True |
|
|||
107 | # initial indents must be preserved. |
|
|||
108 | run([(i,py3compat.u_format(o)) for i,o in \ |
|
|||
109 | [(u'if 1:\n !true', "if 1:\n get_ipython().system({u}'true')"), |
|
|||
110 | (u'if 2:\n lsmagic', "if 2:\n get_ipython().magic({u}'lsmagic ')"), |
|
|||
111 | (u'if 1:\n an_alias', "if 1:\n get_ipython().system({u}'true ')"), |
|
|||
112 | # Weird one |
|
|||
113 | (u'if 1:\n !!true', "if 1:\n get_ipython().magic({u}'sx true')"), |
|
|||
114 |
|
||||
115 | # Even with m_l_s on, autocall is off even with special chars |
|
|||
116 | ('if 1:\n /fun 1 2', 'if 1:\n /fun 1 2'), |
|
|||
117 | ('if 1:\n ;fun 1 2', 'if 1:\n ;fun 1 2'), |
|
|||
118 | ('if 1:\n ,fun 1 2', 'if 1:\n ,fun 1 2'), |
|
|||
119 | ('if 1:\n ?fun 1 2', 'if 1:\n ?fun 1 2'), |
|
|||
120 | # What about !! |
|
|||
121 | ]]) |
|
80 | ]]) | |
122 |
|
81 | |||
123 | # Objects which are instances of IPyAutocall are *always* autocalled |
|
82 | # Objects which are instances of IPyAutocall are *always* autocalled | |
@@ -133,15 +92,9 b' def test_handlers():' | |||||
133 | ('autocallable', 'autocallable()'), |
|
92 | ('autocallable', 'autocallable()'), | |
134 | # Don't add extra brackets (gh-1117) |
|
93 | # Don't add extra brackets (gh-1117) | |
135 | ('autocallable()', 'autocallable()'), |
|
94 | ('autocallable()', 'autocallable()'), | |
136 | (",list 1 2 3", 'list("1", "2", "3")'), |
|
|||
137 | (";list 1 2 3", 'list("1 2 3")'), |
|
|||
138 | ("/len range(1,4)", 'len(range(1,4))'), |
|
|||
139 | ]) |
|
95 | ]) | |
140 | ip.magic('autocall 1') |
|
96 | ip.magic('autocall 1') | |
141 | run([ |
|
97 | run([ | |
142 | (",list 1 2 3", 'list("1", "2", "3")'), |
|
|||
143 | (";list 1 2 3", 'list("1 2 3")'), |
|
|||
144 | ("/len range(1,4)", 'len(range(1,4))'), |
|
|||
145 | ('len "abc"', 'len("abc")'), |
|
98 | ('len "abc"', 'len("abc")'), | |
146 | ('len "abc";', 'len("abc");'), # ; is special -- moves out of parens |
|
99 | ('len "abc";', 'len("abc");'), # ; is special -- moves out of parens | |
147 | # Autocall is turned off if first arg is [] and the object |
|
100 | # Autocall is turned off if first arg is [] and the object | |
@@ -153,9 +106,6 b' def test_handlers():' | |||||
153 | ]) |
|
106 | ]) | |
154 | ip.magic('autocall 2') |
|
107 | ip.magic('autocall 2') | |
155 | run([ |
|
108 | run([ | |
156 | (",list 1 2 3", 'list("1", "2", "3")'), |
|
|||
157 | (";list 1 2 3", 'list("1 2 3")'), |
|
|||
158 | ("/len range(1,4)", 'len(range(1,4))'), |
|
|||
159 | ('len "abc"', 'len("abc")'), |
|
109 | ('len "abc"', 'len("abc")'), | |
160 | ('len "abc";', 'len("abc");'), |
|
110 | ('len "abc";', 'len("abc");'), | |
161 | ('len [1,2]', 'len([1,2])'), |
|
111 | ('len [1,2]', 'len([1,2])'), |
@@ -283,22 +283,18 b' def test_tb_syntaxerror():' | |||||
283 | nt.assert_equal(last_line, "SyntaxError: invalid syntax") |
|
283 | nt.assert_equal(last_line, "SyntaxError: invalid syntax") | |
284 |
|
284 | |||
285 |
|
285 | |||
286 | @py3compat.doctest_refactor_print |
|
286 | def test_time(): | |
287 | def doctest_time(): |
|
287 | ip = get_ipython() | |
288 | """ |
|
|||
289 | In [10]: %time None |
|
|||
290 | CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s |
|
|||
291 | Wall time: 0.00 s |
|
|||
292 |
|
288 | |||
293 | In [11]: def f(kmjy): |
|
289 | with tt.AssertPrints("CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s"): | |
294 | ....: %time print 2*kmjy |
|
290 | ip.run_cell("%time None") | |
295 |
|
|
291 | ||
296 | In [12]: f(3) |
|
292 | ip.run_cell("def f(kmjy):\n" | |
297 | 6 |
|
293 | " %time print (2*kmjy)") | |
298 | CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s |
|
294 | ||
299 | Wall time: 0.00 s |
|
295 | with tt.AssertPrints("CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s"): | |
300 | """ |
|
296 | with tt.AssertPrints("hihi", suppress=False): | |
301 |
|
297 | ip.run_cell("f('hi')") | ||
302 |
|
298 | |||
303 | def test_doctest_mode(): |
|
299 | def test_doctest_mode(): | |
304 | "Toggle doctest_mode twice, it should be a no-op and run without error" |
|
300 | "Toggle doctest_mode twice, it should be a no-op and run without error" |
@@ -20,17 +20,6 b' def test_prefilter():' | |||||
20 |
|
20 | |||
21 | # pairs of (raw, expected correct) input |
|
21 | # pairs of (raw, expected correct) input | |
22 | pairs = [ ('2+2','2+2'), |
|
22 | pairs = [ ('2+2','2+2'), | |
23 | ('>>> 2+2','2+2'), |
|
|||
24 | ('>>> # This is a comment\n' |
|
|||
25 | '... 2+2', |
|
|||
26 | '# This is a comment\n' |
|
|||
27 | '2+2'), |
|
|||
28 | # Some IPython input |
|
|||
29 | ('In [1]: 1', '1'), |
|
|||
30 | ('In [2]: for i in range(5):\n' |
|
|||
31 | ' ...: print i,', |
|
|||
32 | 'for i in range(5):\n' |
|
|||
33 | ' print i,'), |
|
|||
34 | ] |
|
23 | ] | |
35 |
|
24 | |||
36 | for raw, correct in pairs: |
|
25 | for raw, correct in pairs: |
@@ -47,6 +47,12 b' import nose.core' | |||||
47 | from nose.plugins import doctests, Plugin |
|
47 | from nose.plugins import doctests, Plugin | |
48 | from nose.util import anyp, getpackage, test_address, resolve_name, tolist |
|
48 | from nose.util import anyp, getpackage, test_address, resolve_name, tolist | |
49 |
|
49 | |||
|
50 | # Our own imports | |||
|
51 | ||||
|
52 | # We're temporarily using TerminalMagics.cleanup_input() until the functionality | |||
|
53 | # is moved into core. | |||
|
54 | from IPython.frontend.terminal.interactiveshell import TerminalMagics | |||
|
55 | ||||
50 | #----------------------------------------------------------------------------- |
|
56 | #----------------------------------------------------------------------------- | |
51 | # Module globals and other constants |
|
57 | # Module globals and other constants | |
52 | #----------------------------------------------------------------------------- |
|
58 | #----------------------------------------------------------------------------- | |
@@ -380,17 +386,7 b' class IPDocTestParser(doctest.DocTestParser):' | |||||
380 |
|
386 | |||
381 | def ip2py(self,source): |
|
387 | def ip2py(self,source): | |
382 | """Convert input IPython source into valid Python.""" |
|
388 | """Convert input IPython source into valid Python.""" | |
383 | out = [] |
|
389 | return TerminalMagics(_ip).cleanup_input(source) | |
384 | newline = out.append |
|
|||
385 | #print 'IPSRC:\n',source,'\n###' # dbg |
|
|||
386 | # The input source must be first stripped of all bracketing whitespace |
|
|||
387 | # and turned into lines, so it looks to the parser like regular user |
|
|||
388 | # input |
|
|||
389 | for lnum,line in enumerate(source.strip().splitlines()): |
|
|||
390 | newline(_ip.prefilter(line,lnum>0)) |
|
|||
391 | newline('') # ensure a closing newline, needed by doctest |
|
|||
392 | #print "PYSRC:", '\n'.join(out) # dbg |
|
|||
393 | return '\n'.join(out) |
|
|||
394 |
|
390 | |||
395 | def parse(self, string, name='<string>'): |
|
391 | def parse(self, string, name='<string>'): | |
396 | """ |
|
392 | """ |
General Comments 0
You need to be logged in to leave comments.
Login now