##// END OF EJS Templates
save future compile directives from ipython -i module.py
Thomas Ballinger -
Show More
@@ -2565,10 +2565,16 b' class InteractiveShell(SingletonConfigurable):'
2565 silenced for zero status, as it is so common).
2565 silenced for zero status, as it is so common).
2566 raise_exceptions : bool (False)
2566 raise_exceptions : bool (False)
2567 If True raise exceptions everywhere. Meant for testing.
2567 If True raise exceptions everywhere. Meant for testing.
2568 shell_futures : bool (False)
2569 If True, the code will share future statements with the interactive
2570 shell. It will both be affected by previous __future__ imports, and
2571 any __future__ imports in the code will affect the shell. If False,
2572 __future__ imports are not shared in either direction.
2568
2573
2569 """
2574 """
2570 kw.setdefault('exit_ignore', False)
2575 kw.setdefault('exit_ignore', False)
2571 kw.setdefault('raise_exceptions', False)
2576 kw.setdefault('raise_exceptions', False)
2577 kw.setdefault('shell_futures', False)
2572
2578
2573 fname = os.path.abspath(os.path.expanduser(fname))
2579 fname = os.path.abspath(os.path.expanduser(fname))
2574
2580
@@ -2587,7 +2593,10 b' class InteractiveShell(SingletonConfigurable):'
2587
2593
2588 with prepended_to_syspath(dname):
2594 with prepended_to_syspath(dname):
2589 try:
2595 try:
2590 py3compat.execfile(fname,*where)
2596 glob, loc = (where + (None, ))[:2]
2597 py3compat.execfile(
2598 fname, glob, loc,
2599 self.compile if kw['shell_futures'] else None)
2591 except SystemExit as status:
2600 except SystemExit as status:
2592 # If the call was made with 0 or None exit status (sys.exit(0)
2601 # If the call was made with 0 or None exit status (sys.exit(0)
2593 # or sys.exit() ), don't bother showing a traceback, as both of
2602 # or sys.exit() ), don't bother showing a traceback, as both of
@@ -2608,7 +2617,7 b' class InteractiveShell(SingletonConfigurable):'
2608 # tb offset is 2 because we wrap execfile
2617 # tb offset is 2 because we wrap execfile
2609 self.showtraceback(tb_offset=2)
2618 self.showtraceback(tb_offset=2)
2610
2619
2611 def safe_execfile_ipy(self, fname):
2620 def safe_execfile_ipy(self, fname, shell_futures=False):
2612 """Like safe_execfile, but for .ipy or .ipynb files with IPython syntax.
2621 """Like safe_execfile, but for .ipy or .ipynb files with IPython syntax.
2613
2622
2614 Parameters
2623 Parameters
@@ -2616,6 +2625,11 b' class InteractiveShell(SingletonConfigurable):'
2616 fname : str
2625 fname : str
2617 The name of the file to execute. The filename must have a
2626 The name of the file to execute. The filename must have a
2618 .ipy or .ipynb extension.
2627 .ipy or .ipynb extension.
2628 shell_futures : bool (False)
2629 If True, the code will share future statements with the interactive
2630 shell. It will both be affected by previous __future__ imports, and
2631 any __future__ imports in the code will affect the shell. If False,
2632 __future__ imports are not shared in either direction.
2619 """
2633 """
2620 fname = os.path.abspath(os.path.expanduser(fname))
2634 fname = os.path.abspath(os.path.expanduser(fname))
2621
2635
@@ -2654,7 +2668,7 b' class InteractiveShell(SingletonConfigurable):'
2654 # raised in user code. It would be nice if there were
2668 # raised in user code. It would be nice if there were
2655 # versions of run_cell that did raise, so
2669 # versions of run_cell that did raise, so
2656 # we could catch the errors.
2670 # we could catch the errors.
2657 self.run_cell(cell, silent=True, shell_futures=False)
2671 self.run_cell(cell, silent=True, shell_futures=shell_futures)
2658 except:
2672 except:
2659 self.showtraceback()
2673 self.showtraceback()
2660 warn('Unknown failure executing file: <%s>' % fname)
2674 warn('Unknown failure executing file: <%s>' % fname)
@@ -324,7 +324,7 b' class InteractiveShellApp(Configurable):'
324 self.log.warn("Unknown error in handling IPythonApp.exec_lines:")
324 self.log.warn("Unknown error in handling IPythonApp.exec_lines:")
325 self.shell.showtraceback()
325 self.shell.showtraceback()
326
326
327 def _exec_file(self, fname):
327 def _exec_file(self, fname, shell_futures=False):
328 try:
328 try:
329 full_filename = filefind(fname, [u'.', self.ipython_dir])
329 full_filename = filefind(fname, [u'.', self.ipython_dir])
330 except IOError as e:
330 except IOError as e:
@@ -346,11 +346,13 b' class InteractiveShellApp(Configurable):'
346 with preserve_keys(self.shell.user_ns, '__file__'):
346 with preserve_keys(self.shell.user_ns, '__file__'):
347 self.shell.user_ns['__file__'] = fname
347 self.shell.user_ns['__file__'] = fname
348 if full_filename.endswith('.ipy'):
348 if full_filename.endswith('.ipy'):
349 self.shell.safe_execfile_ipy(full_filename)
349 self.shell.safe_execfile_ipy(full_filename,
350 shell_futures=shell_futures)
350 else:
351 else:
351 # default to python, even without extension
352 # default to python, even without extension
352 self.shell.safe_execfile(full_filename,
353 self.shell.safe_execfile(full_filename,
353 self.shell.user_ns)
354 self.shell.user_ns,
355 shell_futures=shell_futures)
354 finally:
356 finally:
355 sys.argv = save_argv
357 sys.argv = save_argv
356
358
@@ -418,7 +420,7 b' class InteractiveShellApp(Configurable):'
418 elif self.file_to_run:
420 elif self.file_to_run:
419 fname = self.file_to_run
421 fname = self.file_to_run
420 try:
422 try:
421 self._exec_file(fname)
423 self._exec_file(fname, shell_futures=True)
422 except:
424 except:
423 self.log.warn("Error in executing file in user namespace: %s" %
425 self.log.warn("Error in executing file in user namespace: %s" %
424 fname)
426 fname)
@@ -19,6 +19,11 b' import unittest'
19
19
20 from IPython.testing import decorators as dec
20 from IPython.testing import decorators as dec
21 from IPython.testing import tools as tt
21 from IPython.testing import tools as tt
22 from IPython.utils.py3compat import PY3
23
24 sqlite_err_maybe = dec.module_not_available('sqlite3')
25 SQLITE_NOT_AVAILABLE_ERROR = ('WARNING: IPython History requires SQLite,'
26 ' your history will not be saved\n')
22
27
23 class TestFileToRun(unittest.TestCase, tt.TempFileMixin):
28 class TestFileToRun(unittest.TestCase, tt.TempFileMixin):
24 """Test the behavior of the file_to_run parameter."""
29 """Test the behavior of the file_to_run parameter."""
@@ -28,10 +33,7 b' class TestFileToRun(unittest.TestCase, tt.TempFileMixin):'
28 src = "print(__file__)\n"
33 src = "print(__file__)\n"
29 self.mktmp(src)
34 self.mktmp(src)
30
35
31 if dec.module_not_available('sqlite3'):
36 err = SQLITE_NOT_AVAILABLE_ERROR if sqlite_err_maybe else None
32 err = 'WARNING: IPython History requires SQLite, your history will not be saved\n'
33 else:
34 err = None
35 tt.ipexec_validate(self.fname, self.fname, err)
37 tt.ipexec_validate(self.fname, self.fname, err)
36
38
37 def test_ipy_script_file_attribute(self):
39 def test_ipy_script_file_attribute(self):
@@ -39,11 +41,24 b' class TestFileToRun(unittest.TestCase, tt.TempFileMixin):'
39 src = "print(__file__)\n"
41 src = "print(__file__)\n"
40 self.mktmp(src, ext='.ipy')
42 self.mktmp(src, ext='.ipy')
41
43
42 if dec.module_not_available('sqlite3'):
44 err = SQLITE_NOT_AVAILABLE_ERROR if sqlite_err_maybe else None
43 err = 'WARNING: IPython History requires SQLite, your history will not be saved\n'
44 else:
45 err = None
46 tt.ipexec_validate(self.fname, self.fname, err)
45 tt.ipexec_validate(self.fname, self.fname, err)
47
46
48 # Ideally we would also test that `__file__` is not set in the
47 def test_py_script_file_attribute_interactively(self):
49 # interactive namespace after running `ipython -i <file>`.
48 """Test that `__file__` is not set after `ipython -i file.py`"""
49 src = "True\n"
50 self.mktmp(src)
51
52 err = SQLITE_NOT_AVAILABLE_ERROR if sqlite_err_maybe else None
53 tt.ipexec_validate(self.fname, 'False', err, options=['-i'],
54 commands=['"__file__" in globals()', 'exit()'])
55
56 @dec.skipif(PY3)
57 def test_py_script_file_compiler_directive(self):
58 """Test `__future__` compiler directives with `ipython -i file.py`"""
59 src = "from __future__ import division\n"
60 self.mktmp(src)
61
62 err = SQLITE_NOT_AVAILABLE_ERROR if sqlite_err_maybe else None
63 tt.ipexec_validate(self.fname, 'float', err, options=['-i'],
64 commands=['type(1/2)', 'exit()'])
@@ -177,7 +177,7 b' def get_ipython_cmd(as_string=False):'
177
177
178 return ipython_cmd
178 return ipython_cmd
179
179
180 def ipexec(fname, options=None):
180 def ipexec(fname, options=None, commands=()):
181 """Utility to call 'ipython filename'.
181 """Utility to call 'ipython filename'.
182
182
183 Starts IPython with a minimal and safe configuration to make startup as fast
183 Starts IPython with a minimal and safe configuration to make startup as fast
@@ -193,6 +193,9 b' def ipexec(fname, options=None):'
193 options : optional, list
193 options : optional, list
194 Extra command-line flags to be passed to IPython.
194 Extra command-line flags to be passed to IPython.
195
195
196 commands : optional, list
197 Commands to send in on stdin
198
196 Returns
199 Returns
197 -------
200 -------
198 (stdout, stderr) of ipython subprocess.
201 (stdout, stderr) of ipython subprocess.
@@ -215,8 +218,8 b' def ipexec(fname, options=None):'
215 full_cmd = ipython_cmd + cmdargs + [full_fname]
218 full_cmd = ipython_cmd + cmdargs + [full_fname]
216 env = os.environ.copy()
219 env = os.environ.copy()
217 env.pop('PYTHONWARNINGS', None) # Avoid extraneous warnings appearing on stderr
220 env.pop('PYTHONWARNINGS', None) # Avoid extraneous warnings appearing on stderr
218 p = Popen(full_cmd, stdout=PIPE, stderr=PIPE, env=env)
221 p = Popen(full_cmd, stdout=PIPE, stderr=PIPE, stdin=PIPE, env=env)
219 out, err = p.communicate()
222 out, err = p.communicate(input=py3compat.str_to_bytes('\n'.join(commands)) or None)
220 out, err = py3compat.bytes_to_str(out), py3compat.bytes_to_str(err)
223 out, err = py3compat.bytes_to_str(out), py3compat.bytes_to_str(err)
221 # `import readline` causes 'ESC[?1034h' to be output sometimes,
224 # `import readline` causes 'ESC[?1034h' to be output sometimes,
222 # so strip that out before doing comparisons
225 # so strip that out before doing comparisons
@@ -226,7 +229,7 b' def ipexec(fname, options=None):'
226
229
227
230
228 def ipexec_validate(fname, expected_out, expected_err='',
231 def ipexec_validate(fname, expected_out, expected_err='',
229 options=None):
232 options=None, commands=()):
230 """Utility to call 'ipython filename' and validate output/error.
233 """Utility to call 'ipython filename' and validate output/error.
231
234
232 This function raises an AssertionError if the validation fails.
235 This function raises an AssertionError if the validation fails.
@@ -254,7 +257,7 b" def ipexec_validate(fname, expected_out, expected_err='',"
254
257
255 import nose.tools as nt
258 import nose.tools as nt
256
259
257 out, err = ipexec(fname, options)
260 out, err = ipexec(fname, options, commands)
258 #print 'OUT', out # dbg
261 #print 'OUT', out # dbg
259 #print 'ERR', err # dbg
262 #print 'ERR', err # dbg
260 # If there are any errors, we must check those befor stdout, as they may be
263 # If there are any errors, we must check those befor stdout, as they may be
@@ -101,11 +101,12 b' if sys.version_info[0] >= 3:'
101 getcwd = os.getcwd
101 getcwd = os.getcwd
102
102
103 MethodType = types.MethodType
103 MethodType = types.MethodType
104
104
105 def execfile(fname, glob, loc=None):
105 def execfile(fname, glob, loc=None, compiler=None):
106 loc = loc if (loc is not None) else glob
106 loc = loc if (loc is not None) else glob
107 with open(fname, 'rb') as f:
107 with open(fname, 'rb') as f:
108 exec(compile(f.read(), fname, 'exec'), glob, loc)
108 compiler = compiler or compile
109 exec(compiler(f.read(), fname, 'exec'), glob, loc)
109
110
110 # Refactor print statements in doctests.
111 # Refactor print statements in doctests.
111 _print_statement_re = re.compile(r"\bprint (?P<expr>.*)$", re.MULTILINE)
112 _print_statement_re = re.compile(r"\bprint (?P<expr>.*)$", re.MULTILINE)
@@ -185,7 +186,7 b' else:'
185 return s.format(u='u')
186 return s.format(u='u')
186
187
187 if sys.platform == 'win32':
188 if sys.platform == 'win32':
188 def execfile(fname, glob=None, loc=None):
189 def execfile(fname, glob=None, loc=None, compiler=None):
189 loc = loc if (loc is not None) else glob
190 loc = loc if (loc is not None) else glob
190 # The rstrip() is necessary b/c trailing whitespace in files will
191 # The rstrip() is necessary b/c trailing whitespace in files will
191 # cause an IndentationError in Python 2.6 (this was fixed in 2.7,
192 # cause an IndentationError in Python 2.6 (this was fixed in 2.7,
@@ -197,14 +198,21 b' else:'
197 filename = unicode_to_str(fname)
198 filename = unicode_to_str(fname)
198 else:
199 else:
199 filename = fname
200 filename = fname
200 exec(compile(scripttext, filename, 'exec'), glob, loc)
201 compiler = compiler or compile
202 exec(compiler(scripttext, filename, 'exec'), glob, loc)
203
201 else:
204 else:
202 def execfile(fname, *where):
205 def execfile(fname, glob=None, loc=None, compiler=None):
203 if isinstance(fname, unicode):
206 if isinstance(fname, unicode):
204 filename = fname.encode(sys.getfilesystemencoding())
207 filename = fname.encode(sys.getfilesystemencoding())
205 else:
208 else:
206 filename = fname
209 filename = fname
207 builtin_mod.execfile(filename, *where)
210 where = [ns for ns in [glob, loc] if ns is not None]
211 if compiler is None:
212 builtin_mod.execfile(filename, *where)
213 else:
214 scripttext = builtin_mod.open(fname).read().rstrip() + '\n'
215 exec(compiler(scripttext, filename, 'exec'), glob, loc)
208
216
209
217
210 def annotate(**kwargs):
218 def annotate(**kwargs):
General Comments 0
You need to be logged in to leave comments. Login now