##// END OF EJS Templates
Added functionality to %R and %octave magics so that -i first looks in local...
Guy Haskin Fernald -
Show More
@@ -2088,11 +2088,12 b' class InteractiveShell(SingletonConfigurable):'
2088 magic_arg_s = self.var_expand(line, stack_depth)
2088 magic_arg_s = self.var_expand(line, stack_depth)
2089 # Put magic args in a list so we can call with f(*a) syntax
2089 # Put magic args in a list so we can call with f(*a) syntax
2090 args = [magic_arg_s]
2090 args = [magic_arg_s]
2091 kwargs = {}
2091 # Grab local namespace if we need it:
2092 # Grab local namespace if we need it:
2092 if getattr(fn, "needs_local_scope", False):
2093 if getattr(fn, "needs_local_scope", False):
2093 args.append(sys._getframe(stack_depth).f_locals)
2094 kwargs['local_ns'] = sys._getframe(stack_depth).f_locals
2094 with self.builtin_trap:
2095 with self.builtin_trap:
2095 result = fn(*args)
2096 result = fn(*args,**kwargs)
2096 return result
2097 return result
2097
2098
2098 def run_cell_magic(self, magic_name, line, cell):
2099 def run_cell_magic(self, magic_name, line, cell):
@@ -812,7 +812,7 b' python-profiler package from non-free.""")'
812 @skip_doctest
812 @skip_doctest
813 @needs_local_scope
813 @needs_local_scope
814 @line_magic
814 @line_magic
815 def time(self,parameter_s, user_locals):
815 def time(self,parameter_s, local_ns=None):
816 """Time execution of a Python statement or expression.
816 """Time execution of a Python statement or expression.
817
817
818 The CPU and wall clock times are printed, and the value of the
818 The CPU and wall clock times are printed, and the value of the
@@ -884,11 +884,11 b' python-profiler package from non-free.""")'
884 wall_st = wtime()
884 wall_st = wtime()
885 if mode=='eval':
885 if mode=='eval':
886 st = clock2()
886 st = clock2()
887 out = eval(code, glob, user_locals)
887 out = eval(code, glob, local_ns)
888 end = clock2()
888 end = clock2()
889 else:
889 else:
890 st = clock2()
890 st = clock2()
891 exec code in glob, user_locals
891 exec code in glob, local_ns
892 end = clock2()
892 end = clock2()
893 out = None
893 out = None
894 wall_end = wtime()
894 wall_end = wtime()
@@ -45,7 +45,7 b' from xml.dom import minidom'
45
45
46 from IPython.core.displaypub import publish_display_data
46 from IPython.core.displaypub import publish_display_data
47 from IPython.core.magic import (Magics, magics_class, line_magic,
47 from IPython.core.magic import (Magics, magics_class, line_magic,
48 line_cell_magic)
48 line_cell_magic, needs_local_scope)
49 from IPython.testing.skipdoctest import skip_doctest
49 from IPython.testing.skipdoctest import skip_doctest
50 from IPython.core.magic_arguments import (
50 from IPython.core.magic_arguments import (
51 argument, magic_arguments, parse_argstring
51 argument, magic_arguments, parse_argstring
@@ -182,12 +182,13 b' class OctaveMagics(Magics):'
182 help='Plot format (png, svg or jpg).'
182 help='Plot format (png, svg or jpg).'
183 )
183 )
184
184
185 @needs_local_scope
185 @argument(
186 @argument(
186 'code',
187 'code',
187 nargs='*',
188 nargs='*',
188 )
189 )
189 @line_cell_magic
190 @line_cell_magic
190 def octave(self, line, cell=None):
191 def octave(self, line, cell=None, local_ns=None):
191 '''
192 '''
192 Execute code in Octave, and pull some of the results back into the
193 Execute code in Octave, and pull some of the results back into the
193 Python namespace.
194 Python namespace.
@@ -237,18 +238,24 b' class OctaveMagics(Magics):'
237 if cell is None:
238 if cell is None:
238 code = ''
239 code = ''
239 return_output = True
240 return_output = True
240 line_mode = True
241 else:
241 else:
242 code = cell
242 code = cell
243 return_output = False
243 return_output = False
244 line_mode = False
245
244
246 code = ' '.join(args.code) + code
245 code = ' '.join(args.code) + code
247
246
247 # if there is no local namespace then default to an empty dict
248 if local_ns is None:
249 local_ns = {}
250
248 if args.input:
251 if args.input:
249 for input in ','.join(args.input).split(','):
252 for input in ','.join(args.input).split(','):
250 input = unicode_to_str(input)
253 input = unicode_to_str(input)
251 self._oct.put(input, self.shell.user_ns[input])
254 try:
255 val = local_ns[input]
256 except KeyError:
257 val = self.shell.user_ns[input]
258 self._oct.put(input, val)
252
259
253 # generate plots in a temporary directory
260 # generate plots in a temporary directory
254 plot_dir = tempfile.mkdtemp()
261 plot_dir = tempfile.mkdtemp()
@@ -53,7 +53,7 b' ro.conversion.py2ri = numpy2ri'
53
53
54 from IPython.core.displaypub import publish_display_data
54 from IPython.core.displaypub import publish_display_data
55 from IPython.core.magic import (Magics, magics_class, cell_magic, line_magic,
55 from IPython.core.magic import (Magics, magics_class, cell_magic, line_magic,
56 line_cell_magic)
56 line_cell_magic, needs_local_scope)
57 from IPython.testing.skipdoctest import skip_doctest
57 from IPython.testing.skipdoctest import skip_doctest
58 from IPython.core.magic_arguments import (
58 from IPython.core.magic_arguments import (
59 argument, magic_arguments, parse_argstring
59 argument, magic_arguments, parse_argstring
@@ -344,8 +344,9 b' class RMagics(Magics):'
344 'code',
344 'code',
345 nargs='*',
345 nargs='*',
346 )
346 )
347 @needs_local_scope
347 @line_cell_magic
348 @line_cell_magic
348 def R(self, line, cell=None):
349 def R(self, line, cell=None, local_ns=None):
349 '''
350 '''
350 Execute code in R, and pull some of the results back into the Python namespace.
351 Execute code in R, and pull some of the results back into the Python namespace.
351
352
@@ -482,7 +483,8 b' class RMagics(Magics):'
482
483
483 # arguments 'code' in line are prepended to
484 # arguments 'code' in line are prepended to
484 # the cell lines
485 # the cell lines
485 if not cell:
486
487 if cell is None:
486 code = ''
488 code = ''
487 return_output = True
489 return_output = True
488 line_mode = True
490 line_mode = True
@@ -493,9 +495,17 b' class RMagics(Magics):'
493
495
494 code = ' '.join(args.code) + code
496 code = ' '.join(args.code) + code
495
497
498 # if there is no local namespace then default to an empty dict
499 if local_ns is None:
500 local_ns = {}
501
496 if args.input:
502 if args.input:
497 for input in ','.join(args.input).split(','):
503 for input in ','.join(args.input).split(','):
498 self.r.assign(input, self.pyconverter(self.shell.user_ns[input]))
504 try:
505 val = local_ns[input]
506 except KeyError:
507 val = self.shell.user_ns[input]
508 self.r.assign(input, self.pyconverter(val))
499
509
500 png_argdict = dict([(n, getattr(args, n)) for n in ['units', 'height', 'width', 'bg', 'pointsize']])
510 png_argdict = dict([(n, getattr(args, n)) for n in ['units', 'height', 'width', 'bg', 'pointsize']])
501 png_args = ','.join(['%s=%s' % (o,v) for o, v in png_argdict.items() if v is not None])
511 png_args = ','.join(['%s=%s' % (o,v) for o, v in png_argdict.items() if v is not None])
@@ -62,3 +62,24 b' def test_octave_plot():'
62 'plot([1, 2, 3]); figure; plot([4, 5, 6]);')
62 'plot([1, 2, 3]); figure; plot([4, 5, 6]);')
63
63
64 nt.assert_equal(test_octave_plot.svgs_generated, 2)
64 nt.assert_equal(test_octave_plot.svgs_generated, 2)
65
66 def test_octavemagic_localscope():
67 ip = get_ipython()
68 ip.magic('load_ext octavemagic')
69 ip.push({'x':0})
70 ip.run_line_magic('octave', '-i x -o result result = x+1')
71 result = ip.user_ns['result']
72 nt.assert_equal(result, 1)
73
74 ip.run_cell('''def octavemagic_addone(u):
75 %octave -i u -o result result = u+1
76 return result''')
77 ip.run_cell('result = octavemagic_addone(1)')
78 result = ip.user_ns['result']
79 nt.assert_equal(result, 2)
80
81 nt.assert_raises(
82 KeyError,
83 ip.run_line_magic,
84 "octave",
85 "-i var_not_defined 1+1")
@@ -60,3 +60,23 b' def test_cell_magic():'
60 ip.run_cell_magic('R', '-i x,y -o r,xc a=lm(y~x)', snippet)
60 ip.run_cell_magic('R', '-i x,y -o r,xc a=lm(y~x)', snippet)
61 np.testing.assert_almost_equal(ip.user_ns['xc'], [3.2, 0.9])
61 np.testing.assert_almost_equal(ip.user_ns['xc'], [3.2, 0.9])
62 np.testing.assert_almost_equal(ip.user_ns['r'], np.array([-0.2, 0.9, -1. , 0.1, 0.2]))
62 np.testing.assert_almost_equal(ip.user_ns['r'], np.array([-0.2, 0.9, -1. , 0.1, 0.2]))
63
64
65 def test_rmagic_localscope():
66 ip.push({'x':0})
67 ip.run_line_magic('R', '-i x -o result result <-x+1')
68 result = ip.user_ns['result']
69 nt.assert_equal(result[0], 1)
70
71 ip.run_cell('''def rmagic_addone(u):
72 %R -i u -o result result <- u+1
73 return result[0]''')
74 ip.run_cell('result = rmagic_addone(1)')
75 result = ip.user_ns['result']
76 nt.assert_equal(result, 2)
77
78 nt.assert_raises(
79 KeyError,
80 ip.run_line_magic,
81 "R",
82 "-i var_not_defined 1+1")
General Comments 0
You need to be logged in to leave comments. Login now