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