{CI} Fix parser spellchecker test by setting explicit parser prog#33314
Conversation
️✔️AzureCLI-FullTest
|
️✔️AzureCLI-BreakingChangeTest
|
|
The git hooks are available for azure-cli and azure-cli-extensions repos. They could help you run required checks before creating the PR. Please sync the latest code with latest dev branch (for azure-cli) or main branch (for azure-cli-extensions). pip install azdev --upgrade
azdev setup -c <your azure-cli repo path> -r <your azure-cli-extensions repo path>
|
|
Thank you for your contribution! We will review the pull request and get back to you soon. |
There was a problem hiding this comment.
Pull request overview
This PR updates the Azure CLI core parser spellchecker unit test to construct the command parser in a way that matches the real runtime setup, avoiding Python 3.14 argparse default prog differences under pytest that impacted dynamic extension install behavior in the test.
Changes:
- Create and use a “global” parent parser in the test (via
create_global_parser(cli_ctx=cli)). - Instantiate the main parser with an explicit
prog=cli.name. - Pass the global parser through
parents=[global_parser]so command parsers inherit the same global args structure as production.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| parser = cli.parser_cls(cli) | ||
| global_parser = cli.parser_cls.create_global_parser(cli_ctx=cli) | ||
| parser = cli.parser_cls(cli, prog=cli.name, parents=[global_parser]) |
There was a problem hiding this comment.
What's the error before this change?
There was a problem hiding this comment.
2026-05-05T01:31:44.9051924Z # test dynamic extension install
2026-05-05T01:31:44.9052399Z with mock.patch.object(logging.Logger, 'error', mock_log_error), \
2026-05-05T01:31:44.9052993Z mock.patch.object(azure.cli.core.extension.operations, 'add_extension', mock_add_extension), \
2026-05-05T01:31:44.9053659Z mock.patch.object(azure.cli.core.extension.dynamic_install, '_get_extension_command_tree',
2026-05-05T01:31:44.9054193Z mock_ext_cmd_tree_load), \
2026-05-05T01:31:44.9054759Z mock.patch.object(azure.cli.core.extension.dynamic_install, '_get_extension_use_dynamic_install_config',
2026-05-05T01:31:44.9055326Z return_value='yes_without_prompt'), \
2026-05-05T01:31:44.9055825Z mock.patch.object(azure.cli.core.extension.dynamic_install,
2026-05-05T01:31:44.9056515Z '_get_extension_run_after_dynamic_install_config', return_value=False):
2026-05-05T01:31:44.9057035Z with self.assertRaises(SystemExit):
2026-05-05T01:31:44.9057570Z parser.parse_args('test new-ext create --opt enum_2'.split())
2026-05-05T01:31:44.9058144Z > self.assertIn("Extension new-ext-name installed. Please rerun your command.", logger_msgs[5])
2026-05-05T01:31:44.9058862Z E AssertionError: 'Extension new-ext-name installed. Please rerun your command.' not found in "'new-ext' is misspelled or not recognized by the system."
2026-05-05T01:31:44.9059213Z
2026-05-05T01:31:44.9059685Z src/azure-cli-core/azure/cli/core/tests/test_parser.py:271: AssertionError
Under Python 3.14, argparse changed the default prog to reflect how __main__ was actually invoked. Under pytest, instead of az, self.prog became something like __main__.py or a full invocation path.
This matters because parser.py line 298 builds the args list as:
args = self.prog.split() + self._raw_arguments_check_value_in_extensions then calls roughly_parse_command(args[1:]), which assumes args[0] is always the single token az. When self.prog was a multi-token string, self.prog.split() produced multiple elements, args[1:] skipped the wrong token, and command_str was computed incorrectly. That caused _search_in_extension_commands to miss new-ext in the mocked command tree — the dynamic install path was never triggered. The parser fell through to the spellchecker and logged:
'new-ext' is misspelled or not recognized by the system.
instead of the expected:
Extension new-ext-name installed. Please rerun your command.
The fix sets prog=cli.name explicitly (always az), matching what production always does, so self.prog.split() is reliably ['az'] regardless of how pytest launched the process.
Summary
This updates the parser spellchecker test to construct the parser the same way production does, with an explicit
progvalue and the global parser parent.Why
Python 3.14 changed
argparsedefaultprogbehavior to reflect how__main__was actually executed. In this test, the parser was being created without an explicitprog, so the effectiveprogdiffered between Python 3.13 and Python 3.14 underpytest.That difference leaked into the dynamic extension install path and made the test fail on Python 3.14 even though production code always sets
progexplicitly.What changed
prog=cli.nameparentsto match the real runtime setupThis is a test-only fix. No product behavior is changed.
Validation
python -m pytest src/azure-cli-core/azure/cli/core/tests/test_parser.py -k test_parser_error_spellchecker -qpython -m pytest src/azure-cli-core/azure/cli/core/tests/test_parser.py -k test_parser_error_spellchecker -qNotes
This keeps the test focused on parser spellchecking and dynamic extension install behavior, instead of depending on interpreter-specific
argparsedefaults.