Skip to content

Commit b333036

Browse files
Upgrade code for compatibility with prompt_toolkit 3.0.
1 parent b9ba68c commit b333036

21 files changed

+241
-321
lines changed

Diff for: PyInquirer/__init__.py

+15-7
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,7 @@
11
# -*- coding: utf-8 -*-
22

3-
from __future__ import absolute_import, print_function
43
import os
54

6-
# from prompt_toolkit.token import Token
7-
# from prompt_toolkit.styles import style_from_dict
8-
# from prompt_toolkit.validation import Validator, ValidationError
9-
105
from .utils import print_json, format_json
116

127

@@ -21,9 +16,22 @@ class PromptParameterException(ValueError):
2116
def __init__(self, message, errors=None):
2217

2318
# Call the base class constructor with the parameters it needs
24-
super(PromptParameterException, self).__init__(
25-
'You must provide a `%s` value' % message, errors)
19+
super().__init__('You must provide a `%s` value' % message, errors)
2620

2721
from .prompt import prompt
2822
from .separator import Separator
2923
from .prompts.common import default_style
24+
25+
26+
# The code below here is here because of backwards-compatibility. Before,
27+
# people were using style_from_dict and importing it from here. It's better to
28+
# use Style.from_dict, as recommended by prompt_toolkit now.
29+
from prompt_toolkit.styles import Style
30+
def style_from_dict(style_dict):
31+
# Deprecated function. Users should use Style.from_dict instead.
32+
# Keep this here for backwards-compatibility.
33+
return Style.from_dict({
34+
'.'.join(key).lower(): value for key, value in style_dict.items()
35+
})
36+
from pygments.token import Token
37+
from prompt_toolkit.validation import Validator, ValidationError

Diff for: PyInquirer/color_print.py

+3-7
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,17 @@
22
"""
33
provide colorized output
44
"""
5-
from __future__ import print_function, unicode_literals
65
import sys
7-
from prompt_toolkit.shortcuts import print_tokens, style_from_dict, Token
6+
from prompt_toolkit.shortcuts import print_tokens
87

98

109
def _print_token_factory(col):
1110
"""Internal helper to provide color names."""
1211
def _helper(msg):
13-
style = style_from_dict({
14-
Token.Color: col,
15-
})
1612
tokens = [
17-
(Token.Color, msg)
13+
('fg:' + col, msg)
1814
]
19-
print_tokens(tokens, style=style)
15+
print_tokens(tokens)
2016

2117
def _helper_no_terminal(msg):
2218
# workaround if we have no terminal

Diff for: PyInquirer/prompt.py

+22-15
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
# -*- coding: utf-8 -*-
2-
3-
from __future__ import absolute_import, print_function
4-
5-
from prompt_toolkit.shortcuts import run_application
6-
2+
from contextlib import contextmanager
73
from . import PromptParameterException, prompts
84
from .prompts import list, confirm, input, password, checkbox, rawlist, expand, editor
5+
from prompt_toolkit.patch_stdout import patch_stdout as pt_patch_stdout
6+
from prompt_toolkit.shortcuts import PromptSession
7+
from prompt_toolkit.application import Application
98

109

1110
def prompt(questions, answers=None, **kwargs):
@@ -17,7 +16,6 @@ def prompt(questions, answers=None, **kwargs):
1716
return_asyncio_coroutine = kwargs.pop('return_asyncio_coroutine', False)
1817
true_color = kwargs.pop('true_color', False)
1918
refresh_interval = kwargs.pop('refresh_interval', 0)
20-
eventloop = kwargs.pop('eventloop', None)
2119
kbi_msg = kwargs.pop('keyboard_interrupt_msg', 'Cancelled by user')
2220
raise_kbi = kwargs.pop('raise_keyboard_interrupt', False)
2321

@@ -64,16 +62,22 @@ def prompt(questions, answers=None, **kwargs):
6462

6563
if callable(question.get('default')):
6664
_kwargs['default'] = question['default'](answers)
67-
68-
application = getattr(prompts, type).question(message, **_kwargs)
6965

70-
answer = run_application(
71-
application,
72-
patch_stdout=patch_stdout,
73-
return_asyncio_coroutine=return_asyncio_coroutine,
74-
true_color=true_color,
75-
refresh_interval=refresh_interval,
76-
eventloop=eventloop)
66+
with pt_patch_stdout() if patch_stdout else _dummy_context_manager():
67+
result = getattr(prompts, type).question(message, **_kwargs)
68+
69+
if isinstance(result, PromptSession):
70+
answer = result.prompt()
71+
elif isinstance(result, Application):
72+
answer = result.run()
73+
else:
74+
assert isinstance(answer, str)
75+
answer = result
76+
77+
#answer = application.run(
78+
# return_asyncio_coroutine=return_asyncio_coroutine,
79+
# true_color=true_color,
80+
# refresh_interval=refresh_interval)
7781

7882
if answer is not None:
7983
if filter:
@@ -97,6 +101,9 @@ def prompt(questions, answers=None, **kwargs):
97101
return {}
98102
return answers
99103

104+
@contextmanager
105+
def _dummy_context_manager():
106+
yield
100107

101108
# TODO:
102109
# Bottom Bar - inquirer.ui.BottomBar

Diff for: PyInquirer/prompts/checkbox.py

+41-45
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,24 @@
22
"""
33
`checkbox` type question
44
"""
5-
from __future__ import print_function, unicode_literals
65
from prompt_toolkit.application import Application
7-
from prompt_toolkit.key_binding.manager import KeyBindingManager
8-
from prompt_toolkit.keys import Keys
9-
from prompt_toolkit.layout.containers import Window
6+
from prompt_toolkit.key_binding import KeyBindings
107
from prompt_toolkit.filters import IsDone
11-
from prompt_toolkit.layout.controls import TokenListControl
8+
from prompt_toolkit.layout.controls import FormattedTextControl
129
from prompt_toolkit.layout.containers import ConditionalContainer, \
13-
ScrollOffsets, HSplit
10+
ScrollOffsets, HSplit, Window, WindowAlign
1411
from prompt_toolkit.layout.dimension import LayoutDimension as D
15-
from prompt_toolkit.token import Token
12+
from prompt_toolkit.layout import Layout
1613

1714
from .. import PromptParameterException
1815
from ..separator import Separator
1916
from .common import setup_simple_validator, default_style, if_mousedown
2017

2118

22-
# custom control based on TokenListControl
19+
# custom control based on FormattedTextControl
2320

2421

25-
class InquirerControl(TokenListControl):
22+
class InquirerControl(FormattedTextControl):
2623
def __init__(self, choices, pointer_index, **kwargs):
2724
self.pointer_index = pointer_index
2825
self.pointer_sign = kwargs.pop("pointer_sign", "\u276f")
@@ -31,8 +28,7 @@ def __init__(self, choices, pointer_index, **kwargs):
3128
self.selected_options = [] # list of names
3229
self.answered = False
3330
self._init_choices(choices)
34-
super(InquirerControl, self).__init__(self._get_choice_tokens,
35-
**kwargs)
31+
super().__init__(self._get_choice_tokens, **kwargs)
3632

3733
def _init_choices(self, choices):
3834
# helper to convert from question format to internal format
@@ -57,48 +53,47 @@ def _init_choices(self, choices):
5753
def choice_count(self):
5854
return len(self.choices)
5955

60-
def _get_choice_tokens(self, cli):
56+
def _get_choice_tokens(self):
6157
tokens = []
62-
T = Token
6358

6459
def append(index, line):
6560
if isinstance(line, Separator):
66-
tokens.append((T.Separator, ' %s\n' % line))
61+
tokens.append(('class:Separator', ' %s\n' % line))
6762
else:
6863
line_name = line[0]
6964
line_value = line[1]
7065
selected = (line_value in self.selected_options) # use value to check if option has been selected
7166
pointed_at = (index == self.pointer_index)
7267

7368
@if_mousedown
74-
def select_item(cli, mouse_event):
69+
def select_item(mouse_event):
7570
# bind option with this index to mouse event
7671
if line_value in self.selected_options:
7772
self.selected_options.remove(line_value)
7873
else:
7974
self.selected_options.append(line_value)
8075

8176
if pointed_at:
82-
tokens.append((T.Pointer, ' {}'.format(self.pointer_sign), select_item)) # ' >'
77+
tokens.append(('class:pointer', ' {}'.format(self.pointer_sign), select_item)) # ' >'
8378
else:
84-
tokens.append((T, ' ', select_item))
79+
tokens.append(('', ' ', select_item))
8580
# 'o ' - FISHEYE
8681
if choice[2]: # disabled
87-
tokens.append((T, '- %s (%s)' % (choice[0], choice[2])))
82+
tokens.append(('', '- %s (%s)' % (choice[0], choice[2])))
8883
else:
8984
if selected:
90-
tokens.append((T.Selected, '{} '.format(self.selected_sign), select_item))
85+
tokens.append(('class:selected', '{} '.format(self.selected_sign), select_item))
9186
else:
92-
tokens.append((T, '{} '.format(self.unselected_sign), select_item))
87+
tokens.append(('', '{} '.format(self.unselected_sign), select_item))
9388

9489
if pointed_at:
95-
tokens.append((Token.SetCursorPosition, ''))
90+
tokens.append(('[SetCursorPosition]', ''))
9691

9792
if choice[3]: # description
98-
tokens.append((T, "%s - %s" % (line_name, choice[3])))
93+
tokens.append(('', "%s - %s" % (line_name, choice[3])))
9994
else:
100-
tokens.append((T, line_name, select_item))
101-
tokens.append((T, '\n'))
95+
tokens.append(('', line_name, select_item))
96+
tokens.append(('', '\n'))
10297

10398
# prepare the select choices
10499
for i, choice in enumerate(self.choices):
@@ -142,30 +137,31 @@ def question(message, **kwargs):
142137
ic = InquirerControl(choices, pointer_index, **additional_parameters)
143138
qmark = kwargs.pop('qmark', '?')
144139

145-
def get_prompt_tokens(cli):
140+
def get_prompt_tokens():
146141
tokens = []
147142

148-
tokens.append((Token.QuestionMark, qmark))
149-
tokens.append((Token.Question, ' %s ' % message))
143+
tokens.append(('class:questionmark', qmark))
144+
tokens.append(('class:question', ' %s ' % message))
150145
if ic.answered:
151146
nbr_selected = len(ic.selected_options)
152147
if nbr_selected == 0:
153-
tokens.append((Token.Answer, ' done'))
148+
tokens.append(('class:answer', ' done'))
154149
elif nbr_selected == 1:
155-
tokens.append((Token.Answer, ' [%s]' % ic.selected_options[0]))
150+
tokens.append(('class:Answer', ' [%s]' % ic.selected_options[0]))
156151
else:
157-
tokens.append((Token.Answer,
152+
tokens.append(('class:answer',
158153
' done (%d selections)' % nbr_selected))
159154
else:
160-
tokens.append((Token.Instruction,
155+
tokens.append(('class:instruction',
161156
' (<up>, <down> to move, <space> to select, <a> '
162157
'to toggle, <i> to invert)'))
163158
return tokens
164159

165160
# assemble layout
166161
layout = HSplit([
167162
Window(height=D.exact(1),
168-
content=TokenListControl(get_prompt_tokens, align_center=False)
163+
content=FormattedTextControl(get_prompt_tokens),
164+
align=WindowAlign.CENTER,
169165
),
170166
ConditionalContainer(
171167
Window(
@@ -179,31 +175,31 @@ def get_prompt_tokens(cli):
179175
])
180176

181177
# key bindings
182-
manager = KeyBindingManager.for_prompt()
178+
kb = KeyBindings()
183179

184-
@manager.registry.add_binding(Keys.ControlQ, eager=True)
185-
@manager.registry.add_binding(Keys.ControlC, eager=True)
180+
@kb.add('c-q', eager=True)
181+
@kb.add('c-c', eager=True)
186182
def _(event):
187183
raise KeyboardInterrupt()
188-
# event.cli.set_return_value(None)
184+
# event.app.exit(result=None)
189185

190-
@manager.registry.add_binding(' ', eager=True)
186+
@kb.add(' ', eager=True)
191187
def toggle(event):
192188
pointed_choice = ic.choices[ic.pointer_index][1] # value
193189
if pointed_choice in ic.selected_options:
194190
ic.selected_options.remove(pointed_choice)
195191
else:
196192
ic.selected_options.append(pointed_choice)
197193

198-
@manager.registry.add_binding('i', eager=True)
194+
@kb.add('i', eager=True)
199195
def invert(event):
200196
inverted_selection = [c[1] for c in ic.choices if
201197
not isinstance(c, Separator) and
202198
c[1] not in ic.selected_options and
203199
not c[2]]
204200
ic.selected_options = inverted_selection
205201

206-
@manager.registry.add_binding('a', eager=True)
202+
@kb.add('a', eager=True)
207203
def all(event):
208204
all_selected = True # all choices have been selected
209205
for c in ic.choices:
@@ -214,7 +210,7 @@ def all(event):
214210
if all_selected:
215211
ic.selected_options = []
216212

217-
@manager.registry.add_binding(Keys.Down, eager=True)
213+
@kb.add('down', eager=True)
218214
def move_cursor_down(event):
219215
def _next():
220216
ic.pointer_index = ((ic.pointer_index + 1) % ic.line_count)
@@ -223,7 +219,7 @@ def _next():
223219
ic.choices[ic.pointer_index][2]:
224220
_next()
225221

226-
@manager.registry.add_binding(Keys.Up, eager=True)
222+
@kb.add('up', eager=True)
227223
def move_cursor_up(event):
228224
def _prev():
229225
ic.pointer_index = ((ic.pointer_index - 1) % ic.line_count)
@@ -232,15 +228,15 @@ def _prev():
232228
ic.choices[ic.pointer_index][2]:
233229
_prev()
234230

235-
@manager.registry.add_binding(Keys.Enter, eager=True)
231+
@kb.add('enter', eager=True)
236232
def set_answer(event):
237233
ic.answered = True
238234
# TODO use validator
239-
event.cli.set_return_value(ic.get_selected_values())
235+
event.app.exit(result=ic.get_selected_values())
240236

241237
return Application(
242-
layout=layout,
243-
key_bindings_registry=manager.registry,
238+
layout=Layout(layout),
239+
key_bindings=kb,
244240
mouse_support=True,
245241
style=style
246242
)

0 commit comments

Comments
 (0)