From 99a40d88e8b998ad3a1e322e44500c41d5f8a5a4 Mon Sep 17 00:00:00 2001 From: chloegoh Date: Mon, 11 Apr 2022 22:49:59 -0400 Subject: [PATCH 1/7] Add subcommand alias mechanism --- src/pip/_internal/cli/autocompletion.py | 4 +-- src/pip/_internal/cli/main_parser.py | 21 ++++---------- src/pip/_internal/commands/__init__.py | 37 +++++++++++++++++++++++-- src/pip/_internal/commands/help.py | 17 ++---------- tests/functional/test_help.py | 4 +-- tests/lib/options_helpers.py | 12 +++++++- tests/unit/test_commands.py | 15 ++++++++-- 7 files changed, 69 insertions(+), 41 deletions(-) diff --git a/src/pip/_internal/cli/autocompletion.py b/src/pip/_internal/cli/autocompletion.py index 226fe84dc0d..0f2c4b2b9a7 100644 --- a/src/pip/_internal/cli/autocompletion.py +++ b/src/pip/_internal/cli/autocompletion.py @@ -8,7 +8,7 @@ from typing import Any, Iterable, List, Optional from pip._internal.cli.main_parser import create_main_parser -from pip._internal.commands import commands_dict, create_command +from pip._internal.commands import create_command, subcommands_set from pip._internal.metadata import get_default_environment @@ -25,7 +25,7 @@ def autocomplete() -> None: current = "" parser = create_main_parser() - subcommands = list(commands_dict) + subcommands = list(subcommands_set) options = [] # subcommand diff --git a/src/pip/_internal/cli/main_parser.py b/src/pip/_internal/cli/main_parser.py index 3666ab04ca6..f8195d54a16 100644 --- a/src/pip/_internal/cli/main_parser.py +++ b/src/pip/_internal/cli/main_parser.py @@ -7,8 +7,7 @@ from pip._internal.cli import cmdoptions from pip._internal.cli.parser import ConfigOptionParser, UpdatingDefaultsHelpFormatter -from pip._internal.commands import commands_dict, get_similar_commands -from pip._internal.exceptions import CommandError +from pip._internal.commands import aliases_of_commands, check_subcommand, commands_dict from pip._internal.utils.misc import get_pip_version, get_prog __all__ = ["create_main_parser", "parse_command"] @@ -36,10 +35,10 @@ def create_main_parser() -> ConfigOptionParser: parser.main = True # type: ignore # create command listing for description - description = [""] + [ - f"{name:27} {command_info.summary}" - for name, command_info in commands_dict.items() - ] + description = [''] + for name, info in commands_dict.items(): + names = ', '.join(aliases_of_commands[name]) + description.append('{:27} {.summary}'.format(names, info)) parser.description = "\n".join(description) return parser @@ -70,15 +69,7 @@ def parse_command(args: List[str]) -> Tuple[str, List[str]]: # the subcommand name cmd_name = args_else[0] - - if cmd_name not in commands_dict: - guess = get_similar_commands(cmd_name) - - msg = [f'unknown command "{cmd_name}"'] - if guess: - msg.append(f'maybe you meant "{guess}"') - - raise CommandError(" - ".join(msg)) + check_subcommand(cmd_name) # all the args without the subcommand cmd_args = args[:] diff --git a/src/pip/_internal/commands/__init__.py b/src/pip/_internal/commands/__init__.py index c72f24f30e2..ed6ea74700c 100644 --- a/src/pip/_internal/commands/__init__.py +++ b/src/pip/_internal/commands/__init__.py @@ -4,9 +4,10 @@ import importlib from collections import namedtuple -from typing import Any, Dict, Optional +from typing import Any, Dict, List, Optional, Set from pip._internal.cli.base_command import Command +from pip._internal.exceptions import CommandError CommandInfo = namedtuple("CommandInfo", "module_path, class_name, summary") @@ -101,11 +102,30 @@ } +aliases_dict = { + 'add': 'install', + 'i': 'install', + 'remove': 'uninstall', + 'u': 'uninstall' +} # type: Dict[str, str] + +aliases_of_commands = { + name: [name] for name in commands_dict} # type: Dict[str, List[str]] +for alias, name in aliases_dict.items(): + aliases_of_commands[name].append(alias) + +subcommands_set = {cmd for aliases in aliases_of_commands.values() + for cmd in aliases} # type: Set[str] + + def create_command(name: str, **kwargs: Any) -> Command: """ Create an instance of the Command class with the given name. """ - module_path, class_name, summary = commands_dict[name] + try: + module_path, class_name, summary = commands_dict[name] + except KeyError: + module_path, class_name, summary = commands_dict[aliases_dict[name]] module = importlib.import_module(module_path) command_class = getattr(module, class_name) command = command_class(name=name, summary=summary, **kwargs) @@ -119,9 +139,20 @@ def get_similar_commands(name: str) -> Optional[str]: name = name.lower() - close_commands = get_close_matches(name, commands_dict.keys()) + close_commands = get_close_matches(name, subcommands_set) if close_commands: return close_commands[0] else: return None + + +def check_subcommand(name): + # type: (str) -> None + """Raise CommandError if the given subcommand not found.""" + if name not in aliases_dict and name not in commands_dict: + guess = get_similar_commands(name) + msg = 'unknown command "{}"'.format(name) + if guess: + msg += ' - maybe you meant "{}"'.format(guess) + raise CommandError(msg) diff --git a/src/pip/_internal/commands/help.py b/src/pip/_internal/commands/help.py index 62066318b74..ddff90698d4 100644 --- a/src/pip/_internal/commands/help.py +++ b/src/pip/_internal/commands/help.py @@ -3,7 +3,6 @@ from pip._internal.cli.base_command import Command from pip._internal.cli.status_codes import SUCCESS -from pip._internal.exceptions import CommandError class HelpCommand(Command): @@ -14,11 +13,7 @@ class HelpCommand(Command): ignore_require_venv = True def run(self, options: Values, args: List[str]) -> int: - from pip._internal.commands import ( - commands_dict, - create_command, - get_similar_commands, - ) + from pip._internal.commands import check_subcommand, create_command try: # 'pip help' with no args is handled by pip.__init__.parseopt() @@ -26,15 +21,7 @@ def run(self, options: Values, args: List[str]) -> int: except IndexError: return SUCCESS - if cmd_name not in commands_dict: - guess = get_similar_commands(cmd_name) - - msg = [f'unknown command "{cmd_name}"'] - if guess: - msg.append(f'maybe you meant "{guess}"') - - raise CommandError(" - ".join(msg)) - + check_subcommand(cmd_name) command = create_command(cmd_name) command.parser.print_help() diff --git a/tests/functional/test_help.py b/tests/functional/test_help.py index dba41af5f79..848775ab6ab 100644 --- a/tests/functional/test_help.py +++ b/tests/functional/test_help.py @@ -3,7 +3,7 @@ import pytest from pip._internal.cli.status_codes import ERROR, SUCCESS -from pip._internal.commands import commands_dict, create_command +from pip._internal.commands import create_command, subcommands_set from pip._internal.exceptions import CommandError from tests.conftest import InMemoryPip from tests.lib import PipTestEnvironment @@ -110,7 +110,7 @@ def test_help_commands_equally_functional(in_memory_pip: InMemoryPip) -> None: assert sum(ret) == 0, "exit codes of: " + msg assert all(len(o) > 0 for o in out) - for name in commands_dict: + for name in subcommands_set: assert ( in_memory_pip.pip("help", name).stdout == in_memory_pip.pip(name, "--help").stdout diff --git a/tests/lib/options_helpers.py b/tests/lib/options_helpers.py index 31f65003545..8b4f04c14cc 100644 --- a/tests/lib/options_helpers.py +++ b/tests/lib/options_helpers.py @@ -6,7 +6,12 @@ from pip._internal.cli import cmdoptions from pip._internal.cli.base_command import Command -from pip._internal.commands import CommandInfo, commands_dict +from pip._internal.commands import ( + CommandInfo, + aliases_of_commands, + commands_dict, + subcommands_set, +) class FakeCommand(Command): @@ -29,5 +34,10 @@ def setup(self) -> None: "fake summary", ) + aliases_of_commands['fake'] = ['fake'] + subcommands_set.add('fake') + def teardown(self) -> None: commands_dict.pop("fake") + aliases_of_commands.pop('fake') + subcommands_set.remove('fake') diff --git a/tests/unit/test_commands.py b/tests/unit/test_commands.py index 7a5c4e8319d..8d3061d06e9 100644 --- a/tests/unit/test_commands.py +++ b/tests/unit/test_commands.py @@ -9,7 +9,12 @@ RequirementCommand, SessionCommandMixin, ) -from pip._internal.commands import commands_dict, create_command +from pip._internal.commands import ( + aliases_dict, + commands_dict, + create_command, + subcommands_set, +) # These are the expected names of the commands whose classes inherit from # IndexGroupCommand. @@ -36,12 +41,16 @@ def test_commands_dict__order() -> None: assert names[-1] == "help" -@pytest.mark.parametrize("name", list(commands_dict)) +@pytest.mark.parametrize('name', subcommands_set) def test_create_command(name: str) -> None: """Test creating an instance of each available command.""" command = create_command(name) assert command.name == name - assert command.summary == commands_dict[name].summary + try: + summary = commands_dict[name].summary + except KeyError: + summary = commands_dict[aliases_dict[name]].summary + assert command.summary == summary def test_session_commands() -> None: From 4873f406a1470c1ec141cc6c5f226ce12feb3551 Mon Sep 17 00:00:00 2001 From: chloegoh Date: Mon, 11 Apr 2022 23:24:09 -0400 Subject: [PATCH 2/7] Add news entry --- news/8130.feature.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 news/8130.feature.rst diff --git a/news/8130.feature.rst b/news/8130.feature.rst new file mode 100644 index 00000000000..fa127d73236 --- /dev/null +++ b/news/8130.feature.rst @@ -0,0 +1,2 @@ +Add 'add' and 'i' aliases for 'install', 'remove' and 'u' aliases for +'uninstall'. \ No newline at end of file From c394bf6c0d70f4bd1da0dcecb23d309cf525154e Mon Sep 17 00:00:00 2001 From: Martin Fischer Date: Tue, 12 Apr 2022 22:02:41 +0200 Subject: [PATCH 3/7] Fix RST admonition & add missing inline code formatting (#10747) --- docs/html/user_guide.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/html/user_guide.rst b/docs/html/user_guide.rst index aa5d41c8cfe..13e8ec42347 100644 --- a/docs/html/user_guide.rst +++ b/docs/html/user_guide.rst @@ -17,7 +17,7 @@ to your system, which can be run from the command prompt as follows: ``python -m pip`` executes pip using the Python interpreter you specified as python. So ``/usr/bin/python3.7 -m pip`` means - you are executing pip for your interpreter located at /usr/bin/python3.7. + you are executing pip for your interpreter located at ``/usr/bin/python3.7``. .. tab:: Windows @@ -629,7 +629,7 @@ Moreover, the "user scheme" can be customized by setting the ``PYTHONUSERBASE`` environment variable, which updates the value of ``site.USER_BASE``. -To install "SomePackage" into an environment with site.USER_BASE customized to +To install "SomePackage" into an environment with ``site.USER_BASE`` customized to '/myappenv', do the following: .. tab:: Unix/macOS From e4376ed128592e1d22cdc9e842d3e1fd8334a207 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Edgar=20Ram=C3=ADrez?= Date: Wed, 13 Apr 2022 01:25:43 +0200 Subject: [PATCH 4/7] docs: Add section on PEP 508 support for build system requirements (#10735) --- docs/html/reference/build-system/pyproject-toml.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/html/reference/build-system/pyproject-toml.md b/docs/html/reference/build-system/pyproject-toml.md index ee93df034a7..7959a2d081f 100644 --- a/docs/html/reference/build-system/pyproject-toml.md +++ b/docs/html/reference/build-system/pyproject-toml.md @@ -49,6 +49,14 @@ hook will be called by pip, and dependencies it describes will also be installed in the build environment. For example, newer versions of setuptools expose the contents of `setup_requires` to pip via this hook. +Build-time requirement specifiers follow {pep}`508`, so it's possible to +reference packages with URLs. For example: + +```toml +[build-system] +requires = ["setuptools @ git+https://github.com/pypa/setuptools.git@main"] +``` + ### Metadata Generation ```{versionadded} 19.0 From cbce333245389ae051f2ed568b6270a41e5d7d97 Mon Sep 17 00:00:00 2001 From: chloegoh Date: Mon, 11 Apr 2022 22:49:59 -0400 Subject: [PATCH 5/7] Add subcommand alias mechanism --- src/pip/_internal/cli/autocompletion.py | 4 +-- src/pip/_internal/cli/main_parser.py | 21 ++++---------- src/pip/_internal/commands/__init__.py | 37 +++++++++++++++++++++++-- src/pip/_internal/commands/help.py | 17 ++---------- tests/functional/test_help.py | 4 +-- tests/lib/options_helpers.py | 12 +++++++- tests/unit/test_commands.py | 15 ++++++++-- 7 files changed, 69 insertions(+), 41 deletions(-) diff --git a/src/pip/_internal/cli/autocompletion.py b/src/pip/_internal/cli/autocompletion.py index 226fe84dc0d..0f2c4b2b9a7 100644 --- a/src/pip/_internal/cli/autocompletion.py +++ b/src/pip/_internal/cli/autocompletion.py @@ -8,7 +8,7 @@ from typing import Any, Iterable, List, Optional from pip._internal.cli.main_parser import create_main_parser -from pip._internal.commands import commands_dict, create_command +from pip._internal.commands import create_command, subcommands_set from pip._internal.metadata import get_default_environment @@ -25,7 +25,7 @@ def autocomplete() -> None: current = "" parser = create_main_parser() - subcommands = list(commands_dict) + subcommands = list(subcommands_set) options = [] # subcommand diff --git a/src/pip/_internal/cli/main_parser.py b/src/pip/_internal/cli/main_parser.py index 3666ab04ca6..f8195d54a16 100644 --- a/src/pip/_internal/cli/main_parser.py +++ b/src/pip/_internal/cli/main_parser.py @@ -7,8 +7,7 @@ from pip._internal.cli import cmdoptions from pip._internal.cli.parser import ConfigOptionParser, UpdatingDefaultsHelpFormatter -from pip._internal.commands import commands_dict, get_similar_commands -from pip._internal.exceptions import CommandError +from pip._internal.commands import aliases_of_commands, check_subcommand, commands_dict from pip._internal.utils.misc import get_pip_version, get_prog __all__ = ["create_main_parser", "parse_command"] @@ -36,10 +35,10 @@ def create_main_parser() -> ConfigOptionParser: parser.main = True # type: ignore # create command listing for description - description = [""] + [ - f"{name:27} {command_info.summary}" - for name, command_info in commands_dict.items() - ] + description = [''] + for name, info in commands_dict.items(): + names = ', '.join(aliases_of_commands[name]) + description.append('{:27} {.summary}'.format(names, info)) parser.description = "\n".join(description) return parser @@ -70,15 +69,7 @@ def parse_command(args: List[str]) -> Tuple[str, List[str]]: # the subcommand name cmd_name = args_else[0] - - if cmd_name not in commands_dict: - guess = get_similar_commands(cmd_name) - - msg = [f'unknown command "{cmd_name}"'] - if guess: - msg.append(f'maybe you meant "{guess}"') - - raise CommandError(" - ".join(msg)) + check_subcommand(cmd_name) # all the args without the subcommand cmd_args = args[:] diff --git a/src/pip/_internal/commands/__init__.py b/src/pip/_internal/commands/__init__.py index c72f24f30e2..ed6ea74700c 100644 --- a/src/pip/_internal/commands/__init__.py +++ b/src/pip/_internal/commands/__init__.py @@ -4,9 +4,10 @@ import importlib from collections import namedtuple -from typing import Any, Dict, Optional +from typing import Any, Dict, List, Optional, Set from pip._internal.cli.base_command import Command +from pip._internal.exceptions import CommandError CommandInfo = namedtuple("CommandInfo", "module_path, class_name, summary") @@ -101,11 +102,30 @@ } +aliases_dict = { + 'add': 'install', + 'i': 'install', + 'remove': 'uninstall', + 'u': 'uninstall' +} # type: Dict[str, str] + +aliases_of_commands = { + name: [name] for name in commands_dict} # type: Dict[str, List[str]] +for alias, name in aliases_dict.items(): + aliases_of_commands[name].append(alias) + +subcommands_set = {cmd for aliases in aliases_of_commands.values() + for cmd in aliases} # type: Set[str] + + def create_command(name: str, **kwargs: Any) -> Command: """ Create an instance of the Command class with the given name. """ - module_path, class_name, summary = commands_dict[name] + try: + module_path, class_name, summary = commands_dict[name] + except KeyError: + module_path, class_name, summary = commands_dict[aliases_dict[name]] module = importlib.import_module(module_path) command_class = getattr(module, class_name) command = command_class(name=name, summary=summary, **kwargs) @@ -119,9 +139,20 @@ def get_similar_commands(name: str) -> Optional[str]: name = name.lower() - close_commands = get_close_matches(name, commands_dict.keys()) + close_commands = get_close_matches(name, subcommands_set) if close_commands: return close_commands[0] else: return None + + +def check_subcommand(name): + # type: (str) -> None + """Raise CommandError if the given subcommand not found.""" + if name not in aliases_dict and name not in commands_dict: + guess = get_similar_commands(name) + msg = 'unknown command "{}"'.format(name) + if guess: + msg += ' - maybe you meant "{}"'.format(guess) + raise CommandError(msg) diff --git a/src/pip/_internal/commands/help.py b/src/pip/_internal/commands/help.py index 62066318b74..ddff90698d4 100644 --- a/src/pip/_internal/commands/help.py +++ b/src/pip/_internal/commands/help.py @@ -3,7 +3,6 @@ from pip._internal.cli.base_command import Command from pip._internal.cli.status_codes import SUCCESS -from pip._internal.exceptions import CommandError class HelpCommand(Command): @@ -14,11 +13,7 @@ class HelpCommand(Command): ignore_require_venv = True def run(self, options: Values, args: List[str]) -> int: - from pip._internal.commands import ( - commands_dict, - create_command, - get_similar_commands, - ) + from pip._internal.commands import check_subcommand, create_command try: # 'pip help' with no args is handled by pip.__init__.parseopt() @@ -26,15 +21,7 @@ def run(self, options: Values, args: List[str]) -> int: except IndexError: return SUCCESS - if cmd_name not in commands_dict: - guess = get_similar_commands(cmd_name) - - msg = [f'unknown command "{cmd_name}"'] - if guess: - msg.append(f'maybe you meant "{guess}"') - - raise CommandError(" - ".join(msg)) - + check_subcommand(cmd_name) command = create_command(cmd_name) command.parser.print_help() diff --git a/tests/functional/test_help.py b/tests/functional/test_help.py index dba41af5f79..848775ab6ab 100644 --- a/tests/functional/test_help.py +++ b/tests/functional/test_help.py @@ -3,7 +3,7 @@ import pytest from pip._internal.cli.status_codes import ERROR, SUCCESS -from pip._internal.commands import commands_dict, create_command +from pip._internal.commands import create_command, subcommands_set from pip._internal.exceptions import CommandError from tests.conftest import InMemoryPip from tests.lib import PipTestEnvironment @@ -110,7 +110,7 @@ def test_help_commands_equally_functional(in_memory_pip: InMemoryPip) -> None: assert sum(ret) == 0, "exit codes of: " + msg assert all(len(o) > 0 for o in out) - for name in commands_dict: + for name in subcommands_set: assert ( in_memory_pip.pip("help", name).stdout == in_memory_pip.pip(name, "--help").stdout diff --git a/tests/lib/options_helpers.py b/tests/lib/options_helpers.py index 31f65003545..8b4f04c14cc 100644 --- a/tests/lib/options_helpers.py +++ b/tests/lib/options_helpers.py @@ -6,7 +6,12 @@ from pip._internal.cli import cmdoptions from pip._internal.cli.base_command import Command -from pip._internal.commands import CommandInfo, commands_dict +from pip._internal.commands import ( + CommandInfo, + aliases_of_commands, + commands_dict, + subcommands_set, +) class FakeCommand(Command): @@ -29,5 +34,10 @@ def setup(self) -> None: "fake summary", ) + aliases_of_commands['fake'] = ['fake'] + subcommands_set.add('fake') + def teardown(self) -> None: commands_dict.pop("fake") + aliases_of_commands.pop('fake') + subcommands_set.remove('fake') diff --git a/tests/unit/test_commands.py b/tests/unit/test_commands.py index 7a5c4e8319d..8d3061d06e9 100644 --- a/tests/unit/test_commands.py +++ b/tests/unit/test_commands.py @@ -9,7 +9,12 @@ RequirementCommand, SessionCommandMixin, ) -from pip._internal.commands import commands_dict, create_command +from pip._internal.commands import ( + aliases_dict, + commands_dict, + create_command, + subcommands_set, +) # These are the expected names of the commands whose classes inherit from # IndexGroupCommand. @@ -36,12 +41,16 @@ def test_commands_dict__order() -> None: assert names[-1] == "help" -@pytest.mark.parametrize("name", list(commands_dict)) +@pytest.mark.parametrize('name', subcommands_set) def test_create_command(name: str) -> None: """Test creating an instance of each available command.""" command = create_command(name) assert command.name == name - assert command.summary == commands_dict[name].summary + try: + summary = commands_dict[name].summary + except KeyError: + summary = commands_dict[aliases_dict[name]].summary + assert command.summary == summary def test_session_commands() -> None: From a8fe05dfe5664517009df0e713f7e3f76e38735d Mon Sep 17 00:00:00 2001 From: chloegoh Date: Mon, 11 Apr 2022 23:24:09 -0400 Subject: [PATCH 6/7] Add news entry --- news/8130.feature.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 news/8130.feature.rst diff --git a/news/8130.feature.rst b/news/8130.feature.rst new file mode 100644 index 00000000000..fa127d73236 --- /dev/null +++ b/news/8130.feature.rst @@ -0,0 +1,2 @@ +Add 'add' and 'i' aliases for 'install', 'remove' and 'u' aliases for +'uninstall'. \ No newline at end of file From 7f254ca6199a0e5b56762cf259471ee46677748d Mon Sep 17 00:00:00 2001 From: chloegoh Date: Tue, 12 Apr 2022 20:23:47 -0400 Subject: [PATCH 7/7] Fix lint errors --- news/8130.feature.rst | 4 ++-- src/pip/_internal/cli/main_parser.py | 6 +++--- src/pip/_internal/commands/__init__.py | 16 +++++++++------- tests/lib/options_helpers.py | 8 ++++---- tests/unit/test_commands.py | 2 +- 5 files changed, 19 insertions(+), 17 deletions(-) diff --git a/news/8130.feature.rst b/news/8130.feature.rst index fa127d73236..6a2f4bb0bc3 100644 --- a/news/8130.feature.rst +++ b/news/8130.feature.rst @@ -1,2 +1,2 @@ -Add 'add' and 'i' aliases for 'install', 'remove' and 'u' aliases for -'uninstall'. \ No newline at end of file +Add 'add' and 'i' aliases for 'install', 'remove' and 'u' aliases for +'uninstall'. diff --git a/src/pip/_internal/cli/main_parser.py b/src/pip/_internal/cli/main_parser.py index f8195d54a16..6b96302a2cb 100644 --- a/src/pip/_internal/cli/main_parser.py +++ b/src/pip/_internal/cli/main_parser.py @@ -35,10 +35,10 @@ def create_main_parser() -> ConfigOptionParser: parser.main = True # type: ignore # create command listing for description - description = [''] + description = [""] for name, info in commands_dict.items(): - names = ', '.join(aliases_of_commands[name]) - description.append('{:27} {.summary}'.format(names, info)) + names = ", ".join(aliases_of_commands[name]) + description.append("{:27} {.summary}".format(names, info)) parser.description = "\n".join(description) return parser diff --git a/src/pip/_internal/commands/__init__.py b/src/pip/_internal/commands/__init__.py index ed6ea74700c..aaac18a1827 100644 --- a/src/pip/_internal/commands/__init__.py +++ b/src/pip/_internal/commands/__init__.py @@ -103,19 +103,21 @@ aliases_dict = { - 'add': 'install', - 'i': 'install', - 'remove': 'uninstall', - 'u': 'uninstall' + "add": "install", + "i": "install", + "remove": "uninstall", + "u": "uninstall", } # type: Dict[str, str] aliases_of_commands = { - name: [name] for name in commands_dict} # type: Dict[str, List[str]] + name: [name] for name in commands_dict +} # type: Dict[str, List[str]] for alias, name in aliases_dict.items(): aliases_of_commands[name].append(alias) -subcommands_set = {cmd for aliases in aliases_of_commands.values() - for cmd in aliases} # type: Set[str] +subcommands_set = { + cmd for aliases in aliases_of_commands.values() for cmd in aliases +} # type: Set[str] def create_command(name: str, **kwargs: Any) -> Command: diff --git a/tests/lib/options_helpers.py b/tests/lib/options_helpers.py index 8b4f04c14cc..dcb78023393 100644 --- a/tests/lib/options_helpers.py +++ b/tests/lib/options_helpers.py @@ -34,10 +34,10 @@ def setup(self) -> None: "fake summary", ) - aliases_of_commands['fake'] = ['fake'] - subcommands_set.add('fake') + aliases_of_commands["fake"] = ["fake"] + subcommands_set.add("fake") def teardown(self) -> None: commands_dict.pop("fake") - aliases_of_commands.pop('fake') - subcommands_set.remove('fake') + aliases_of_commands.pop("fake") + subcommands_set.remove("fake") diff --git a/tests/unit/test_commands.py b/tests/unit/test_commands.py index 8d3061d06e9..e3905dbf0dd 100644 --- a/tests/unit/test_commands.py +++ b/tests/unit/test_commands.py @@ -41,7 +41,7 @@ def test_commands_dict__order() -> None: assert names[-1] == "help" -@pytest.mark.parametrize('name', subcommands_set) +@pytest.mark.parametrize("name", subcommands_set) def test_create_command(name: str) -> None: """Test creating an instance of each available command.""" command = create_command(name)