Skip to content

Commit aad6577

Browse files
authored
[v2] Implement conditional prompt_toolkit importing (#10231)
1 parent 8a886d8 commit aad6577

22 files changed

Lines changed: 1598 additions & 1407 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"type": "enhancement",
3+
"category": "Performance",
4+
"description": "Defer some imports (e.g. ``prompt_toolkit``) until they are needed to reduce command initialization time (e.g. loading all imported modules)."
5+
}

awscli/autoprompt/core.py

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,13 @@
1010
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
1111
# ANY KIND, either express or implied. See the License for the specific
1212
# language governing permissions and limitations under the License.
13-
from botocore.exceptions import ProfileNotFound
14-
1513
from awscli.autocomplete.filters import fuzzy_filter
1614
from awscli.autocomplete.main import create_autocompleter
1715
from awscli.autoprompt.prompttoolkit import PromptToolkitPrompter
18-
from awscli.customizations.exceptions import ParamValidationError
1916
from awscli.errorhandler import SilenceParamValidationMsgErrorHandler
2017

2118

2219
class AutoPromptDriver:
23-
_NO_PROMPT_ARGS = ['help', '--version']
24-
_CLI_AUTO_PROMPT_OPTION = '--cli-auto-prompt'
25-
_NO_CLI_AUTO_PROMPT_OPTION = '--no-cli-auto-prompt'
26-
2720
def __init__(self, driver, completion_source=None, prompter=None):
2821
self._completion_source = completion_source
2922
self._prompter = prompter
@@ -42,34 +35,6 @@ def prompter(self):
4235
)
4336
return self._prompter
4437

45-
def validate_auto_prompt_args_are_mutually_exclusive(self, args):
46-
no_cli_auto_prompt = self._NO_CLI_AUTO_PROMPT_OPTION in args
47-
cli_auto_prompt = self._CLI_AUTO_PROMPT_OPTION in args
48-
if cli_auto_prompt and no_cli_auto_prompt:
49-
raise ParamValidationError(
50-
'Both --cli-auto-prompt and --no-cli-auto-prompt cannot be '
51-
'specified at the same time.'
52-
)
53-
54-
def resolve_mode(self, args):
55-
# Order of precedence to check:
56-
# - check if any arg rom NO_PROMPT_ARGS in args
57-
# - check if '--no-cli-auto-prompt' was specified
58-
# - check if '--cli-auto-prompt' was specified
59-
# - check configuration chain
60-
self.validate_auto_prompt_args_are_mutually_exclusive(args)
61-
if any(arg in args for arg in self._NO_PROMPT_ARGS):
62-
return 'off'
63-
if self._NO_CLI_AUTO_PROMPT_OPTION in args:
64-
return 'off'
65-
if self._CLI_AUTO_PROMPT_OPTION in args:
66-
return 'on'
67-
try:
68-
config = self._session.get_config_variable('cli_auto_prompt')
69-
return config.lower()
70-
except ProfileNotFound:
71-
return 'off'
72-
7338
def inject_silence_param_error_msg_handler(self, driver):
7439
driver.error_handler.inject_handler(
7540
0, SilenceParamValidationMsgErrorHandler()

awscli/autoprompt/exceptions.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License"). You
4+
# may not use this file except in compliance with the License. A copy of
5+
# the License is located at
6+
#
7+
# http://aws.amazon.com/apache2.0/
8+
#
9+
# or in the "license" file accompanying this file. This file is
10+
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
11+
# ANY KIND, either express or implied. See the License for the specific
12+
# language governing permissions and limitations under the License.
13+
class PrompterKeyboardInterrupt(KeyboardInterrupt):
14+
pass

awscli/autoprompt/factory.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
from prompt_toolkit.layout.processors import BeforeInput
2929
from prompt_toolkit.widgets import SearchToolbar, VerticalLine
3030

31+
from awscli.autoprompt.exceptions import PrompterKeyboardInterrupt
3132
from awscli.autoprompt.filters import (
3233
doc_section_visible,
3334
doc_window_has_focus,
@@ -46,10 +47,6 @@
4647
)
4748

4849

49-
class PrompterKeyboardInterrupt(KeyboardInterrupt):
50-
pass
51-
52-
5350
class CLIPromptBuffer(Buffer):
5451
def __init__(self, *args, **kwargs):
5552
super().__init__(*args, **kwargs)

awscli/clidriver.py

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
ScopedConfigProvider,
3131
)
3232
from botocore.context import start_as_current_context
33+
from botocore.exceptions import ProfileNotFound
3334
from botocore.history import get_global_history_recorder
3435

3536
from awscli import __version__
@@ -49,7 +50,6 @@
4950
ListArgument,
5051
UnknownArgumentError,
5152
)
52-
from awscli.autoprompt.core import AutoPromptDriver
5353
from awscli.commands import CLICommand
5454
from awscli.compat import (
5555
default_pager,
@@ -58,6 +58,7 @@
5858
validate_preferred_output_encoding,
5959
)
6060
from awscli.constants import PARAM_VALIDATION_ERROR_RC
61+
from awscli.customizations.exceptions import ParamValidationError
6162
from awscli.errorhandler import (
6263
construct_cli_error_handlers_chain,
6364
construct_entry_point_handlers_chain,
@@ -90,6 +91,9 @@
9091
)
9192
HISTORY_RECORDER = get_global_history_recorder()
9293
METADATA_FILENAME = 'metadata.json'
94+
_NO_AUTO_PROMPT_ARGS = ['help', '--version']
95+
_CLI_AUTO_PROMPT_OPTION = '--cli-auto-prompt'
96+
_NO_CLI_AUTO_PROMPT_OPTION = '--no-cli-auto-prompt'
9397
# Don't remove this line. The idna encoding
9498
# is used by getaddrinfo when dealing with unicode hostnames,
9599
# and in some cases, there appears to be a race condition
@@ -126,6 +130,36 @@ def create_clidriver(args=None):
126130
return driver
127131

128132

133+
def validate_auto_prompt_args_are_mutually_exclusive(args):
134+
no_cli_auto_prompt = _NO_CLI_AUTO_PROMPT_OPTION in args
135+
cli_auto_prompt = _CLI_AUTO_PROMPT_OPTION in args
136+
if cli_auto_prompt and no_cli_auto_prompt:
137+
raise ParamValidationError(
138+
'Both --cli-auto-prompt and --no-cli-auto-prompt cannot be '
139+
'specified at the same time.'
140+
)
141+
142+
143+
def resolve_auto_prompt_mode(args, session):
144+
# Order of precedence to check:
145+
# - check if any arg from _NO_AUTO_PROMPT_ARGS in args
146+
# - check if '--no-cli-auto-prompt' was specified
147+
# - check if '--cli-auto-prompt' was specified
148+
# - check configuration chain
149+
validate_auto_prompt_args_are_mutually_exclusive(args)
150+
if any(arg in args for arg in _NO_AUTO_PROMPT_ARGS):
151+
return 'off'
152+
if _NO_CLI_AUTO_PROMPT_OPTION in args:
153+
return 'off'
154+
if _CLI_AUTO_PROMPT_OPTION in args:
155+
return 'on'
156+
try:
157+
config = session.get_config_variable('cli_auto_prompt')
158+
return config.lower()
159+
except ProfileNotFound:
160+
return 'off'
161+
162+
129163
def _get_distribution_source():
130164
metadata_file = os.path.join(
131165
os.path.join(os.path.dirname(os.path.abspath(__file__)), 'data'),
@@ -220,12 +254,17 @@ def _do_main(self, args):
220254
driver = self._driver
221255
if driver is None:
222256
driver = create_clidriver(args)
223-
autoprompt_driver = AutoPromptDriver(driver)
224-
auto_prompt_mode = autoprompt_driver.resolve_mode(args)
257+
auto_prompt_mode = resolve_auto_prompt_mode(args, driver.session)
225258
if auto_prompt_mode == 'on':
259+
from awscli.autoprompt.core import AutoPromptDriver
260+
261+
autoprompt_driver = AutoPromptDriver(driver)
226262
args = autoprompt_driver.prompt_for_args(args)
227263
rc = self._run_driver(driver, args, prompt_mode='on')
228264
elif auto_prompt_mode == 'on-partial':
265+
from awscli.autoprompt.core import AutoPromptDriver
266+
267+
autoprompt_driver = AutoPromptDriver(driver)
229268
autoprompt_driver.inject_silence_param_error_msg_handler(driver)
230269
rc = self._run_driver(driver, args, prompt_mode='off')
231270
if rc == PARAM_VALIDATION_ERROR_RC:

awscli/customizations/configure/configure.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
from awscli.customizations.configure.listprofiles import ListProfilesCommand
2929
from awscli.customizations.configure.mfalogin import ConfigureMFALoginCommand
3030
from awscli.customizations.configure.set import ConfigureSetCommand
31-
from awscli.customizations.configure.sso import (
31+
from awscli.customizations.configure.sso_commands import (
3232
ConfigureSSOCommand,
3333
ConfigureSSOSessionCommand,
3434
)

0 commit comments

Comments
 (0)