##// END OF EJS Templates
Refined checking for assignment vs other python operators in the new input transformation/prefiltering system. This makes it once again possible for magics to do useful things which involve python operator characters (e.g. 'cd /'). Also added tests to verify this.
dan.milstein -
Show More
@@ -138,8 +138,9 b' def prefilter(line_info, ip):'
138 138 checkIPyAutocall,
139 139 checkMultiLineShell,
140 140 checkEscChars,
141 checkPythonChars,
141 checkAssignment,
142 142 checkAutomagic,
143 checkPythonOps,
143 144 checkAlias,
144 145 checkAutocall,
145 146 ]:
@@ -202,24 +203,27 b' def checkEscChars(l_info,ip):'
202 203 return ip.esc_handlers[l_info.preChar]
203 204 else:
204 205 return None
206
207
208 def checkAssignment(l_info,ip):
209 """Check to see if user is assigning to a var for the first time, in
210 which case we want to avoid any sort of automagic / autocall games.
205 211
206 def checkPythonChars(l_info,ip):
207 """If the 'rest' of the line begins with an (in)equality, assginment,
208 function call or tuple comma, we should simply execute the line
209 (regardless of whether or not there's a possible alias, automagic or
210 autocall expansion). This both avoids spurious geattr() accesses on
211 objects upon assignment, and also allows users to assign to either alias
212 or magic names true python variables (the magic/alias systems always
213 take second seat to true python code). E.g. ls='hi', or ls,that=1,2"""
214 if l_info.theRest and l_info.theRest[0] in '!=()<>,+*/%^&|':
212 This allows users to assign to either alias or magic names true python
213 variables (the magic/alias systems always take second seat to true
214 python code). E.g. ls='hi', or ls,that=1,2"""
215 if l_info.theRest and l_info.theRest[0] in '=,':
215 216 return ip.handle_normal
216 217 else:
217 218 return None
218 219
220
219 221 def checkAutomagic(l_info,ip):
220 222 """If the iFun is magic, and automagic is on, run it. Note: normal,
221 223 non-auto magic would already have been triggered via '%' in
222 check_esc_chars. This just checks for automagic."""
224 check_esc_chars. This just checks for automagic. Also, before
225 triggering the magic handler, make sure that there is nothing in the
226 user namespace which could shadow it."""
223 227 if not ip.rc.automagic or not hasattr(ip,'magic_'+l_info.iFun):
224 228 return None
225 229
@@ -233,7 +237,18 b' def checkAutomagic(l_info,ip):'
233 237
234 238 return ip.handle_magic
235 239
236
240
241 def checkPythonOps(l_info,ip):
242 """If the 'rest' of the line begins with a function call or pretty much
243 any python operator, we should simply execute the line (regardless of
244 whether or not there's a possible alias or autocall expansion). This
245 avoids spurious (and very confusing) geattr() accesses."""
246 if l_info.theRest and l_info.theRest[0] in '!=()<>,+*/%^&|':
247 return ip.handle_normal
248 else:
249 return None
250
251
237 252 def checkAlias(l_info,ip):
238 253 "Check if the initital identifier on the line is an alias."
239 254 # Note: aliases can not contain '.'
@@ -206,22 +206,25 b' run_handler_tests(['
206 206 # Without automagic, only shows up with explicit escape
207 207 ( 'cpaste', handle_normal),
208 208 ( '%cpaste', handle_magic),
209 ( '%does_not_exist', handle_magic)
209 ( '%does_not_exist', handle_magic),
210 210 ])
211 211 ip.options.automagic = 1
212 212 run_handler_tests([
213 213 ( 'cpaste', handle_magic),
214 214 ( '%cpaste', handle_magic),
215 215 ( 'does_not_exist', handle_normal),
216 ( '%does_not_exist', handle_magic)])
216 ( '%does_not_exist', handle_magic),
217 ( 'cd /', handle_magic),
218 ( 'cd = 2', handle_normal),
219 ])
217 220
218 221 # If next elt starts with anything that could be an assignment, func call,
219 222 # etc, we don't call the magic func, unless explicitly escaped to do so.
220 magic_killing_tests = []
221 for c in list('!=()<>,'):
222 magic_killing_tests.append(('cpaste %s killed_automagic' % c, handle_normal))
223 magic_killing_tests.append(('%%cpaste %s escaped_magic' % c, handle_magic))
224 run_handler_tests(magic_killing_tests)
223 #magic_killing_tests = []
224 #for c in list('!=()<>,'):
225 # magic_killing_tests.append(('cpaste %s killed_automagic' % c, handle_normal))
226 # magic_killing_tests.append(('%%cpaste %s escaped_magic' % c, handle_magic))
227 #run_handler_tests(magic_killing_tests)
225 228
226 229 # magic on indented continuation lines -- on iff multi_line_specials == 1
227 230 ip.options.multi_line_specials = 0
General Comments 0
You need to be logged in to leave comments. Login now