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= |
|
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 |
@@ -102,10 +102,11 b' if sys.version_info[0] >= 3:' | |||||
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, |
|
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 | |
|
210 | where = [ns for ns in [glob, loc] if ns is not None] | |||
|
211 | if compiler is None: | |||
207 | builtin_mod.execfile(filename, *where) |
|
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