Show More
@@ -2565,10 +2565,16 b' class InteractiveShell(SingletonConfigurable):' | |||
|
2565 | 2565 | silenced for zero status, as it is so common). |
|
2566 | 2566 | raise_exceptions : bool (False) |
|
2567 | 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 | 2575 | kw.setdefault('exit_ignore', False) |
|
2571 | 2576 | kw.setdefault('raise_exceptions', False) |
|
2577 | kw.setdefault('shell_futures', False) | |
|
2572 | 2578 | |
|
2573 | 2579 | fname = os.path.abspath(os.path.expanduser(fname)) |
|
2574 | 2580 | |
@@ -2587,7 +2593,10 b' class InteractiveShell(SingletonConfigurable):' | |||
|
2587 | 2593 | |
|
2588 | 2594 | with prepended_to_syspath(dname): |
|
2589 | 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 | 2600 | except SystemExit as status: |
|
2592 | 2601 | # If the call was made with 0 or None exit status (sys.exit(0) |
|
2593 | 2602 | # or sys.exit() ), don't bother showing a traceback, as both of |
@@ -2608,7 +2617,7 b' class InteractiveShell(SingletonConfigurable):' | |||
|
2608 | 2617 | # tb offset is 2 because we wrap execfile |
|
2609 | 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 | 2621 | """Like safe_execfile, but for .ipy or .ipynb files with IPython syntax. |
|
2613 | 2622 | |
|
2614 | 2623 | Parameters |
@@ -2616,6 +2625,11 b' class InteractiveShell(SingletonConfigurable):' | |||
|
2616 | 2625 | fname : str |
|
2617 | 2626 | The name of the file to execute. The filename must have a |
|
2618 | 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 | 2634 | fname = os.path.abspath(os.path.expanduser(fname)) |
|
2621 | 2635 | |
@@ -2654,7 +2668,7 b' class InteractiveShell(SingletonConfigurable):' | |||
|
2654 | 2668 | # raised in user code. It would be nice if there were |
|
2655 | 2669 | # versions of run_cell that did raise, so |
|
2656 | 2670 | # we could catch the errors. |
|
2657 |
self.run_cell(cell, silent=True, shell_futures= |
|
|
2671 | self.run_cell(cell, silent=True, shell_futures=shell_futures) | |
|
2658 | 2672 | except: |
|
2659 | 2673 | self.showtraceback() |
|
2660 | 2674 | warn('Unknown failure executing file: <%s>' % fname) |
@@ -324,7 +324,7 b' class InteractiveShellApp(Configurable):' | |||
|
324 | 324 | self.log.warn("Unknown error in handling IPythonApp.exec_lines:") |
|
325 | 325 | self.shell.showtraceback() |
|
326 | 326 | |
|
327 | def _exec_file(self, fname): | |
|
327 | def _exec_file(self, fname, shell_futures=False): | |
|
328 | 328 | try: |
|
329 | 329 | full_filename = filefind(fname, [u'.', self.ipython_dir]) |
|
330 | 330 | except IOError as e: |
@@ -346,11 +346,13 b' class InteractiveShellApp(Configurable):' | |||
|
346 | 346 | with preserve_keys(self.shell.user_ns, '__file__'): |
|
347 | 347 | self.shell.user_ns['__file__'] = fname |
|
348 | 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 | 351 | else: |
|
351 | 352 | # default to python, even without extension |
|
352 | 353 | self.shell.safe_execfile(full_filename, |
|
353 |
self.shell.user_ns |
|
|
354 | self.shell.user_ns, | |
|
355 | shell_futures=shell_futures) | |
|
354 | 356 | finally: |
|
355 | 357 | sys.argv = save_argv |
|
356 | 358 | |
@@ -418,7 +420,7 b' class InteractiveShellApp(Configurable):' | |||
|
418 | 420 | elif self.file_to_run: |
|
419 | 421 | fname = self.file_to_run |
|
420 | 422 | try: |
|
421 | self._exec_file(fname) | |
|
423 | self._exec_file(fname, shell_futures=True) | |
|
422 | 424 | except: |
|
423 | 425 | self.log.warn("Error in executing file in user namespace: %s" % |
|
424 | 426 | fname) |
@@ -19,6 +19,11 b' import unittest' | |||
|
19 | 19 | |
|
20 | 20 | from IPython.testing import decorators as dec |
|
21 | 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 | 28 | class TestFileToRun(unittest.TestCase, tt.TempFileMixin): |
|
24 | 29 | """Test the behavior of the file_to_run parameter.""" |
@@ -28,10 +33,7 b' class TestFileToRun(unittest.TestCase, tt.TempFileMixin):' | |||
|
28 | 33 | src = "print(__file__)\n" |
|
29 | 34 | self.mktmp(src) |
|
30 | 35 | |
|
31 | if dec.module_not_available('sqlite3'): | |
|
32 | err = 'WARNING: IPython History requires SQLite, your history will not be saved\n' | |
|
33 | else: | |
|
34 | err = None | |
|
36 | err = SQLITE_NOT_AVAILABLE_ERROR if sqlite_err_maybe else None | |
|
35 | 37 | tt.ipexec_validate(self.fname, self.fname, err) |
|
36 | 38 | |
|
37 | 39 | def test_ipy_script_file_attribute(self): |
@@ -39,11 +41,24 b' class TestFileToRun(unittest.TestCase, tt.TempFileMixin):' | |||
|
39 | 41 | src = "print(__file__)\n" |
|
40 | 42 | self.mktmp(src, ext='.ipy') |
|
41 | 43 | |
|
42 | if dec.module_not_available('sqlite3'): | |
|
43 | err = 'WARNING: IPython History requires SQLite, your history will not be saved\n' | |
|
44 | else: | |
|
45 | err = None | |
|
44 | err = SQLITE_NOT_AVAILABLE_ERROR if sqlite_err_maybe else None | |
|
46 | 45 | tt.ipexec_validate(self.fname, self.fname, err) |
|
47 | 46 | |
|
48 | # Ideally we would also test that `__file__` is not set in the | |
|
49 | # interactive namespace after running `ipython -i <file>`. | |
|
47 | def test_py_script_file_attribute_interactively(self): | |
|
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 | 178 | return ipython_cmd |
|
179 | 179 | |
|
180 | def ipexec(fname, options=None): | |
|
180 | def ipexec(fname, options=None, commands=()): | |
|
181 | 181 | """Utility to call 'ipython filename'. |
|
182 | 182 | |
|
183 | 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 | 193 | options : optional, list |
|
194 | 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 | 199 | Returns |
|
197 | 200 | ------- |
|
198 | 201 | (stdout, stderr) of ipython subprocess. |
@@ -215,8 +218,8 b' def ipexec(fname, options=None):' | |||
|
215 | 218 | full_cmd = ipython_cmd + cmdargs + [full_fname] |
|
216 | 219 | env = os.environ.copy() |
|
217 | 220 | env.pop('PYTHONWARNINGS', None) # Avoid extraneous warnings appearing on stderr |
|
218 | p = Popen(full_cmd, stdout=PIPE, stderr=PIPE, env=env) | |
|
219 | out, err = p.communicate() | |
|
221 | p = Popen(full_cmd, stdout=PIPE, stderr=PIPE, stdin=PIPE, env=env) | |
|
222 | out, err = p.communicate(input=py3compat.str_to_bytes('\n'.join(commands)) or None) | |
|
220 | 223 | out, err = py3compat.bytes_to_str(out), py3compat.bytes_to_str(err) |
|
221 | 224 | # `import readline` causes 'ESC[?1034h' to be output sometimes, |
|
222 | 225 | # so strip that out before doing comparisons |
@@ -226,7 +229,7 b' def ipexec(fname, options=None):' | |||
|
226 | 229 | |
|
227 | 230 | |
|
228 | 231 | def ipexec_validate(fname, expected_out, expected_err='', |
|
229 | options=None): | |
|
232 | options=None, commands=()): | |
|
230 | 233 | """Utility to call 'ipython filename' and validate output/error. |
|
231 | 234 | |
|
232 | 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 | 258 | import nose.tools as nt |
|
256 | 259 | |
|
257 | out, err = ipexec(fname, options) | |
|
260 | out, err = ipexec(fname, options, commands) | |
|
258 | 261 | #print 'OUT', out # dbg |
|
259 | 262 | #print 'ERR', err # dbg |
|
260 | 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 | 101 | getcwd = os.getcwd |
|
102 | 102 | |
|
103 | 103 | MethodType = types.MethodType |
|
104 | ||
|
105 | def execfile(fname, glob, loc=None): | |
|
104 | ||
|
105 | def execfile(fname, glob, loc=None, compiler=None): | |
|
106 | 106 | loc = loc if (loc is not None) else glob |
|
107 | 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 | 111 | # Refactor print statements in doctests. |
|
111 | 112 | _print_statement_re = re.compile(r"\bprint (?P<expr>.*)$", re.MULTILINE) |
@@ -185,7 +186,7 b' else:' | |||
|
185 | 186 | return s.format(u='u') |
|
186 | 187 | |
|
187 | 188 | if sys.platform == 'win32': |
|
188 | def execfile(fname, glob=None, loc=None): | |
|
189 | def execfile(fname, glob=None, loc=None, compiler=None): | |
|
189 | 190 | loc = loc if (loc is not None) else glob |
|
190 | 191 | # The rstrip() is necessary b/c trailing whitespace in files will |
|
191 | 192 | # cause an IndentationError in Python 2.6 (this was fixed in 2.7, |
@@ -197,14 +198,21 b' else:' | |||
|
197 | 198 | filename = unicode_to_str(fname) |
|
198 | 199 | else: |
|
199 | 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 | 204 | else: |
|
202 |
def execfile(fname, |
|
|
205 | def execfile(fname, glob=None, loc=None, compiler=None): | |
|
203 | 206 | if isinstance(fname, unicode): |
|
204 | 207 | filename = fname.encode(sys.getfilesystemencoding()) |
|
205 | 208 | else: |
|
206 | 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 | 218 | def annotate(**kwargs): |
General Comments 0
You need to be logged in to leave comments.
Login now