##// END OF EJS Templates
Prettified and hardened string/backslash quoting with ipsystem(), ipalias() and ...
vivainio -
r100:d79e37bb
parent child
Show More
@@ -5,7 +5,7 General purpose utilities.
5 This is a grab-bag of stuff I find useful in most programs I write. Some of
5 This is a grab-bag of stuff I find useful in most programs I write. Some of
6 these things are also convenient when working at the command line.
6 these things are also convenient when working at the command line.
7
7
8 $Id: genutils.py 994 2006-01-08 08:29:44Z fperez $"""
8 $Id: genutils.py 1007 2006-01-12 17:15:41Z vivainio $"""
9
9
10 #*****************************************************************************
10 #*****************************************************************************
11 # Copyright (C) 2001-2006 Fernando Perez. <fperez@colorado.edu>
11 # Copyright (C) 2001-2006 Fernando Perez. <fperez@colorado.edu>
@@ -949,6 +949,40 def esc_quotes(strng):
949 return strng.replace('"','\\"').replace("'","\\'")
949 return strng.replace('"','\\"').replace("'","\\'")
950
950
951 #----------------------------------------------------------------------------
951 #----------------------------------------------------------------------------
952 def make_quoted_expr(s):
953 """Return string s in appropriate quotes, using raw string if possible.
954
955 Effectively this turns string: cd \ao\ao\
956 to: r"cd \ao\ao\_"[:-1]
957
958 Note the use of raw string and padding at the end to allow trailing backslash.
959
960 """
961
962 tail = ''
963 tailpadding = ''
964 raw = ''
965 if "\\" in s:
966 raw = 'r'
967 if s.endswith('\\'):
968 tail = '[:-1]'
969 tailpadding = '_'
970 if '"' not in s:
971 quote = '"'
972 elif "'" not in s:
973 quote = "'"
974 elif '"""' not in s and not s.endswith('"'):
975 quote = '"""'
976 elif "'''" not in s and not s.endswith("'"):
977 quote = "'''"
978 else:
979 # give up, backslash-escaped string will do
980 return '"%s"' % esc_quotes(s)
981 res = itpl("$raw$quote$s$tailpadding$quote$tail")
982 return res
983
984
985 #----------------------------------------------------------------------------
952 def raw_input_multi(header='', ps1='==> ', ps2='..> ',terminate_str = '.'):
986 def raw_input_multi(header='', ps1='==> ', ps2='..> ',terminate_str = '.'):
953 """Take multiple lines of input.
987 """Take multiple lines of input.
954
988
@@ -6,7 +6,7 Requires Python 2.1 or newer.
6
6
7 This file contains all the classes and helper functions specific to IPython.
7 This file contains all the classes and helper functions specific to IPython.
8
8
9 $Id: iplib.py 1005 2006-01-12 08:39:26Z fperez $
9 $Id: iplib.py 1007 2006-01-12 17:15:41Z vivainio $
10 """
10 """
11
11
12 #*****************************************************************************
12 #*****************************************************************************
@@ -1180,6 +1180,7 want to merge them back into the new files.""" % locals()
1180
1180
1181 if e.filename in ('<ipython console>','<input>','<string>',
1181 if e.filename in ('<ipython console>','<input>','<string>',
1182 '<console>',None):
1182 '<console>',None):
1183
1183 return False
1184 return False
1184 try:
1185 try:
1185 if not ask_yes_no('Return to editor to correct syntax error? '
1186 if not ask_yes_no('Return to editor to correct syntax error? '
@@ -1887,7 +1888,7 want to merge them back into the new files.""" % locals()
1887
1888
1888 # pre is needed, because it carries the leading whitespace. Otherwise
1889 # pre is needed, because it carries the leading whitespace. Otherwise
1889 # aliases won't work in indented sections.
1890 # aliases won't work in indented sections.
1890 line_out = '%sipalias("%s %s")' % (pre,iFun,esc_quotes(theRest))
1891 line_out = '%sipalias(%s)' % (pre,make_quoted_expr(iFun + " " + theRest))
1891 self.log(line_out,continue_prompt)
1892 self.log(line_out,continue_prompt)
1892 return line_out
1893 return line_out
1893
1894
@@ -1897,36 +1898,27 want to merge them back into the new files.""" % locals()
1897
1898
1898 #print 'line in :', `line` # dbg
1899 #print 'line in :', `line` # dbg
1899 # Example of a special handler. Others follow a similar pattern.
1900 # Example of a special handler. Others follow a similar pattern.
1900 if continue_prompt: # multi-line statements
1901 if line.startswith('!!'):
1901 if iFun.startswith('!!'):
1902 # rewrite iFun/theRest to properly hold the call to %sx and
1902 print 'SyntaxError: !! is not allowed in multiline statements'
1903 # the actual command to be executed, so handle_magic can work
1903 return pre
1904 # correctly
1904 else:
1905 theRest = '%s %s' % (iFun[2:],theRest)
1905 cmd = ("%s %s" % (iFun[1:],theRest))
1906 iFun = 'sx'
1906 line_out = '%sipsystem(r"""%s"""[:-1])' % (pre,cmd + "_")
1907 return self.handle_magic('%ssx %s' % (self.ESC_MAGIC,line[2:]),
1907 else: # single-line input
1908 continue_prompt,pre,iFun,theRest)
1908 if line.startswith('!!'):
1909 else:
1909 # rewrite iFun/theRest to properly hold the call to %sx and
1910 cmd=line[1:]
1910 # the actual command to be executed, so handle_magic can work
1911 line_out = '%sipsystem(%s)' % (pre,make_quoted_expr(cmd))
1911 # correctly
1912 theRest = '%s %s' % (iFun[2:],theRest)
1913 iFun = 'sx'
1914 return self.handle_magic('%ssx %s' % (self.ESC_MAGIC,line[2:]),
1915 continue_prompt,pre,iFun,theRest)
1916 else:
1917 cmd=line[1:]
1918 line_out = '%sipsystem(r"""%s"""[:-1])' % (pre,cmd +"_")
1919 # update cache/log and return
1912 # update cache/log and return
1920 self.log(line_out,continue_prompt)
1913 self.log(line_out,continue_prompt)
1921 return line_out
1914 return line_out
1922
1915
1923 def handle_magic(self, line, continue_prompt=None,
1916 def handle_magic(self, line, continue_prompt=None,
1924 pre=None,iFun=None,theRest=None):
1917 pre=None,iFun=None,theRest=None):
1925 """Execute magic functions.
1918 """Execute magic functions."""
1926
1919
1927 Also log them with a prepended # so the log is clean Python."""
1928
1920
1929 cmd = '%sipmagic("%s")' % (pre,esc_quotes('%s %s' % (iFun,theRest)))
1921 cmd = '%sipmagic(%s)' % (pre,make_quoted_expr(iFun + " " + theRest))
1930 self.log(cmd,continue_prompt)
1922 self.log(cmd,continue_prompt)
1931 #print 'in handle_magic, cmd=<%s>' % cmd # dbg
1923 #print 'in handle_magic, cmd=<%s>' % cmd # dbg
1932 return cmd
1924 return cmd
@@ -1,3 +1,14
1 2006-01-12 Ville Vainio <vivainio@gmail.com>
2
3 * IPython/iplib.py.py (make_quoted_expr,handle_shell_escape):
4 Prettified and hardened string/backslash quoting with ipsystem(),
5 ipalias() and ipmagic(). Now even \ characters are passed to
6 %magics, !shell escapes and aliases exactly as they are in the
7 ipython command line. Should improve backslash experience,
8 particularly in Windows. %cd magic still doesn't support backslash
9 path delimiters, though. Also deleted all pretense of supporting
10 multiline command strings in !system or %magic commands.
11
1 2006-01-12 Fernando Perez <Fernando.Perez@colorado.edu>
12 2006-01-12 Fernando Perez <Fernando.Perez@colorado.edu>
2
13
3 * IPython/ipstruct.py (Struct): Rename IPython.Struct to
14 * IPython/ipstruct.py (Struct): Rename IPython.Struct to
General Comments 0
You need to be logged in to leave comments. Login now