##// END OF EJS Templates
Fix test mimebundle paging...
Matthias Bussonnier -
Show More
@@ -1,149 +1,150 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
24 import sys
23 import sys
25
24
26 # our own
25 # our own
27 from . import tools
26 from . import tools
28
27
29 from IPython.core import page
28 from IPython.core import page
30 from IPython.utils import io
29 from IPython.utils import io
31 from IPython.utils import py3compat
30 from IPython.utils import py3compat
32 from IPython.utils.py3compat import builtin_mod
31 from IPython.utils.py3compat import builtin_mod
33 from IPython.terminal.interactiveshell import TerminalInteractiveShell
32 from IPython.terminal.interactiveshell import TerminalInteractiveShell
34
33
35 #-----------------------------------------------------------------------------
34 #-----------------------------------------------------------------------------
36 # Functions
35 # Functions
37 #-----------------------------------------------------------------------------
36 #-----------------------------------------------------------------------------
38
37
39 class StreamProxy(io.IOStream):
38 class StreamProxy(io.IOStream):
40 """Proxy for sys.stdout/err. This will request the stream *at call time*
39 """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.
40 allowing for nose's Capture plugin's redirection of sys.stdout/err.
42
41
43 Parameters
42 Parameters
44 ----------
43 ----------
45 name : str
44 name : str
46 The name of the stream. This will be requested anew at every call
45 The name of the stream. This will be requested anew at every call
47 """
46 """
48
47
49 def __init__(self, name):
48 def __init__(self, name):
50 self.name=name
49 self.name=name
51
50
52 @property
51 @property
53 def stream(self):
52 def stream(self):
54 return getattr(sys, self.name)
53 return getattr(sys, self.name)
55
54
56 def flush(self):
55 def flush(self):
57 self.stream.flush()
56 self.stream.flush()
58
57
59
58
60 def get_ipython():
59 def get_ipython():
61 # This will get replaced by the real thing once we start IPython below
60 # This will get replaced by the real thing once we start IPython below
62 return start_ipython()
61 return start_ipython()
63
62
64
63
65 # A couple of methods to override those in the running IPython to interact
64 # A couple of methods to override those in the running IPython to interact
66 # better with doctest (doctest captures on raw stdout, so we need to direct
65 # better with doctest (doctest captures on raw stdout, so we need to direct
67 # various types of output there otherwise it will miss them).
66 # various types of output there otherwise it will miss them).
68
67
69 def xsys(self, cmd):
68 def xsys(self, cmd):
70 """Replace the default system call with a capturing one for doctest.
69 """Replace the default system call with a capturing one for doctest.
71 """
70 """
72 # We use getoutput, but we need to strip it because pexpect captures
71 # We use getoutput, but we need to strip it because pexpect captures
73 # the trailing newline differently from commands.getoutput
72 # the trailing newline differently from commands.getoutput
74 print(self.getoutput(cmd, split=False, depth=1).rstrip(), end='', file=sys.stdout)
73 print(self.getoutput(cmd, split=False, depth=1).rstrip(), end='', file=sys.stdout)
75 sys.stdout.flush()
74 sys.stdout.flush()
76
75
77
76
78 def _showtraceback(self, etype, evalue, stb):
77 def _showtraceback(self, etype, evalue, stb):
79 """Print the traceback purely on stdout for doctest to capture it.
78 """Print the traceback purely on stdout for doctest to capture it.
80 """
79 """
81 print(self.InteractiveTB.stb2text(stb), file=sys.stdout)
80 print(self.InteractiveTB.stb2text(stb), file=sys.stdout)
82
81
83
82
84 def start_ipython():
83 def start_ipython():
85 """Start a global IPython shell, which we need for IPython-specific syntax.
84 """Start a global IPython shell, which we need for IPython-specific syntax.
86 """
85 """
87 global get_ipython
86 global get_ipython
88
87
89 # This function should only ever run once!
88 # This function should only ever run once!
90 if hasattr(start_ipython, 'already_called'):
89 if hasattr(start_ipython, 'already_called'):
91 return
90 return
92 start_ipython.already_called = True
91 start_ipython.already_called = True
93
92
94 # Store certain global objects that IPython modifies
93 # Store certain global objects that IPython modifies
95 _displayhook = sys.displayhook
94 _displayhook = sys.displayhook
96 _excepthook = sys.excepthook
95 _excepthook = sys.excepthook
97 _main = sys.modules.get('__main__')
96 _main = sys.modules.get('__main__')
98
97
99 # Create custom argv and namespaces for our IPython to be test-friendly
98 # Create custom argv and namespaces for our IPython to be test-friendly
100 config = tools.default_config()
99 config = tools.default_config()
101
100
102 # Create and initialize our test-friendly IPython instance.
101 # Create and initialize our test-friendly IPython instance.
103 shell = TerminalInteractiveShell.instance(config=config,
102 shell = TerminalInteractiveShell.instance(config=config,
104 )
103 )
105
104
106 # A few more tweaks needed for playing nicely with doctests...
105 # A few more tweaks needed for playing nicely with doctests...
107
106
108 # remove history file
107 # remove history file
109 shell.tempfiles.append(config.HistoryManager.hist_file)
108 shell.tempfiles.append(config.HistoryManager.hist_file)
110
109
111 # These traps are normally only active for interactive use, set them
110 # These traps are normally only active for interactive use, set them
112 # permanently since we'll be mocking interactive sessions.
111 # permanently since we'll be mocking interactive sessions.
113 shell.builtin_trap.activate()
112 shell.builtin_trap.activate()
114
113
115 # Modify the IPython system call with one that uses getoutput, so that we
114 # Modify the IPython system call with one that uses getoutput, so that we
116 # can capture subcommands and print them to Python's stdout, otherwise the
115 # can capture subcommands and print them to Python's stdout, otherwise the
117 # doctest machinery would miss them.
116 # doctest machinery would miss them.
118 shell.system = py3compat.MethodType(xsys, shell)
117 shell.system = py3compat.MethodType(xsys, shell)
119
118
120 shell._showtraceback = py3compat.MethodType(_showtraceback, shell)
119 shell._showtraceback = py3compat.MethodType(_showtraceback, shell)
121
120
122 # IPython is ready, now clean up some global state...
121 # IPython is ready, now clean up some global state...
123
122
124 # Deactivate the various python system hooks added by ipython for
123 # Deactivate the various python system hooks added by ipython for
125 # interactive convenience so we don't confuse the doctest system
124 # interactive convenience so we don't confuse the doctest system
126 sys.modules['__main__'] = _main
125 sys.modules['__main__'] = _main
127 sys.displayhook = _displayhook
126 sys.displayhook = _displayhook
128 sys.excepthook = _excepthook
127 sys.excepthook = _excepthook
129
128
130 # So that ipython magics and aliases can be doctested (they work by making
129 # So that ipython magics and aliases can be doctested (they work by making
131 # a call into a global _ip object). Also make the top-level get_ipython
130 # a call into a global _ip object). Also make the top-level get_ipython
132 # now return this without recursively calling here again.
131 # now return this without recursively calling here again.
133 _ip = shell
132 _ip = shell
134 get_ipython = _ip.get_ipython
133 get_ipython = _ip.get_ipython
135 builtin_mod._ip = _ip
134 builtin_mod._ip = _ip
136 builtin_mod.get_ipython = get_ipython
135 builtin_mod.get_ipython = get_ipython
137
136
138 # To avoid extra IPython messages during testing, suppress io.stdout/stderr
137 # To avoid extra IPython messages during testing, suppress io.stdout/stderr
139 io.stdout = StreamProxy('stdout')
138 io.stdout = StreamProxy('stdout')
140 io.stderr = StreamProxy('stderr')
139 io.stderr = StreamProxy('stderr')
141
140
142 # Override paging, so we don't require user interaction during the tests.
141 # Override paging, so we don't require user interaction during the tests.
143 def nopage(strng, start=0, screen_lines=0, pager_cmd=None):
142 def nopage(strng, start=0, screen_lines=0, pager_cmd=None):
143 if isinstance(strng, dict):
144 strng = strng.get('text/plain', '')
144 print(strng)
145 print(strng)
145
146
146 page.orig_page = page.pager_page
147 page.orig_page = page.pager_page
147 page.pager_page = nopage
148 page.pager_page = nopage
148
149
149 return _ip
150 return _ip
General Comments 0
You need to be logged in to leave comments. Login now