~ibmcharmers/charms/xenial/ibm-cinder-storwize-svc/trunk

« back to all changes in this revision

Viewing changes to .tox/py35/lib/python3.5/site-packages/pip/_vendor/colorama/ansitowin32.py

  • Committer: Ankammarao
  • Date: 2017-03-06 05:11:42 UTC
  • Revision ID: achittet@in.ibm.com-20170306051142-dpg27z4es1k56hfn
Marked tests folder executable

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file.
 
2
import re
 
3
import sys
 
4
import os
 
5
 
 
6
from .ansi import AnsiFore, AnsiBack, AnsiStyle, Style
 
7
from .winterm import WinTerm, WinColor, WinStyle
 
8
from .win32 import windll, winapi_test
 
9
 
 
10
 
 
11
winterm = None
 
12
if windll is not None:
 
13
    winterm = WinTerm()
 
14
 
 
15
 
 
16
def is_stream_closed(stream):
 
17
    return not hasattr(stream, 'closed') or stream.closed
 
18
 
 
19
 
 
20
def is_a_tty(stream):
 
21
    return hasattr(stream, 'isatty') and stream.isatty()
 
22
 
 
23
 
 
24
class StreamWrapper(object):
 
25
    '''
 
26
    Wraps a stream (such as stdout), acting as a transparent proxy for all
 
27
    attribute access apart from method 'write()', which is delegated to our
 
28
    Converter instance.
 
29
    '''
 
30
    def __init__(self, wrapped, converter):
 
31
        # double-underscore everything to prevent clashes with names of
 
32
        # attributes on the wrapped stream object.
 
33
        self.__wrapped = wrapped
 
34
        self.__convertor = converter
 
35
 
 
36
    def __getattr__(self, name):
 
37
        return getattr(self.__wrapped, name)
 
38
 
 
39
    def write(self, text):
 
40
        self.__convertor.write(text)
 
41
 
 
42
 
 
43
class AnsiToWin32(object):
 
44
    '''
 
45
    Implements a 'write()' method which, on Windows, will strip ANSI character
 
46
    sequences from the text, and if outputting to a tty, will convert them into
 
47
    win32 function calls.
 
48
    '''
 
49
    ANSI_CSI_RE = re.compile('\001?\033\[((?:\d|;)*)([a-zA-Z])\002?')     # Control Sequence Introducer
 
50
    ANSI_OSC_RE = re.compile('\001?\033\]((?:.|;)*?)(\x07)\002?')         # Operating System Command
 
51
 
 
52
    def __init__(self, wrapped, convert=None, strip=None, autoreset=False):
 
53
        # The wrapped stream (normally sys.stdout or sys.stderr)
 
54
        self.wrapped = wrapped
 
55
 
 
56
        # should we reset colors to defaults after every .write()
 
57
        self.autoreset = autoreset
 
58
 
 
59
        # create the proxy wrapping our output stream
 
60
        self.stream = StreamWrapper(wrapped, self)
 
61
 
 
62
        on_windows = os.name == 'nt'
 
63
        # We test if the WinAPI works, because even if we are on Windows
 
64
        # we may be using a terminal that doesn't support the WinAPI
 
65
        # (e.g. Cygwin Terminal). In this case it's up to the terminal
 
66
        # to support the ANSI codes.
 
67
        conversion_supported = on_windows and winapi_test()
 
68
 
 
69
        # should we strip ANSI sequences from our output?
 
70
        if strip is None:
 
71
            strip = conversion_supported or (not is_stream_closed(wrapped) and not is_a_tty(wrapped))
 
72
        self.strip = strip
 
73
 
 
74
        # should we should convert ANSI sequences into win32 calls?
 
75
        if convert is None:
 
76
            convert = conversion_supported and not is_stream_closed(wrapped) and is_a_tty(wrapped)
 
77
        self.convert = convert
 
78
 
 
79
        # dict of ansi codes to win32 functions and parameters
 
80
        self.win32_calls = self.get_win32_calls()
 
81
 
 
82
        # are we wrapping stderr?
 
83
        self.on_stderr = self.wrapped is sys.stderr
 
84
 
 
85
    def should_wrap(self):
 
86
        '''
 
87
        True if this class is actually needed. If false, then the output
 
88
        stream will not be affected, nor will win32 calls be issued, so
 
89
        wrapping stdout is not actually required. This will generally be
 
90
        False on non-Windows platforms, unless optional functionality like
 
91
        autoreset has been requested using kwargs to init()
 
92
        '''
 
93
        return self.convert or self.strip or self.autoreset
 
94
 
 
95
    def get_win32_calls(self):
 
96
        if self.convert and winterm:
 
97
            return {
 
98
                AnsiStyle.RESET_ALL: (winterm.reset_all, ),
 
99
                AnsiStyle.BRIGHT: (winterm.style, WinStyle.BRIGHT),
 
100
                AnsiStyle.DIM: (winterm.style, WinStyle.NORMAL),
 
101
                AnsiStyle.NORMAL: (winterm.style, WinStyle.NORMAL),
 
102
                AnsiFore.BLACK: (winterm.fore, WinColor.BLACK),
 
103
                AnsiFore.RED: (winterm.fore, WinColor.RED),
 
104
                AnsiFore.GREEN: (winterm.fore, WinColor.GREEN),
 
105
                AnsiFore.YELLOW: (winterm.fore, WinColor.YELLOW),
 
106
                AnsiFore.BLUE: (winterm.fore, WinColor.BLUE),
 
107
                AnsiFore.MAGENTA: (winterm.fore, WinColor.MAGENTA),
 
108
                AnsiFore.CYAN: (winterm.fore, WinColor.CYAN),
 
109
                AnsiFore.WHITE: (winterm.fore, WinColor.GREY),
 
110
                AnsiFore.RESET: (winterm.fore, ),
 
111
                AnsiFore.LIGHTBLACK_EX: (winterm.fore, WinColor.BLACK, True),
 
112
                AnsiFore.LIGHTRED_EX: (winterm.fore, WinColor.RED, True),
 
113
                AnsiFore.LIGHTGREEN_EX: (winterm.fore, WinColor.GREEN, True),
 
114
                AnsiFore.LIGHTYELLOW_EX: (winterm.fore, WinColor.YELLOW, True),
 
115
                AnsiFore.LIGHTBLUE_EX: (winterm.fore, WinColor.BLUE, True),
 
116
                AnsiFore.LIGHTMAGENTA_EX: (winterm.fore, WinColor.MAGENTA, True),
 
117
                AnsiFore.LIGHTCYAN_EX: (winterm.fore, WinColor.CYAN, True),
 
118
                AnsiFore.LIGHTWHITE_EX: (winterm.fore, WinColor.GREY, True),
 
119
                AnsiBack.BLACK: (winterm.back, WinColor.BLACK),
 
120
                AnsiBack.RED: (winterm.back, WinColor.RED),
 
121
                AnsiBack.GREEN: (winterm.back, WinColor.GREEN),
 
122
                AnsiBack.YELLOW: (winterm.back, WinColor.YELLOW),
 
123
                AnsiBack.BLUE: (winterm.back, WinColor.BLUE),
 
124
                AnsiBack.MAGENTA: (winterm.back, WinColor.MAGENTA),
 
125
                AnsiBack.CYAN: (winterm.back, WinColor.CYAN),
 
126
                AnsiBack.WHITE: (winterm.back, WinColor.GREY),
 
127
                AnsiBack.RESET: (winterm.back, ),
 
128
                AnsiBack.LIGHTBLACK_EX: (winterm.back, WinColor.BLACK, True),
 
129
                AnsiBack.LIGHTRED_EX: (winterm.back, WinColor.RED, True),
 
130
                AnsiBack.LIGHTGREEN_EX: (winterm.back, WinColor.GREEN, True),
 
131
                AnsiBack.LIGHTYELLOW_EX: (winterm.back, WinColor.YELLOW, True),
 
132
                AnsiBack.LIGHTBLUE_EX: (winterm.back, WinColor.BLUE, True),
 
133
                AnsiBack.LIGHTMAGENTA_EX: (winterm.back, WinColor.MAGENTA, True),
 
134
                AnsiBack.LIGHTCYAN_EX: (winterm.back, WinColor.CYAN, True),
 
135
                AnsiBack.LIGHTWHITE_EX: (winterm.back, WinColor.GREY, True),
 
136
            }
 
137
        return dict()
 
138
 
 
139
    def write(self, text):
 
140
        if self.strip or self.convert:
 
141
            self.write_and_convert(text)
 
142
        else:
 
143
            self.wrapped.write(text)
 
144
            self.wrapped.flush()
 
145
        if self.autoreset:
 
146
            self.reset_all()
 
147
 
 
148
 
 
149
    def reset_all(self):
 
150
        if self.convert:
 
151
            self.call_win32('m', (0,))
 
152
        elif not self.strip and not is_stream_closed(self.wrapped):
 
153
            self.wrapped.write(Style.RESET_ALL)
 
154
 
 
155
 
 
156
    def write_and_convert(self, text):
 
157
        '''
 
158
        Write the given text to our wrapped stream, stripping any ANSI
 
159
        sequences from the text, and optionally converting them into win32
 
160
        calls.
 
161
        '''
 
162
        cursor = 0
 
163
        text = self.convert_osc(text)
 
164
        for match in self.ANSI_CSI_RE.finditer(text):
 
165
            start, end = match.span()
 
166
            self.write_plain_text(text, cursor, start)
 
167
            self.convert_ansi(*match.groups())
 
168
            cursor = end
 
169
        self.write_plain_text(text, cursor, len(text))
 
170
 
 
171
 
 
172
    def write_plain_text(self, text, start, end):
 
173
        if start < end:
 
174
            self.wrapped.write(text[start:end])
 
175
            self.wrapped.flush()
 
176
 
 
177
 
 
178
    def convert_ansi(self, paramstring, command):
 
179
        if self.convert:
 
180
            params = self.extract_params(command, paramstring)
 
181
            self.call_win32(command, params)
 
182
 
 
183
 
 
184
    def extract_params(self, command, paramstring):
 
185
        if command in 'Hf':
 
186
            params = tuple(int(p) if len(p) != 0 else 1 for p in paramstring.split(';'))
 
187
            while len(params) < 2:
 
188
                # defaults:
 
189
                params = params + (1,)
 
190
        else:
 
191
            params = tuple(int(p) for p in paramstring.split(';') if len(p) != 0)
 
192
            if len(params) == 0:
 
193
                # defaults:
 
194
                if command in 'JKm':
 
195
                    params = (0,)
 
196
                elif command in 'ABCD':
 
197
                    params = (1,)
 
198
 
 
199
        return params
 
200
 
 
201
 
 
202
    def call_win32(self, command, params):
 
203
        if command == 'm':
 
204
            for param in params:
 
205
                if param in self.win32_calls:
 
206
                    func_args = self.win32_calls[param]
 
207
                    func = func_args[0]
 
208
                    args = func_args[1:]
 
209
                    kwargs = dict(on_stderr=self.on_stderr)
 
210
                    func(*args, **kwargs)
 
211
        elif command in 'J':
 
212
            winterm.erase_screen(params[0], on_stderr=self.on_stderr)
 
213
        elif command in 'K':
 
214
            winterm.erase_line(params[0], on_stderr=self.on_stderr)
 
215
        elif command in 'Hf':     # cursor position - absolute
 
216
            winterm.set_cursor_position(params, on_stderr=self.on_stderr)
 
217
        elif command in 'ABCD':   # cursor position - relative
 
218
            n = params[0]
 
219
            # A - up, B - down, C - forward, D - back
 
220
            x, y = {'A': (0, -n), 'B': (0, n), 'C': (n, 0), 'D': (-n, 0)}[command]
 
221
            winterm.cursor_adjust(x, y, on_stderr=self.on_stderr)
 
222
 
 
223
 
 
224
    def convert_osc(self, text):
 
225
        for match in self.ANSI_OSC_RE.finditer(text):
 
226
            start, end = match.span()
 
227
            text = text[:start] + text[end:]
 
228
            paramstring, command = match.groups()
 
229
            if command in '\x07':       # \x07 = BEL
 
230
                params = paramstring.split(";")
 
231
                # 0 - change title and icon (we will only change title)
 
232
                # 1 - change icon (we don't support this)
 
233
                # 2 - change title
 
234
                if params[0] in '02':
 
235
                    winterm.set_title(params[1])
 
236
        return text