##// END OF EJS Templates
Disable the pager for the test suite....
Thomas Kluyver -
Show More
@@ -1,19 +1,20 b''
1 1 #-----------------------------------------------------------------------------
2 2 # Copyright (C) 2010 The IPython Development Team.
3 3 #
4 4 # Distributed under the terms of the BSD License.
5 5 #
6 6 # The full license is in the file COPYING.txt, distributed with this software.
7 7 #-----------------------------------------------------------------------------
8 8 import io
9 9
10 # N.B. For the test suite, page.page is overridden (see IPython.testing.globalipapp)
10 11 from IPython.core import page
11 12
12 13 def test_detect_screen_size():
13 14 """Simple smoketest for page._detect_screen_size."""
14 15 try:
15 16 page._detect_screen_size(True, 25)
16 17 except (TypeError, io.UnsupportedOperation):
17 18 # This can happen in the test suite, because stdout may not have a
18 19 # fileno.
19 20 pass
@@ -1,232 +1,240 b''
1 1 """Global IPython app to support test running.
2 2
3 3 We must start our own ipython object and heavily muck with it so that all the
4 4 modifications IPython makes to system behavior don't send the doctest machinery
5 5 into a fit. This code should be considered a gross hack, but it gets the job
6 6 done.
7 7 """
8 8 from __future__ import absolute_import
9 9 from __future__ import print_function
10 10
11 11 #-----------------------------------------------------------------------------
12 12 # Copyright (C) 2009-2010 The IPython Development Team
13 13 #
14 14 # Distributed under the terms of the BSD License. The full license is in
15 15 # the file COPYING, distributed as part of this software.
16 16 #-----------------------------------------------------------------------------
17 17
18 18 #-----------------------------------------------------------------------------
19 19 # Imports
20 20 #-----------------------------------------------------------------------------
21 21
22 22 # stdlib
23 23 import __builtin__ as builtin_mod
24 24 import os
25 25 import sys
26 26
27 27 # our own
28 28 from . import tools
29 29
30 from IPython.core import page
30 31 from IPython.utils import io
31 32 from IPython.utils import py3compat
32 33 from IPython.frontend.terminal.interactiveshell import TerminalInteractiveShell
33 34
34 35 #-----------------------------------------------------------------------------
35 36 # Functions
36 37 #-----------------------------------------------------------------------------
37 38
38 39 class StreamProxy(io.IOStream):
39 40 """Proxy for sys.stdout/err. This will request the stream *at call time*
40 41 allowing for nose's Capture plugin's redirection of sys.stdout/err.
41 42
42 43 Parameters
43 44 ----------
44 45 name : str
45 46 The name of the stream. This will be requested anew at every call
46 47 """
47 48
48 49 def __init__(self, name):
49 50 self.name=name
50 51
51 52 @property
52 53 def stream(self):
53 54 return getattr(sys, self.name)
54 55
55 56 def flush(self):
56 57 self.stream.flush()
57 58
58 59 # Hack to modify the %run command so we can sync the user's namespace with the
59 60 # test globals. Once we move over to a clean magic system, this will be done
60 61 # with much less ugliness.
61 62
62 63 class py_file_finder(object):
63 64 def __init__(self,test_filename):
64 65 self.test_filename = test_filename
65 66
66 67 def __call__(self,name,win32=False):
67 68 from IPython.utils.path import get_py_filename
68 69 try:
69 70 return get_py_filename(name,win32=win32)
70 71 except IOError:
71 72 test_dir = os.path.dirname(self.test_filename)
72 73 new_path = os.path.join(test_dir,name)
73 74 return get_py_filename(new_path,win32=win32)
74 75
75 76
76 77 def _run_ns_sync(self,arg_s,runner=None):
77 78 """Modified version of %run that syncs testing namespaces.
78 79
79 80 This is strictly needed for running doctests that call %run.
80 81 """
81 82 #print('in run_ns_sync', arg_s, file=sys.stderr) # dbg
82 83 finder = py_file_finder(arg_s)
83 84 return get_ipython().magic_run_ori(arg_s, runner, finder)
84 85
85 86
86 87 class ipnsdict(dict):
87 88 """A special subclass of dict for use as an IPython namespace in doctests.
88 89
89 90 This subclass adds a simple checkpointing capability so that when testing
90 91 machinery clears it (we use it as the test execution context), it doesn't
91 92 get completely destroyed.
92 93
93 94 In addition, it can handle the presence of the '_' key in a special manner,
94 95 which is needed because of how Python's doctest machinery operates with
95 96 '_'. See constructor and :meth:`update` for details.
96 97 """
97 98
98 99 def __init__(self,*a):
99 100 dict.__init__(self,*a)
100 101 self._savedict = {}
101 102 # If this flag is True, the .update() method will unconditionally
102 103 # remove a key named '_'. This is so that such a dict can be used as a
103 104 # namespace in doctests that call '_'.
104 105 self.protect_underscore = False
105 106
106 107 def clear(self):
107 108 dict.clear(self)
108 109 self.update(self._savedict)
109 110
110 111 def _checkpoint(self):
111 112 self._savedict.clear()
112 113 self._savedict.update(self)
113 114
114 115 def update(self,other):
115 116 self._checkpoint()
116 117 dict.update(self,other)
117 118
118 119 if self.protect_underscore:
119 120 # If '_' is in the namespace, python won't set it when executing
120 121 # code *in doctests*, and we have multiple doctests that use '_'.
121 122 # So we ensure that the namespace is always 'clean' of it before
122 123 # it's used for test code execution.
123 124 # This flag is only turned on by the doctest machinery, so that
124 125 # normal test code can assume the _ key is updated like any other
125 126 # key and can test for its presence after cell executions.
126 127 self.pop('_', None)
127 128
128 129 # The builtins namespace must *always* be the real __builtin__ module,
129 130 # else weird stuff happens. The main ipython code does have provisions
130 131 # to ensure this after %run, but since in this class we do some
131 132 # aggressive low-level cleaning of the execution namespace, we need to
132 133 # correct for that ourselves, to ensure consitency with the 'real'
133 134 # ipython.
134 135 self['__builtins__'] = builtin_mod
135 136
136 137 def __delitem__(self, key):
137 138 """Part of the test suite checks that we can release all
138 139 references to an object. So we need to make sure that we're not
139 140 keeping a reference in _savedict."""
140 141 dict.__delitem__(self, key)
141 142 try:
142 143 del self._savedict[key]
143 144 except KeyError:
144 145 pass
145 146
146 147
147 148 def get_ipython():
148 149 # This will get replaced by the real thing once we start IPython below
149 150 return start_ipython()
150 151
151 152
152 153 # A couple of methods to override those in the running IPython to interact
153 154 # better with doctest (doctest captures on raw stdout, so we need to direct
154 155 # various types of output there otherwise it will miss them).
155 156
156 157 def xsys(self, cmd):
157 158 """Replace the default system call with a capturing one for doctest.
158 159 """
159 160 # We use getoutput, but we need to strip it because pexpect captures
160 161 # the trailing newline differently from commands.getoutput
161 162 print(self.getoutput(cmd, split=False).rstrip(), end='', file=sys.stdout)
162 163 sys.stdout.flush()
163 164
164 165
165 166 def _showtraceback(self, etype, evalue, stb):
166 167 """Print the traceback purely on stdout for doctest to capture it.
167 168 """
168 169 print(self.InteractiveTB.stb2text(stb), file=sys.stdout)
169 170
170 171
171 172 def start_ipython():
172 173 """Start a global IPython shell, which we need for IPython-specific syntax.
173 174 """
174 175 global get_ipython
175 176
176 177 # This function should only ever run once!
177 178 if hasattr(start_ipython, 'already_called'):
178 179 return
179 180 start_ipython.already_called = True
180 181
181 182 # Store certain global objects that IPython modifies
182 183 _displayhook = sys.displayhook
183 184 _excepthook = sys.excepthook
184 185 _main = sys.modules.get('__main__')
185 186
186 187 # Create custom argv and namespaces for our IPython to be test-friendly
187 188 config = tools.default_config()
188 189
189 190 # Create and initialize our test-friendly IPython instance.
190 191 shell = TerminalInteractiveShell.instance(config=config,
191 192 user_ns=ipnsdict(),
192 193 user_global_ns={}
193 194 )
194 195
195 196 # A few more tweaks needed for playing nicely with doctests...
196 197
197 198 # remove history file
198 199 shell.tempfiles.append(config.HistoryManager.hist_file)
199 200
200 201 # These traps are normally only active for interactive use, set them
201 202 # permanently since we'll be mocking interactive sessions.
202 203 shell.builtin_trap.activate()
203 204
204 205 # Modify the IPython system call with one that uses getoutput, so that we
205 206 # can capture subcommands and print them to Python's stdout, otherwise the
206 207 # doctest machinery would miss them.
207 208 shell.system = py3compat.MethodType(xsys, shell)
208 209
209 210
210 211 shell._showtraceback = py3compat.MethodType(_showtraceback, shell)
211 212
212 213 # IPython is ready, now clean up some global state...
213 214
214 215 # Deactivate the various python system hooks added by ipython for
215 216 # interactive convenience so we don't confuse the doctest system
216 217 sys.modules['__main__'] = _main
217 218 sys.displayhook = _displayhook
218 219 sys.excepthook = _excepthook
219 220
220 221 # So that ipython magics and aliases can be doctested (they work by making
221 222 # a call into a global _ip object). Also make the top-level get_ipython
222 223 # now return this without recursively calling here again.
223 224 _ip = shell
224 225 get_ipython = _ip.get_ipython
225 226 builtin_mod._ip = _ip
226 227 builtin_mod.get_ipython = get_ipython
227 228
228 229 # To avoid extra IPython messages during testing, suppress io.stdout/stderr
229 230 io.stdout = StreamProxy('stdout')
230 231 io.stderr = StreamProxy('stderr')
232
233 # Override paging, so we don't require user interaction during the tests.
234 def nopage(strng, start=0, screen_lines=0, pager_cmd=None):
235 print(strng)
236
237 page.orig_page = page.page
238 page.page = nopage
231 239
232 240 return _ip
General Comments 0
You need to be logged in to leave comments. Login now