##// END OF EJS Templates
Merge pull request #6436 from thomasballinger/fix-6430...
Thomas Kluyver -
r18549:f1dc401d merge
parent child Browse files
Show More
@@ -2556,10 +2556,16 b' class InteractiveShell(SingletonConfigurable):'
2556 silenced for zero status, as it is so common).
2556 silenced for zero status, as it is so common).
2557 raise_exceptions : bool (False)
2557 raise_exceptions : bool (False)
2558 If True raise exceptions everywhere. Meant for testing.
2558 If True raise exceptions everywhere. Meant for testing.
2559 shell_futures : bool (False)
2560 If True, the code will share future statements with the interactive
2561 shell. It will both be affected by previous __future__ imports, and
2562 any __future__ imports in the code will affect the shell. If False,
2563 __future__ imports are not shared in either direction.
2559
2564
2560 """
2565 """
2561 kw.setdefault('exit_ignore', False)
2566 kw.setdefault('exit_ignore', False)
2562 kw.setdefault('raise_exceptions', False)
2567 kw.setdefault('raise_exceptions', False)
2568 kw.setdefault('shell_futures', False)
2563
2569
2564 fname = os.path.abspath(os.path.expanduser(fname))
2570 fname = os.path.abspath(os.path.expanduser(fname))
2565
2571
@@ -2578,7 +2584,10 b' class InteractiveShell(SingletonConfigurable):'
2578
2584
2579 with prepended_to_syspath(dname):
2585 with prepended_to_syspath(dname):
2580 try:
2586 try:
2581 py3compat.execfile(fname,*where)
2587 glob, loc = (where + (None, ))[:2]
2588 py3compat.execfile(
2589 fname, glob, loc,
2590 self.compile if kw['shell_futures'] else None)
2582 except SystemExit as status:
2591 except SystemExit as status:
2583 # If the call was made with 0 or None exit status (sys.exit(0)
2592 # If the call was made with 0 or None exit status (sys.exit(0)
2584 # or sys.exit() ), don't bother showing a traceback, as both of
2593 # or sys.exit() ), don't bother showing a traceback, as both of
@@ -2599,7 +2608,7 b' class InteractiveShell(SingletonConfigurable):'
2599 # tb offset is 2 because we wrap execfile
2608 # tb offset is 2 because we wrap execfile
2600 self.showtraceback(tb_offset=2)
2609 self.showtraceback(tb_offset=2)
2601
2610
2602 def safe_execfile_ipy(self, fname):
2611 def safe_execfile_ipy(self, fname, shell_futures=False):
2603 """Like safe_execfile, but for .ipy or .ipynb files with IPython syntax.
2612 """Like safe_execfile, but for .ipy or .ipynb files with IPython syntax.
2604
2613
2605 Parameters
2614 Parameters
@@ -2607,6 +2616,11 b' class InteractiveShell(SingletonConfigurable):'
2607 fname : str
2616 fname : str
2608 The name of the file to execute. The filename must have a
2617 The name of the file to execute. The filename must have a
2609 .ipy or .ipynb extension.
2618 .ipy or .ipynb extension.
2619 shell_futures : bool (False)
2620 If True, the code will share future statements with the interactive
2621 shell. It will both be affected by previous __future__ imports, and
2622 any __future__ imports in the code will affect the shell. If False,
2623 __future__ imports are not shared in either direction.
2610 """
2624 """
2611 fname = os.path.abspath(os.path.expanduser(fname))
2625 fname = os.path.abspath(os.path.expanduser(fname))
2612
2626
@@ -2645,7 +2659,7 b' class InteractiveShell(SingletonConfigurable):'
2645 # raised in user code. It would be nice if there were
2659 # raised in user code. It would be nice if there were
2646 # versions of run_cell that did raise, so
2660 # versions of run_cell that did raise, so
2647 # we could catch the errors.
2661 # we could catch the errors.
2648 self.run_cell(cell, silent=True, shell_futures=False)
2662 self.run_cell(cell, silent=True, shell_futures=shell_futures)
2649 except:
2663 except:
2650 self.showtraceback()
2664 self.showtraceback()
2651 warn('Unknown failure executing file: <%s>' % fname)
2665 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 scripttext = builtin_mod.open(fname).read()+ '\n'
191 scripttext = builtin_mod.open(fname).read()+ '\n'
191 # compile converts unicode filename to str assuming
192 # compile converts unicode filename to str assuming
@@ -194,14 +195,21 b' else:'
194 filename = unicode_to_str(fname)
195 filename = unicode_to_str(fname)
195 else:
196 else:
196 filename = fname
197 filename = fname
197 exec(compile(scripttext, filename, 'exec'), glob, loc)
198 compiler = compiler or compile
199 exec(compiler(scripttext, filename, 'exec'), glob, loc)
200
198 else:
201 else:
199 def execfile(fname, *where):
202 def execfile(fname, glob=None, loc=None, compiler=None):
200 if isinstance(fname, unicode):
203 if isinstance(fname, unicode):
201 filename = fname.encode(sys.getfilesystemencoding())
204 filename = fname.encode(sys.getfilesystemencoding())
202 else:
205 else:
203 filename = fname
206 filename = fname
204 builtin_mod.execfile(filename, *where)
207 where = [ns for ns in [glob, loc] if ns is not None]
208 if compiler is None:
209 builtin_mod.execfile(filename, *where)
210 else:
211 scripttext = builtin_mod.open(fname).read().rstrip() + '\n'
212 exec(compiler(scripttext, filename, 'exec'), glob, loc)
205
213
206
214
207 def annotate(**kwargs):
215 def annotate(**kwargs):
General Comments 0
You need to be logged in to leave comments. Login now