##// 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 17 import io
18 18 import json
19 19 import os
20 import re
20 21 import sys
21 22 from urllib2 import urlopen
22 23
@@ -39,6 +40,13 b' from IPython.utils.warn import warn'
39 40 # Used for exception handling in magic_edit
40 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 51 @magics_class
44 52 class CodeMagics(Magics):
@@ -274,7 +282,7 b' class CodeMagics(Magics):'
274 282 if filename is None:
275 283 warn("Argument given (%s) can't be found as a variable "
276 284 "or as a filename." % args)
277 return
285 return (None, None, None)
278 286 use_temp = False
279 287
280 288 except DataIsObject:
@@ -301,12 +309,18 b' class CodeMagics(Magics):'
301 309 # target instead
302 310 data = attr
303 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 317 datafile = 1
306 318 if filename is None:
307 319 filename = make_filename(args)
308 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 324 'Opening a file named `%s`' % (args, filename))
311 325 # Now, make sure we can actually read the source (if it was
312 326 # in a temp file it's gone by now).
@@ -316,9 +330,9 b' class CodeMagics(Magics):'
316 330 if lineno is None:
317 331 filename = make_filename(args)
318 332 if filename is None:
319 warn('The file `%s` where `%s` was defined '
320 'cannot be read.' % (filename, data))
321 return
333 warn('The file where `%s` was defined '
334 'cannot be read or found.' % data)
335 return (None, None, None)
322 336 use_temp = False
323 337
324 338 if use_temp:
@@ -491,6 +505,15 b' class CodeMagics(Magics):'
491 505 except MacroToEdit as e:
492 506 self._edit_macro(args, e.args[0])
493 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 518 # do actual editing here
496 519 print 'Editing...',
@@ -296,7 +296,7 b' def find_file(obj):'
296 296 pass
297 297 except:
298 298 pass
299 return fname
299 return cast_unicode(fname)
300 300
301 301
302 302 def find_source_lines(obj):
@@ -326,6 +326,8 b' def find_source_lines(obj):'
326 326 # For instances, try the class object like getsource() does
327 327 if hasattr(obj, '__class__'):
328 328 lineno = inspect.getsourcelines(obj.__class__)[1]
329 else:
330 lineno = None
329 331 except:
330 332 return None
331 333
@@ -28,7 +28,7 b' from IPython.core.magic import (Magics, magics_class, line_magic,'
28 28 cell_magic, line_cell_magic,
29 29 register_line_magic, register_cell_magic,
30 30 register_line_cell_magic)
31 from IPython.core.magics import execution, script
31 from IPython.core.magics import execution, script, code
32 32 from IPython.nbformat.v3.tests.nbexamples import nb0
33 33 from IPython.nbformat import current
34 34 from IPython.testing import decorators as dec
@@ -792,3 +792,49 b' def test_store():'
792 792 ip.user_ns['var'] = 39
793 793 ip.run_line_magic('store' , '-r')
794 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