Skip to content

Commit d1a0f27

Browse files
refactor: put logic into separate methods
1 parent d45fec1 commit d1a0f27

File tree

1 file changed

+28
-16
lines changed

1 file changed

+28
-16
lines changed

src/azure-cli-core/azure/cli/core/__init__.py

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,19 @@ def __init__(self, cli_ctx=None):
210210
self.cmd_to_loader_map = {}
211211
self.loaders = []
212212

213+
def _create_stub_commands_for_completion(self, command_names):
214+
"""Create stub commands for top-level tab completion optimization.
215+
216+
Stub commands allow argcomplete to parse command names without loading modules.
217+
218+
:param command_names: List of command names to create stubs for
219+
"""
220+
from azure.cli.core.commands import AzCliCommand
221+
for cmd_name in command_names:
222+
if cmd_name not in self.command_table:
223+
# Create stub with no-op handler - never invoked during completion
224+
self.command_table[cmd_name] = AzCliCommand(self, cmd_name, lambda: None)
225+
213226
def _update_command_definitions(self):
214227
for cmd_name in self.command_table:
215228
loaders = self.cmd_to_loader_map[cmd_name]
@@ -436,17 +449,9 @@ def _get_extension_suppressions(mod_loaders):
436449
index_result = command_index.get(args)
437450
if index_result:
438451
index_modules, index_extensions = index_result
439-
# Special case for top-level completion - create minimal command groups
452+
440453
if index_modules == TOP_LEVEL_COMPLETION_MARKER:
441-
from azure.cli.core.commands import AzCliCommand
442-
# index_extensions contains the command names, not extensions
443-
for cmd_name in index_extensions:
444-
# Create a minimal command entry for tab completion
445-
# This allows argparse to see the command without loading the module
446-
if cmd_name not in self.command_table:
447-
self.command_table[cmd_name] = AzCliCommand(
448-
self, cmd_name, lambda: None
449-
)
454+
self._create_stub_commands_for_completion(index_extensions)
450455
return self.command_table
451456

452457
# Always load modules and extensions, because some of them (like those in
@@ -500,7 +505,6 @@ def _get_extension_suppressions(mod_loaders):
500505
else:
501506
logger.debug("No module found from index for '%s'", args)
502507

503-
# No module found from the index. Load all command modules and extensions
504508
logger.debug("Loading all modules and extensions")
505509
_update_command_table_from_modules(args)
506510

@@ -596,6 +600,18 @@ def __init__(self, cli_ctx=None):
596600
self.cloud_profile = cli_ctx.cloud.profile
597601
self.cli_ctx = cli_ctx
598602

603+
def _get_top_level_completion_commands(self):
604+
"""Get all command names for top-level completion optimization.
605+
606+
Returns marker and command list for creating stub commands without module loading.
607+
608+
:return: tuple of (TOP_LEVEL_COMPLETION_MARKER, list of command names)
609+
"""
610+
index = self.INDEX[self._COMMAND_INDEX]
611+
all_commands = list(index.keys())
612+
logger.debug("Top-level completion: %d commands available", len(all_commands))
613+
return TOP_LEVEL_COMPLETION_MARKER, all_commands
614+
599615
def get(self, args):
600616
"""Get the corresponding module and extension list of a command.
601617
@@ -617,11 +633,7 @@ def get(self, args):
617633
if not args or args[0].startswith('-'):
618634
# For top-level completion (az [tab])
619635
if not args and self.cli_ctx.data.get('completer_active'):
620-
# Return a special marker so we know to skip module loading for top-level completion
621-
index = self.INDEX[self._COMMAND_INDEX]
622-
all_commands = list(index.keys())
623-
logger.debug("Top-level completion: %d commands available", len(all_commands))
624-
return TOP_LEVEL_COMPLETION_MARKER, all_commands # special marker, command list
636+
return self._get_top_level_completion_commands()
625637
return None
626638

627639
# Get the top-level command, like `network` in `network vnet create -h`

0 commit comments

Comments
 (0)