##// END OF EJS Templates
Merge pull request #2476 from minrk/editmagic...
Min RK -
r9024:c679a6cc merge
parent child Browse files
Show More
@@ -17,6 +17,7 b' import inspect'
17 import io
17 import io
18 import json
18 import json
19 import os
19 import os
20 import re
20 import sys
21 import sys
21 from urllib2 import urlopen
22 from urllib2 import urlopen
22
23
@@ -39,6 +40,13 b' from IPython.utils.warn import warn'
39 # Used for exception handling in magic_edit
40 # Used for exception handling in magic_edit
40 class MacroToEdit(ValueError): pass
41 class MacroToEdit(ValueError): pass
41
42
43 ipython_input_pat = re.compile(r"<ipython\-input\-(\d+)-[a-z\d]+>$")
44
45 class InteractivelyDefined(Exception):
46 """Exception for interactively defined variable in magic_edit"""
47 def __init__(self, index):
48 self.index = index
49
42
50
43 @magics_class
51 @magics_class
44 class CodeMagics(Magics):
52 class CodeMagics(Magics):
@@ -274,7 +282,7 b' class CodeMagics(Magics):'
274 if filename is None:
282 if filename is None:
275 warn("Argument given (%s) can't be found as a variable "
283 warn("Argument given (%s) can't be found as a variable "
276 "or as a filename." % args)
284 "or as a filename." % args)
277 return
285 return (None, None, None)
278 use_temp = False
286 use_temp = False
279
287
280 except DataIsObject:
288 except DataIsObject:
@@ -301,12 +309,18 b' class CodeMagics(Magics):'
301 # target instead
309 # target instead
302 data = attr
310 data = attr
303 break
311 break
304
312
313 m = ipython_input_pat.match(os.path.basename(filename))
314 if m:
315 raise InteractivelyDefined(int(m.groups()[0]))
316
305 datafile = 1
317 datafile = 1
306 if filename is None:
318 if filename is None:
307 filename = make_filename(args)
319 filename = make_filename(args)
308 datafile = 1
320 datafile = 1
309 warn('Could not find file where `%s` is defined.\n'
321 if filename is not None:
322 # only warn about this if we get a real name
323 warn('Could not find file where `%s` is defined.\n'
310 'Opening a file named `%s`' % (args, filename))
324 'Opening a file named `%s`' % (args, filename))
311 # Now, make sure we can actually read the source (if it was
325 # Now, make sure we can actually read the source (if it was
312 # in a temp file it's gone by now).
326 # in a temp file it's gone by now).
@@ -316,9 +330,9 b' class CodeMagics(Magics):'
316 if lineno is None:
330 if lineno is None:
317 filename = make_filename(args)
331 filename = make_filename(args)
318 if filename is None:
332 if filename is None:
319 warn('The file `%s` where `%s` was defined '
333 warn('The file where `%s` was defined '
320 'cannot be read.' % (filename, data))
334 'cannot be read or found.' % data)
321 return
335 return (None, None, None)
322 use_temp = False
336 use_temp = False
323
337
324 if use_temp:
338 if use_temp:
@@ -491,6 +505,15 b' class CodeMagics(Magics):'
491 except MacroToEdit as e:
505 except MacroToEdit as e:
492 self._edit_macro(args, e.args[0])
506 self._edit_macro(args, e.args[0])
493 return
507 return
508 except InteractivelyDefined as e:
509 print "Editing In[%i]" % e.index
510 args = str(e.index)
511 filename, lineno, is_temp = self._find_edit_target(self.shell,
512 args, opts, last_call)
513 if filename is None:
514 # nothing was found, warnings have already been issued,
515 # just give up.
516 return
494
517
495 # do actual editing here
518 # do actual editing here
496 print 'Editing...',
519 print 'Editing...',
@@ -296,7 +296,7 b' def find_file(obj):'
296 pass
296 pass
297 except:
297 except:
298 pass
298 pass
299 return fname
299 return cast_unicode(fname)
300
300
301
301
302 def find_source_lines(obj):
302 def find_source_lines(obj):
@@ -326,6 +326,8 b' def find_source_lines(obj):'
326 # For instances, try the class object like getsource() does
326 # For instances, try the class object like getsource() does
327 if hasattr(obj, '__class__'):
327 if hasattr(obj, '__class__'):
328 lineno = inspect.getsourcelines(obj.__class__)[1]
328 lineno = inspect.getsourcelines(obj.__class__)[1]
329 else:
330 lineno = None
329 except:
331 except:
330 return None
332 return None
331
333
@@ -28,7 +28,7 b' from IPython.core.magic import (Magics, magics_class, line_magic,'
28 cell_magic, line_cell_magic,
28 cell_magic, line_cell_magic,
29 register_line_magic, register_cell_magic,
29 register_line_magic, register_cell_magic,
30 register_line_cell_magic)
30 register_line_cell_magic)
31 from IPython.core.magics import execution, script
31 from IPython.core.magics import execution, script, code
32 from IPython.nbformat.v3.tests.nbexamples import nb0
32 from IPython.nbformat.v3.tests.nbexamples import nb0
33 from IPython.nbformat import current
33 from IPython.nbformat import current
34 from IPython.testing import decorators as dec
34 from IPython.testing import decorators as dec
@@ -792,3 +792,49 b' def test_store():'
792 ip.user_ns['var'] = 39
792 ip.user_ns['var'] = 39
793 ip.run_line_magic('store' , '-r')
793 ip.run_line_magic('store' , '-r')
794 nt.assert_equal(ip.user_ns['var'], 39)
794 nt.assert_equal(ip.user_ns['var'], 39)
795
796
797 def _run_edit_test(arg_s, exp_filename=None,
798 exp_lineno=-1,
799 exp_contents=None,
800 exp_is_temp=None):
801 ip = get_ipython()
802 M = code.CodeMagics(ip)
803 last_call = ['','']
804 opts,args = M.parse_options(arg_s,'prxn:')
805 filename, lineno, is_temp = M._find_edit_target(ip, args, opts, last_call)
806
807 if exp_filename is not None:
808 nt.assert_equal(exp_filename, filename)
809 if exp_contents is not None:
810 with io.open(filename, 'r') as f:
811 contents = f.read()
812 nt.assert_equal(exp_contents, contents)
813 if exp_lineno != -1:
814 nt.assert_equal(exp_lineno, lineno)
815 if exp_is_temp is not None:
816 nt.assert_equal(exp_is_temp, is_temp)
817
818
819 def test_edit_interactive():
820 """%edit on interactively defined objects"""
821 ip = get_ipython()
822 n = ip.execution_count
823 ip.run_cell(u"def foo(): return 1", store_history=True)
824
825 try:
826 _run_edit_test("foo")
827 except code.InteractivelyDefined as e:
828 nt.assert_equal(e.index, n)
829 else:
830 nt.fail("Should have raised InteractivelyDefined")
831
832
833 def test_edit_cell():
834 """%edit [cell id]"""
835 ip = get_ipython()
836
837 ip.run_cell(u"def foo(): return 1", store_history=True)
838
839 # test
840 _run_edit_test("1", exp_contents=ip.user_ns['In'][1], exp_is_temp=True)
General Comments 0
You need to be logged in to leave comments. Login now