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