Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagesmc
Path: blob/master/src/sage/dev/user_interface.py
8815 views
1
r"""
2
User Interface
3
4
This module provides an abstract base class that is used for displaying messages
5
and prompting for user input.
6
7
.. SEEALSO::
8
9
:class:`CmdLineInterface` for an implementation of this class
10
11
AUTHORS:
12
13
- David Roe, Julian Rueth: initial version
14
15
"""
16
#*****************************************************************************
17
# Copyright (C) 2013 David Roe <[email protected]>
18
# Julian Rueth <[email protected]>
19
#
20
# Distributed under the terms of the GNU General Public License (GPL)
21
# as published by the Free Software Foundation; either version 2 of
22
# the License, or (at your option) any later version.
23
# http://www.gnu.org/licenses/
24
#*****************************************************************************
25
26
# log levels
27
ERROR = -2
28
WARNING = -1
29
NORMAL = 0
30
INFO = 1 # display informational messages, such as git commands executed
31
DEBUG = 2 # display additional debug information
32
33
class UserInterface(object):
34
r"""
35
An abstract base class for displaying messages and prompting the user for
36
input.
37
38
TESTS::
39
40
sage: from sage.dev.user_interface import UserInterface
41
sage: from sage.dev.test.config import DoctestConfig
42
sage: UserInterface(DoctestConfig())
43
<sage.dev.user_interface.UserInterface object at 0x...>
44
"""
45
46
def __init__(self, config):
47
r"""
48
Initialization.
49
50
TESTS:
51
52
sage: from sage.dev.user_interface import UserInterface
53
sage: from sage.dev.test.config import DoctestConfig
54
sage: type(UserInterface(DoctestConfig()))
55
<class 'sage.dev.user_interface.UserInterface'>
56
"""
57
self._config = config
58
59
def select(self, prompt, options, default=None):
60
r"""
61
Ask the user to select from list of options and return selected option.
62
63
INPUT:
64
65
- ``prompt`` -- a string, prompt to display
66
67
- ``options`` -- iterable of strings, the options
68
69
- ``default`` -- an integer or ``None`` (default: ``None``),
70
the index of the default option
71
72
TESTS::
73
74
sage: from sage.dev.user_interface import UserInterface
75
sage: from sage.dev.test.config import DoctestConfig
76
sage: UI = UserInterface(DoctestConfig())
77
sage: UI.select("Should I delete your home directory?", ("yes","no","maybe"), default=1)
78
Traceback (most recent call last):
79
...
80
NotImplementedError
81
"""
82
raise NotImplementedError
83
84
def confirm(self, question, default=None):
85
r"""
86
Ask a yes/no question and return the response as a boolean.
87
88
INPUT:
89
90
- ``question`` -- a string
91
92
- ``default`` -- a boolean or ``None`` (default: ``None``), the
93
default value
94
95
TESTS::
96
97
sage: from sage.dev.user_interface import UserInterface
98
sage: from sage.dev.test.config import DoctestConfig
99
sage: UI = UserInterface(DoctestConfig())
100
sage: UI.confirm("Should I delete your home directory?")
101
Traceback (most recent call last):
102
...
103
NotImplementedError
104
"""
105
if default is None:
106
default_option = None
107
elif default is True:
108
default_option = 0
109
elif default is False:
110
default_option = 1
111
else:
112
raise ValueError
113
114
return self.select(question, ("yes", "no"), default_option) == "yes"
115
116
def get_input(self, prompt):
117
r"""
118
Read input after displaying ``prompt``.
119
120
TESTS::
121
122
sage: from sage.dev.user_interface import UserInterface
123
sage: from sage.dev.test.config import DoctestConfig
124
sage: UI = UserInterface(DoctestConfig())
125
sage: UI.get_input("What do you want for dinner?")
126
Traceback (most recent call last):
127
...
128
NotImplementedError
129
"""
130
raise NotImplementedError
131
132
def get_password(self, prompt):
133
r"""
134
Ask for a password after displaying ``prompt``.
135
136
TESTS::
137
138
sage: from sage.dev.user_interface import UserInterface
139
sage: from sage.dev.test.config import DoctestConfig
140
sage: UI = UserInterface(DoctestConfig())
141
sage: UI.get_password("What is the passphrase for your safe?")
142
Traceback (most recent call last):
143
...
144
NotImplementedError
145
"""
146
raise NotImplementedError
147
148
def show(self, message, *args, **kwds):
149
r"""
150
Display ``message``.
151
152
INPUT:
153
154
- ``message`` -- a string or list/tuple/iterable of
155
strings. Each individual message will be wrapped to the
156
terminal width.
157
158
- ``*args`` -- optional positional arguments that will be
159
passed to ``message.format()``.
160
161
- ``log_level=INFO`` -- one of ``ERROR``, ``WARNING``,
162
``NORMAL``, ``INFO``, or ``DEBUG`` (default:
163
``INFO``). Optional keyword argument.
164
165
TESTS::
166
167
sage: from sage.dev.user_interface import UserInterface, DEBUG
168
sage: from sage.dev.test.config import DoctestConfig
169
sage: UI = UserInterface(DoctestConfig())
170
sage: UI.show("I ate filet mignon for dinner.")
171
Traceback (most recent call last):
172
...
173
NotImplementedError
174
sage: UI.show("I ate filet mignon for dinner.", log_level=DEBUG)
175
"""
176
log_level = kwds.pop('log_level', NORMAL)
177
if log_level not in (ERROR, WARNING, NORMAL, INFO, DEBUG):
178
raise ValueError('log_level is invalid')
179
if len(kwds) != 0:
180
raise ValueError('the only allowed keyword argument is "log_level"')
181
config_log_level = int(self._config.get("log_level", str(INFO)))
182
if config_log_level >= log_level:
183
if isinstance(message, basestring):
184
self._show(message, log_level, *args)
185
else:
186
for msg in message:
187
self._show(msg, log_level, *args)
188
189
def debug(self, message, *args):
190
r"""
191
Display ``message``.
192
193
INPUT:
194
195
- ``message`` -- a string or list/tuple/iterable of strings.
196
197
- ``*args`` -- optional positional arguments that will be
198
passed to ``message.format()``.
199
200
TESTS:
201
202
Debug messages are not displayed in doctests::
203
204
sage: from sage.dev.user_interface import UserInterface
205
sage: from sage.dev.test.config import DoctestConfig
206
sage: UI = UserInterface(DoctestConfig())
207
sage: UI.debug("I ate filet mignon for dinner.")
208
"""
209
self.show(message, *args, log_level=DEBUG)
210
211
def info(self, message, *args):
212
r"""
213
Display ``message``.
214
215
These are informational messages to be shown to the user,
216
typically indicating how to proceed.
217
218
INPUT:
219
220
- ``message`` -- a string or list/tuple/iterable of strings.
221
222
- ``*args`` -- optional positional arguments that will be
223
passed to ``message.format()``.
224
225
TESTS:
226
227
Info messages are not displayed in doctests::
228
229
sage: from sage.dev.user_interface import UserInterface
230
sage: from sage.dev.test.config import DoctestConfig
231
sage: UI = UserInterface(DoctestConfig())
232
sage: UI.info("I ate filet mignon for dinner.")
233
Traceback (most recent call last):
234
...
235
NotImplementedError
236
"""
237
self.show(message, *args, log_level=INFO)
238
239
def warning(self, message, *args):
240
r"""
241
Display ``message``.
242
243
INPUT:
244
245
- ``message`` -- a string or list/tuple/iterable of strings.
246
247
- ``*args`` -- optional positional arguments that will be
248
passed to ``message.format()``.
249
250
TESTS:
251
252
sage: from sage.dev.user_interface import UserInterface
253
sage: from sage.dev.test.config import DoctestConfig
254
sage: UI = UserInterface(DoctestConfig())
255
sage: UI.warning("I ate filet mignon for dinner.")
256
Traceback (most recent call last):
257
...
258
NotImplementedError
259
"""
260
self.show(message, *args, log_level=WARNING)
261
262
def error(self, message, *args):
263
r"""
264
Display ``message``.
265
266
INPUT:
267
268
- ``message`` -- a string or list/tuple/iterable of strings.
269
270
- ``*args`` -- optional positional arguments that will be
271
passed to ``message.format()``.
272
273
TESTS:
274
275
sage: from sage.dev.user_interface import UserInterface
276
sage: from sage.dev.test.config import DoctestConfig
277
sage: UI = UserInterface(DoctestConfig())
278
sage: UI.error("I ate filet mignon for dinner.")
279
Traceback (most recent call last):
280
...
281
NotImplementedError
282
"""
283
self.show(message, *args, log_level=ERROR)
284
285
def _show(self, message, log_level, *args):
286
r"""
287
Display ``message``.
288
289
INPUT:
290
291
- ``message`` -- a string
292
293
- ``log_level`` -- one of ``ERROR``, ``WARNING``, ``NORMAL``,
294
``INFO``, or ``DEBUG`` (default: ``NORMAL``)
295
296
- ``*args`` -- optional positional arguments that will be
297
passed to ``message.format()``.
298
299
TESTS::
300
301
sage: from sage.dev.user_interface import UserInterface, NORMAL
302
sage: from sage.dev.test.config import DoctestConfig
303
sage: UI = UserInterface(DoctestConfig())
304
sage: UI._show("I ate filet mignon for dinner.", NORMAL)
305
Traceback (most recent call last):
306
...
307
NotImplementedError
308
"""
309
raise NotImplementedError
310
311
def edit(self, filename):
312
r"""
313
Drop user into an editor with ``filename`` open.
314
315
OUTPUT:
316
317
Raises a :class:`sage.dev.user_interface_error.OperationCancelledError`
318
if the editor exits with non-zero exit code.
319
320
TESTS::
321
322
sage: from sage.dev.user_interface import UserInterface
323
sage: from sage.dev.test.config import DoctestConfig
324
sage: UI = UserInterface(DoctestConfig())
325
sage: UI.edit("filename")
326
Traceback (most recent call last):
327
...
328
NotImplementedError
329
"""
330
raise NotImplementedError
331
332