##// END OF EJS Templates
Merge pull request #1019 from takluyver/repr-quotestring...
Fernando Perez -
r5356:268ecbec merge
parent child Browse files
Show More
@@ -31,7 +31,7 b' from IPython.utils.traitlets import ('
31 )
31 )
32
32
33 from IPython.config.loader import Config
33 from IPython.config.loader import Config
34
34 from IPython.utils.py3compat import PY3
35
35
36 #-----------------------------------------------------------------------------
36 #-----------------------------------------------------------------------------
37 # Test cases
37 # Test cases
@@ -62,6 +62,11 b' mc_help_inst=u"""MyConfigurable options'
62 Current: 4.0
62 Current: 4.0
63 The integer b."""
63 The integer b."""
64
64
65 # On Python 3, the Integer trait is a synonym for Int
66 if PY3:
67 mc_help = mc_help.replace(u"<Integer>", u"<Int>")
68 mc_help_inst = mc_help_inst.replace(u"<Integer>", u"<Int>")
69
65 class Foo(Configurable):
70 class Foo(Configurable):
66 a = Integer(0, config=True, help="The integer a.")
71 a = Integer(0, config=True, help="The integer a.")
67 b = Unicode('nope', config=True)
72 b = Unicode('nope', config=True)
@@ -75,7 +75,6 b' from StringIO import StringIO'
75
75
76 # IPython modules
76 # IPython modules
77 from IPython.core.splitinput import split_user_input, LineInfo
77 from IPython.core.splitinput import split_user_input, LineInfo
78 from IPython.utils.text import make_quoted_expr
79 from IPython.utils.py3compat import cast_unicode
78 from IPython.utils.py3compat import cast_unicode
80
79
81 #-----------------------------------------------------------------------------
80 #-----------------------------------------------------------------------------
@@ -503,8 +502,7 b' def transform_assign_system(line):'
503 if m is not None:
502 if m is not None:
504 cmd = m.group('cmd')
503 cmd = m.group('cmd')
505 lhs = m.group('lhs')
504 lhs = m.group('lhs')
506 expr = make_quoted_expr(cmd)
505 new_line = '%s = get_ipython().getoutput(%r)' % (lhs, cmd)
507 new_line = '%s = get_ipython().getoutput(%s)' % (lhs, expr)
508 return new_line
506 return new_line
509 return line
507 return line
510
508
@@ -518,8 +516,7 b' def transform_assign_magic(line):'
518 if m is not None:
516 if m is not None:
519 cmd = m.group('cmd')
517 cmd = m.group('cmd')
520 lhs = m.group('lhs')
518 lhs = m.group('lhs')
521 expr = make_quoted_expr(cmd)
519 new_line = '%s = get_ipython().magic(%r)' % (lhs, cmd)
522 new_line = '%s = get_ipython().magic(%s)' % (lhs, expr)
523 return new_line
520 return new_line
524 return line
521 return line
525
522
@@ -560,13 +557,13 b' def _make_help_call(target, esc, lspace, next_input=None):'
560 method = 'pinfo2' if esc == '??' \
557 method = 'pinfo2' if esc == '??' \
561 else 'psearch' if '*' in target \
558 else 'psearch' if '*' in target \
562 else 'pinfo'
559 else 'pinfo'
563 arg = make_quoted_expr(" ".join([method, target]))
560 arg = " ".join([method, target])
564
561
565 if next_input:
562 if next_input:
566 tpl = '%sget_ipython().magic(%s, next_input=%s)'
563 tpl = '%sget_ipython().magic(%r, next_input=%r)'
567 return tpl % (lspace, arg, make_quoted_expr(next_input))
564 return tpl % (lspace, arg, next_input)
568 else:
565 else:
569 return '%sget_ipython().magic(%s)' % (lspace, arg)
566 return '%sget_ipython().magic(%r)' % (lspace, arg)
570
567
571 _initial_space_re = re.compile(r'\s*')
568 _initial_space_re = re.compile(r'\s*')
572 _help_end_re = re.compile(r"""(%?
569 _help_end_re = re.compile(r"""(%?
@@ -610,15 +607,13 b' class EscapedTransformer(object):'
610 def _tr_system(line_info):
607 def _tr_system(line_info):
611 "Translate lines escaped with: !"
608 "Translate lines escaped with: !"
612 cmd = line_info.line.lstrip().lstrip(ESC_SHELL)
609 cmd = line_info.line.lstrip().lstrip(ESC_SHELL)
613 return '%sget_ipython().system(%s)' % (line_info.pre,
610 return '%sget_ipython().system(%r)' % (line_info.pre, cmd)
614 make_quoted_expr(cmd))
615
611
616 @staticmethod
612 @staticmethod
617 def _tr_system2(line_info):
613 def _tr_system2(line_info):
618 "Translate lines escaped with: !!"
614 "Translate lines escaped with: !!"
619 cmd = line_info.line.lstrip()[2:]
615 cmd = line_info.line.lstrip()[2:]
620 return '%sget_ipython().getoutput(%s)' % (line_info.pre,
616 return '%sget_ipython().getoutput(%r)' % (line_info.pre, cmd)
621 make_quoted_expr(cmd))
622
617
623 @staticmethod
618 @staticmethod
624 def _tr_help(line_info):
619 def _tr_help(line_info):
@@ -632,9 +627,8 b' class EscapedTransformer(object):'
632 @staticmethod
627 @staticmethod
633 def _tr_magic(line_info):
628 def _tr_magic(line_info):
634 "Translate lines escaped with: %"
629 "Translate lines escaped with: %"
635 tpl = '%sget_ipython().magic(%s)'
630 tpl = '%sget_ipython().magic(%r)'
636 cmd = make_quoted_expr(' '.join([line_info.ifun,
631 cmd = ' '.join([line_info.ifun, line_info.the_rest]).strip()
637 line_info.the_rest]).strip())
638 return tpl % (line_info.pre, cmd)
632 return tpl % (line_info.pre, cmd)
639
633
640 @staticmethod
634 @staticmethod
@@ -36,7 +36,6 b' from IPython.core.splitinput import split_user_input, LineInfo'
36 from IPython.core import page
36 from IPython.core import page
37
37
38 from IPython.utils.traitlets import List, Integer, Any, Unicode, CBool, Bool, Instance
38 from IPython.utils.traitlets import List, Integer, Any, Unicode, CBool, Bool, Instance
39 from IPython.utils.text import make_quoted_expr
40 from IPython.utils.autoattr import auto_attr
39 from IPython.utils.autoattr import auto_attr
41
40
42 #-----------------------------------------------------------------------------
41 #-----------------------------------------------------------------------------
@@ -405,8 +404,8 b' class AssignSystemTransformer(PrefilterTransformer):'
405 if m is not None:
404 if m is not None:
406 cmd = m.group('cmd')
405 cmd = m.group('cmd')
407 lhs = m.group('lhs')
406 lhs = m.group('lhs')
408 expr = make_quoted_expr("sc =%s" % cmd)
407 expr = "sc =%s" % cmd
409 new_line = '%s = get_ipython().magic(%s)' % (lhs, expr)
408 new_line = '%s = get_ipython().magic(%r)' % (lhs, expr)
410 return new_line
409 return new_line
411 return line
410 return line
412
411
@@ -424,8 +423,7 b' class AssignMagicTransformer(PrefilterTransformer):'
424 if m is not None:
423 if m is not None:
425 cmd = m.group('cmd')
424 cmd = m.group('cmd')
426 lhs = m.group('lhs')
425 lhs = m.group('lhs')
427 expr = make_quoted_expr(cmd)
426 new_line = '%s = get_ipython().magic(%r)' % (lhs, cmd)
428 new_line = '%s = get_ipython().magic(%s)' % (lhs, expr)
429 return new_line
427 return new_line
430 return line
428 return line
431
429
@@ -733,8 +731,7 b' class AliasHandler(PrefilterHandler):'
733 transformed = self.shell.alias_manager.expand_aliases(line_info.ifun,line_info.the_rest)
731 transformed = self.shell.alias_manager.expand_aliases(line_info.ifun,line_info.the_rest)
734 # pre is needed, because it carries the leading whitespace. Otherwise
732 # pre is needed, because it carries the leading whitespace. Otherwise
735 # aliases won't work in indented sections.
733 # aliases won't work in indented sections.
736 line_out = '%sget_ipython().system(%s)' % (line_info.pre_whitespace,
734 line_out = '%sget_ipython().system(%r)' % (line_info.pre_whitespace, transformed)
737 make_quoted_expr(transformed))
738
735
739 return line_out
736 return line_out
740
737
@@ -762,8 +759,7 b' class ShellEscapeHandler(PrefilterHandler):'
762 return magic_handler.handle(line_info)
759 return magic_handler.handle(line_info)
763 else:
760 else:
764 cmd = line.lstrip().lstrip(ESC_SHELL)
761 cmd = line.lstrip().lstrip(ESC_SHELL)
765 line_out = '%sget_ipython().system(%s)' % (line_info.pre_whitespace,
762 line_out = '%sget_ipython().system(%r)' % (line_info.pre_whitespace, cmd)
766 make_quoted_expr(cmd))
767 return line_out
763 return line_out
768
764
769
765
@@ -786,8 +782,8 b' class MagicHandler(PrefilterHandler):'
786 """Execute magic functions."""
782 """Execute magic functions."""
787 ifun = line_info.ifun
783 ifun = line_info.ifun
788 the_rest = line_info.the_rest
784 the_rest = line_info.the_rest
789 cmd = '%sget_ipython().magic(%s)' % (line_info.pre_whitespace,
785 cmd = '%sget_ipython().magic(%r)' % (line_info.pre_whitespace,
790 make_quoted_expr(ifun + " " + the_rest))
786 (ifun + " " + the_rest))
791 return cmd
787 return cmd
792
788
793
789
@@ -61,10 +61,10 b' def test_handlers():'
61 ip.alias_manager.alias_table['top'] = (0, 'd:/cygwin/top')
61 ip.alias_manager.alias_table['top'] = (0, 'd:/cygwin/top')
62 ip.alias_manager.alias_table['d'] = (0, 'true')
62 ip.alias_manager.alias_table['d'] = (0, 'true')
63 run([(i,py3compat.u_format(o)) for i,o in \
63 run([(i,py3compat.u_format(o)) for i,o in \
64 [("an_alias", 'get_ipython().system({u}"true ")'), # alias
64 [("an_alias", "get_ipython().system({u}'true ')"), # alias
65 # Below: recursive aliases should expand whitespace-surrounded
65 # Below: recursive aliases should expand whitespace-surrounded
66 # chars, *not* initial chars which happen to be aliases:
66 # chars, *not* initial chars which happen to be aliases:
67 ("top", 'get_ipython().system({u}"d:/cygwin/top ")'),
67 ("top", "get_ipython().system({u}'d:/cygwin/top ')"),
68 ]])
68 ]])
69 ip.system = old_system_cmd
69 ip.system = old_system_cmd
70
70
@@ -76,15 +76,15 b' def test_handlers():'
76 # line.
76 # line.
77 run([(i,py3compat.u_format(o)) for i,o in \
77 run([(i,py3compat.u_format(o)) for i,o in \
78 [('"no change"', '"no change"'), # normal
78 [('"no change"', '"no change"'), # normal
79 ("!true", 'get_ipython().system({u}"true")'), # shell_escapes
79 (u"!true", "get_ipython().system({u}'true')"), # shell_escapes
80 ("!! true", 'get_ipython().magic({u}"sx true")'), # shell_escapes + magic
80 (u"!! true", "get_ipython().magic({u}'sx true')"), # shell_escapes + magic
81 ("!!true", 'get_ipython().magic({u}"sx true")'), # shell_escapes + magic
81 (u"!!true", "get_ipython().magic({u}'sx true')"), # shell_escapes + magic
82 ("%lsmagic", 'get_ipython().magic({u}"lsmagic ")'), # magic
82 (u"%lsmagic", "get_ipython().magic({u}'lsmagic ')"), # magic
83 ("lsmagic", 'get_ipython().magic({u}"lsmagic ")'), # magic
83 (u"lsmagic", "get_ipython().magic({u}'lsmagic ')"), # magic
84 #("a = b # PYTHON-MODE", '_i'), # emacs -- avoids _in cache
84 #("a = b # PYTHON-MODE", '_i'), # emacs -- avoids _in cache
85
85
86 # post-esc-char whitespace goes inside
86 # post-esc-char whitespace goes inside
87 ("! true", 'get_ipython().system({u}" true")'),
87 (u"! true", "get_ipython().system({u}' true')"),
88
88
89 # handle_help
89 # handle_help
90
90
@@ -99,19 +99,19 b' def test_handlers():'
99 ip.prefilter_manager.multi_line_specials = False
99 ip.prefilter_manager.multi_line_specials = False
100 # W/ multi_line_specials off, leading ws kills esc chars/autoexpansion
100 # W/ multi_line_specials off, leading ws kills esc chars/autoexpansion
101 run([
101 run([
102 ('if 1:\n !true', 'if 1:\n !true'),
102 (u'if 1:\n !true', u'if 1:\n !true'),
103 ('if 1:\n lsmagic', 'if 1:\n lsmagic'),
103 (u'if 1:\n lsmagic', u'if 1:\n lsmagic'),
104 ('if 1:\n an_alias', 'if 1:\n an_alias'),
104 (u'if 1:\n an_alias', u'if 1:\n an_alias'),
105 ])
105 ])
106
106
107 ip.prefilter_manager.multi_line_specials = True
107 ip.prefilter_manager.multi_line_specials = True
108 # initial indents must be preserved.
108 # initial indents must be preserved.
109 run([(i,py3compat.u_format(o)) for i,o in \
109 run([(i,py3compat.u_format(o)) for i,o in \
110 [('if 1:\n !true', 'if 1:\n get_ipython().system({u}"true")'),
110 [(u'if 1:\n !true', "if 1:\n get_ipython().system({u}'true')"),
111 ('if 2:\n lsmagic', 'if 2:\n get_ipython().magic({u}"lsmagic ")'),
111 (u'if 2:\n lsmagic', "if 2:\n get_ipython().magic({u}'lsmagic ')"),
112 ('if 1:\n an_alias', 'if 1:\n get_ipython().system({u}"true ")'),
112 (u'if 1:\n an_alias', "if 1:\n get_ipython().system({u}'true ')"),
113 # Weird one
113 # Weird one
114 ('if 1:\n !!true', 'if 1:\n get_ipython().magic({u}"sx true")'),
114 (u'if 1:\n !!true', "if 1:\n get_ipython().magic({u}'sx true')"),
115
115
116 # Even with m_l_s on, autocall is off even with special chars
116 # Even with m_l_s on, autocall is off even with special chars
117 ('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'),
@@ -405,16 +405,16 b' def transform_checker(tests, func):'
405 syntax = \
405 syntax = \
406 dict(assign_system =
406 dict(assign_system =
407 [(i,py3compat.u_format(o)) for i,o in \
407 [(i,py3compat.u_format(o)) for i,o in \
408 [('a =! ls', 'a = get_ipython().getoutput({u}"ls")'),
408 [(u'a =! ls', "a = get_ipython().getoutput({u}'ls')"),
409 ('b = !ls', 'b = get_ipython().getoutput({u}"ls")'),
409 (u'b = !ls', "b = get_ipython().getoutput({u}'ls')"),
410 ('x=1', 'x=1'), # normal input is unmodified
410 ('x=1', 'x=1'), # normal input is unmodified
411 (' ',' '), # blank lines are kept intact
411 (' ',' '), # blank lines are kept intact
412 ]],
412 ]],
413
413
414 assign_magic =
414 assign_magic =
415 [(i,py3compat.u_format(o)) for i,o in \
415 [(i,py3compat.u_format(o)) for i,o in \
416 [('a =% who', 'a = get_ipython().magic({u}"who")'),
416 [(u'a =% who', "a = get_ipython().magic({u}'who')"),
417 ('b = %who', 'b = get_ipython().magic({u}"who")'),
417 (u'b = %who', "b = get_ipython().magic({u}'who')"),
418 ('x=1', 'x=1'), # normal input is unmodified
418 ('x=1', 'x=1'), # normal input is unmodified
419 (' ',' '), # blank lines are kept intact
419 (' ',' '), # blank lines are kept intact
420 ]],
420 ]],
@@ -442,43 +442,45 b' syntax = \\'
442 # System calls
442 # System calls
443 escaped_shell =
443 escaped_shell =
444 [(i,py3compat.u_format(o)) for i,o in \
444 [(i,py3compat.u_format(o)) for i,o in \
445 [ ('!ls', 'get_ipython().system({u}"ls")'),
445 [ (u'!ls', "get_ipython().system({u}'ls')"),
446 # Double-escape shell, this means to capture the output of the
446 # Double-escape shell, this means to capture the output of the
447 # subprocess and return it
447 # subprocess and return it
448 ('!!ls', 'get_ipython().getoutput({u}"ls")'),
448 (u'!!ls', "get_ipython().getoutput({u}'ls')"),
449 ]],
449 ]],
450
450
451 # Help/object info
451 # Help/object info
452 escaped_help =
452 escaped_help =
453 [(i,py3compat.u_format(o)) for i,o in \
453 [(i,py3compat.u_format(o)) for i,o in \
454 [ ('?', 'get_ipython().show_usage()'),
454 [ (u'?', 'get_ipython().show_usage()'),
455 ('?x1', 'get_ipython().magic({u}"pinfo x1")'),
455 (u'?x1', "get_ipython().magic({u}'pinfo x1')"),
456 ('??x2', 'get_ipython().magic({u}"pinfo2 x2")'),
456 (u'??x2', "get_ipython().magic({u}'pinfo2 x2')"),
457 ('?a.*s', 'get_ipython().magic({u}"psearch a.*s")'),
457 (u'?a.*s', "get_ipython().magic({u}'psearch a.*s')"),
458 ('?%hist', 'get_ipython().magic({u}"pinfo %hist")'),
458 (u'?%hist', "get_ipython().magic({u}'pinfo %hist')"),
459 ('?abc = qwe', 'get_ipython().magic({u}"pinfo abc")'),
459 (u'?abc = qwe', "get_ipython().magic({u}'pinfo abc')"),
460 ]],
460 ]],
461
461
462 end_help =
462 end_help =
463 [(i,py3compat.u_format(o)) for i,o in \
463 [(i,py3compat.u_format(o)) for i,o in \
464 [ ('x3?', 'get_ipython().magic({u}"pinfo x3")'),
464 [ (u'x3?', "get_ipython().magic({u}'pinfo x3')"),
465 ('x4??', 'get_ipython().magic({u}"pinfo2 x4")'),
465 (u'x4??', "get_ipython().magic({u}'pinfo2 x4')"),
466 ('%hist?', 'get_ipython().magic({u}"pinfo %hist")'),
466 (u'%hist?', "get_ipython().magic({u}'pinfo %hist')"),
467 ('f*?', 'get_ipython().magic({u}"psearch f*")'),
467 (u'f*?', "get_ipython().magic({u}'psearch f*')"),
468 ('ax.*aspe*?', 'get_ipython().magic({u}"psearch ax.*aspe*")'),
468 (u'ax.*aspe*?', "get_ipython().magic({u}'psearch ax.*aspe*')"),
469 ('a = abc?', 'get_ipython().magic({u}"pinfo abc", next_input={u}"a = abc")'),
469 (u'a = abc?', "get_ipython().magic({u}'pinfo abc', next_input={u}'a = abc')"),
470 ('a = abc.qe??', 'get_ipython().magic({u}"pinfo2 abc.qe", next_input={u}"a = abc.qe")'),
470 (u'a = abc.qe??', "get_ipython().magic({u}'pinfo2 abc.qe', next_input={u}'a = abc.qe')"),
471 ('a = *.items?', 'get_ipython().magic({u}"psearch *.items", next_input={u}"a = *.items")'),
471 (u'a = *.items?', "get_ipython().magic({u}'psearch *.items', next_input={u}'a = *.items')"),
472 ('plot(a?', 'get_ipython().magic({u}"pinfo a", next_input={u}"plot(a")'),
472 (u'plot(a?', "get_ipython().magic({u}'pinfo a', next_input={u}'plot(a')"),
473 ('a*2 #comment?', 'a*2 #comment?'),
473 (u'a*2 #comment?', 'a*2 #comment?'),
474 ]],
474 ]],
475
475
476 # Explicit magic calls
476 # Explicit magic calls
477 escaped_magic =
477 escaped_magic =
478 [(i,py3compat.u_format(o)) for i,o in \
478 [(i,py3compat.u_format(o)) for i,o in \
479 [ ('%cd', 'get_ipython().magic({u}"cd")'),
479 [ (u'%cd', "get_ipython().magic({u}'cd')"),
480 ('%cd /home', 'get_ipython().magic({u}"cd /home")'),
480 (u'%cd /home', "get_ipython().magic({u}'cd /home')"),
481 (' %magic', ' get_ipython().magic({u}"magic")'),
481 # Backslashes need to be escaped.
482 (u'%cd C:\\User', "get_ipython().magic({u}'cd C:\\\\User')"),
483 (u' %magic', " get_ipython().magic({u}'magic')"),
482 ]],
484 ]],
483
485
484 # Quoting with separate arguments
486 # Quoting with separate arguments
@@ -508,11 +510,11 b' syntax = \\'
508 # Check that we transform prompts before other transforms
510 # Check that we transform prompts before other transforms
509 mixed =
511 mixed =
510 [(i,py3compat.u_format(o)) for i,o in \
512 [(i,py3compat.u_format(o)) for i,o in \
511 [ ('In [1]: %lsmagic', 'get_ipython().magic({u}"lsmagic")'),
513 [ (u'In [1]: %lsmagic', "get_ipython().magic({u}'lsmagic')"),
512 ('>>> %lsmagic', 'get_ipython().magic({u}"lsmagic")'),
514 (u'>>> %lsmagic', "get_ipython().magic({u}'lsmagic')"),
513 ('In [2]: !ls', 'get_ipython().system({u}"ls")'),
515 (u'In [2]: !ls', "get_ipython().system({u}'ls')"),
514 ('In [3]: abs?', 'get_ipython().magic({u}"pinfo abs")'),
516 (u'In [3]: abs?', "get_ipython().magic({u}'pinfo abs')"),
515 ('In [4]: b = %who', 'b = get_ipython().magic({u}"who")'),
517 (u'In [4]: b = %who', "b = get_ipython().magic({u}'who')"),
516 ]],
518 ]],
517 )
519 )
518
520
@@ -295,40 +295,6 b' def esc_quotes(strng):'
295 return strng.replace('"','\\"').replace("'","\\'")
295 return strng.replace('"','\\"').replace("'","\\'")
296
296
297
297
298 def make_quoted_expr(s):
299 """Return string s in appropriate quotes, using raw string if possible.
300
301 XXX - example removed because it caused encoding errors in documentation
302 generation. We need a new example that doesn't contain invalid chars.
303
304 Note the use of raw string and padding at the end to allow trailing
305 backslash.
306 """
307
308 tail = ''
309 tailpadding = ''
310 raw = ''
311 ucode = '' if py3compat.PY3 else 'u'
312 if "\\" in s:
313 raw = 'r'
314 if s.endswith('\\'):
315 tail = '[:-1]'
316 tailpadding = '_'
317 if '"' not in s:
318 quote = '"'
319 elif "'" not in s:
320 quote = "'"
321 elif '"""' not in s and not s.endswith('"'):
322 quote = '"""'
323 elif "'''" not in s and not s.endswith("'"):
324 quote = "'''"
325 else:
326 # give up, backslash-escaped string will do
327 return '"%s"' % esc_quotes(s)
328 res = ucode + raw + quote + s + tailpadding + quote + tail
329 return res
330
331
332 def qw(words,flat=0,sep=None,maxsplit=-1):
298 def qw(words,flat=0,sep=None,maxsplit=-1):
333 """Similar to Perl's qw() operator, but with some more options.
299 """Similar to Perl's qw() operator, but with some more options.
334
300
General Comments 0
You need to be logged in to leave comments. Login now