##// END OF EJS Templates
Merge pull request #8559 from Carreau/more-unused...
Thomas Kluyver -
r21481:d4181dd4 merge
parent child Browse files
Show More
@@ -1,176 +1,149 b''
1 """Global IPython app to support test running.
1 """Global IPython app to support test running.
2
2
3 We must start our own ipython object and heavily muck with it so that all the
3 We must start our own ipython object and heavily muck with it so that all the
4 modifications IPython makes to system behavior don't send the doctest machinery
4 modifications IPython makes to system behavior don't send the doctest machinery
5 into a fit. This code should be considered a gross hack, but it gets the job
5 into a fit. This code should be considered a gross hack, but it gets the job
6 done.
6 done.
7 """
7 """
8 from __future__ import absolute_import
8 from __future__ import absolute_import
9 from __future__ import print_function
9 from __future__ import print_function
10
10
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12 # Copyright (C) 2009-2011 The IPython Development Team
12 # Copyright (C) 2009-2011 The IPython Development Team
13 #
13 #
14 # Distributed under the terms of the BSD License. The full license is in
14 # Distributed under the terms of the BSD License. The full license is in
15 # the file COPYING, distributed as part of this software.
15 # the file COPYING, distributed as part of this software.
16 #-----------------------------------------------------------------------------
16 #-----------------------------------------------------------------------------
17
17
18 #-----------------------------------------------------------------------------
18 #-----------------------------------------------------------------------------
19 # Imports
19 # Imports
20 #-----------------------------------------------------------------------------
20 #-----------------------------------------------------------------------------
21
21
22 # stdlib
22 # stdlib
23 import os
23 import os
24 import sys
24 import sys
25
25
26 # our own
26 # our own
27 from . import tools
27 from . import tools
28
28
29 from IPython.core import page
29 from IPython.core import page
30 from IPython.utils import io
30 from IPython.utils import io
31 from IPython.utils import py3compat
31 from IPython.utils import py3compat
32 from IPython.utils.py3compat import builtin_mod
32 from IPython.utils.py3compat import builtin_mod
33 from IPython.terminal.interactiveshell import TerminalInteractiveShell
33 from IPython.terminal.interactiveshell import TerminalInteractiveShell
34
34
35 #-----------------------------------------------------------------------------
35 #-----------------------------------------------------------------------------
36 # Functions
36 # Functions
37 #-----------------------------------------------------------------------------
37 #-----------------------------------------------------------------------------
38
38
39 class StreamProxy(io.IOStream):
39 class StreamProxy(io.IOStream):
40 """Proxy for sys.stdout/err. This will request the stream *at call time*
40 """Proxy for sys.stdout/err. This will request the stream *at call time*
41 allowing for nose's Capture plugin's redirection of sys.stdout/err.
41 allowing for nose's Capture plugin's redirection of sys.stdout/err.
42
42
43 Parameters
43 Parameters
44 ----------
44 ----------
45 name : str
45 name : str
46 The name of the stream. This will be requested anew at every call
46 The name of the stream. This will be requested anew at every call
47 """
47 """
48
48
49 def __init__(self, name):
49 def __init__(self, name):
50 self.name=name
50 self.name=name
51
51
52 @property
52 @property
53 def stream(self):
53 def stream(self):
54 return getattr(sys, self.name)
54 return getattr(sys, self.name)
55
55
56 def flush(self):
56 def flush(self):
57 self.stream.flush()
57 self.stream.flush()
58
58
59 # Hack to modify the %run command so we can sync the user's namespace with the
60 # test globals. Once we move over to a clean magic system, this will be done
61 # with much less ugliness.
62
63 class py_file_finder(object):
64 def __init__(self,test_filename):
65 self.test_filename = test_filename
66
67 def __call__(self,name,win32=False):
68 from IPython.utils.path import get_py_filename
69 try:
70 return get_py_filename(name,win32=win32)
71 except IOError:
72 test_dir = os.path.dirname(self.test_filename)
73 new_path = os.path.join(test_dir,name)
74 return get_py_filename(new_path,win32=win32)
75
76
77 def _run_ns_sync(self,arg_s,runner=None):
78 """Modified version of %run that syncs testing namespaces.
79
80 This is strictly needed for running doctests that call %run.
81 """
82 #print('in run_ns_sync', arg_s, file=sys.stderr) # dbg
83 finder = py_file_finder(arg_s)
84 return get_ipython().magic_run_ori(arg_s, runner, finder)
85
86
59
87 def get_ipython():
60 def get_ipython():
88 # This will get replaced by the real thing once we start IPython below
61 # This will get replaced by the real thing once we start IPython below
89 return start_ipython()
62 return start_ipython()
90
63
91
64
92 # A couple of methods to override those in the running IPython to interact
65 # A couple of methods to override those in the running IPython to interact
93 # better with doctest (doctest captures on raw stdout, so we need to direct
66 # better with doctest (doctest captures on raw stdout, so we need to direct
94 # various types of output there otherwise it will miss them).
67 # various types of output there otherwise it will miss them).
95
68
96 def xsys(self, cmd):
69 def xsys(self, cmd):
97 """Replace the default system call with a capturing one for doctest.
70 """Replace the default system call with a capturing one for doctest.
98 """
71 """
99 # We use getoutput, but we need to strip it because pexpect captures
72 # We use getoutput, but we need to strip it because pexpect captures
100 # the trailing newline differently from commands.getoutput
73 # the trailing newline differently from commands.getoutput
101 print(self.getoutput(cmd, split=False, depth=1).rstrip(), end='', file=sys.stdout)
74 print(self.getoutput(cmd, split=False, depth=1).rstrip(), end='', file=sys.stdout)
102 sys.stdout.flush()
75 sys.stdout.flush()
103
76
104
77
105 def _showtraceback(self, etype, evalue, stb):
78 def _showtraceback(self, etype, evalue, stb):
106 """Print the traceback purely on stdout for doctest to capture it.
79 """Print the traceback purely on stdout for doctest to capture it.
107 """
80 """
108 print(self.InteractiveTB.stb2text(stb), file=sys.stdout)
81 print(self.InteractiveTB.stb2text(stb), file=sys.stdout)
109
82
110
83
111 def start_ipython():
84 def start_ipython():
112 """Start a global IPython shell, which we need for IPython-specific syntax.
85 """Start a global IPython shell, which we need for IPython-specific syntax.
113 """
86 """
114 global get_ipython
87 global get_ipython
115
88
116 # This function should only ever run once!
89 # This function should only ever run once!
117 if hasattr(start_ipython, 'already_called'):
90 if hasattr(start_ipython, 'already_called'):
118 return
91 return
119 start_ipython.already_called = True
92 start_ipython.already_called = True
120
93
121 # Store certain global objects that IPython modifies
94 # Store certain global objects that IPython modifies
122 _displayhook = sys.displayhook
95 _displayhook = sys.displayhook
123 _excepthook = sys.excepthook
96 _excepthook = sys.excepthook
124 _main = sys.modules.get('__main__')
97 _main = sys.modules.get('__main__')
125
98
126 # Create custom argv and namespaces for our IPython to be test-friendly
99 # Create custom argv and namespaces for our IPython to be test-friendly
127 config = tools.default_config()
100 config = tools.default_config()
128
101
129 # Create and initialize our test-friendly IPython instance.
102 # Create and initialize our test-friendly IPython instance.
130 shell = TerminalInteractiveShell.instance(config=config,
103 shell = TerminalInteractiveShell.instance(config=config,
131 )
104 )
132
105
133 # A few more tweaks needed for playing nicely with doctests...
106 # A few more tweaks needed for playing nicely with doctests...
134
107
135 # remove history file
108 # remove history file
136 shell.tempfiles.append(config.HistoryManager.hist_file)
109 shell.tempfiles.append(config.HistoryManager.hist_file)
137
110
138 # These traps are normally only active for interactive use, set them
111 # These traps are normally only active for interactive use, set them
139 # permanently since we'll be mocking interactive sessions.
112 # permanently since we'll be mocking interactive sessions.
140 shell.builtin_trap.activate()
113 shell.builtin_trap.activate()
141
114
142 # Modify the IPython system call with one that uses getoutput, so that we
115 # Modify the IPython system call with one that uses getoutput, so that we
143 # can capture subcommands and print them to Python's stdout, otherwise the
116 # can capture subcommands and print them to Python's stdout, otherwise the
144 # doctest machinery would miss them.
117 # doctest machinery would miss them.
145 shell.system = py3compat.MethodType(xsys, shell)
118 shell.system = py3compat.MethodType(xsys, shell)
146
119
147 shell._showtraceback = py3compat.MethodType(_showtraceback, shell)
120 shell._showtraceback = py3compat.MethodType(_showtraceback, shell)
148
121
149 # IPython is ready, now clean up some global state...
122 # IPython is ready, now clean up some global state...
150
123
151 # Deactivate the various python system hooks added by ipython for
124 # Deactivate the various python system hooks added by ipython for
152 # interactive convenience so we don't confuse the doctest system
125 # interactive convenience so we don't confuse the doctest system
153 sys.modules['__main__'] = _main
126 sys.modules['__main__'] = _main
154 sys.displayhook = _displayhook
127 sys.displayhook = _displayhook
155 sys.excepthook = _excepthook
128 sys.excepthook = _excepthook
156
129
157 # So that ipython magics and aliases can be doctested (they work by making
130 # So that ipython magics and aliases can be doctested (they work by making
158 # a call into a global _ip object). Also make the top-level get_ipython
131 # a call into a global _ip object). Also make the top-level get_ipython
159 # now return this without recursively calling here again.
132 # now return this without recursively calling here again.
160 _ip = shell
133 _ip = shell
161 get_ipython = _ip.get_ipython
134 get_ipython = _ip.get_ipython
162 builtin_mod._ip = _ip
135 builtin_mod._ip = _ip
163 builtin_mod.get_ipython = get_ipython
136 builtin_mod.get_ipython = get_ipython
164
137
165 # To avoid extra IPython messages during testing, suppress io.stdout/stderr
138 # To avoid extra IPython messages during testing, suppress io.stdout/stderr
166 io.stdout = StreamProxy('stdout')
139 io.stdout = StreamProxy('stdout')
167 io.stderr = StreamProxy('stderr')
140 io.stderr = StreamProxy('stderr')
168
141
169 # Override paging, so we don't require user interaction during the tests.
142 # Override paging, so we don't require user interaction during the tests.
170 def nopage(strng, start=0, screen_lines=0, pager_cmd=None):
143 def nopage(strng, start=0, screen_lines=0, pager_cmd=None):
171 print(strng)
144 print(strng)
172
145
173 page.orig_page = page.pager_page
146 page.orig_page = page.pager_page
174 page.pager_page = nopage
147 page.pager_page = nopage
175
148
176 return _ip
149 return _ip
General Comments 0
You need to be logged in to leave comments. Login now