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