diff options
author | Daniƫl van Noord <13665637+DanielNoord@users.noreply.github.com> | 2022-06-03 10:54:57 +0200 |
---|---|---|
committer | Pierre Sassoulas <pierre.sassoulas@gmail.com> | 2022-06-06 22:27:46 +0200 |
commit | 2f785dd52a999e880e5b4dc851365ad80c466865 (patch) | |
tree | 4c884a919c0dbc7f567a1e1d220951fe9eee5fa9 | |
parent | 679d739d065419a952737eaf1507c83f675c5186 (diff) | |
download | pylint-git-2f785dd52a999e880e5b4dc851365ad80c466865.tar.gz |
Fix the use of abbreviations for preprocessable options on the CLI (#6820)
Co-authored-by: Pierre Sassoulas <pierre.sassoulas@gmail.com>
-rw-r--r-- | doc/whatsnew/2/2.14/full.rst | 4 | ||||
-rw-r--r-- | pylint/config/utils.py | 43 | ||||
-rw-r--r-- | tests/config/test_find_default_config_files.py | 15 |
3 files changed, 52 insertions, 10 deletions
diff --git a/doc/whatsnew/2/2.14/full.rst b/doc/whatsnew/2/2.14/full.rst index 937f56f19..25864d655 100644 --- a/doc/whatsnew/2/2.14/full.rst +++ b/doc/whatsnew/2/2.14/full.rst @@ -13,6 +13,10 @@ Release date: TBA Closes #6802 +* Fixed the use of abbreviations for some special options on the command line. + + Closes #6810 + What's New in Pylint 2.14.0? ---------------------------- diff --git a/pylint/config/utils.py b/pylint/config/utils.py index 1fa940165..6ad609789 100644 --- a/pylint/config/utils.py +++ b/pylint/config/utils.py @@ -201,16 +201,30 @@ def _enable_all_extensions(run: Run, value: str | None) -> None: PREPROCESSABLE_OPTIONS: dict[ - str, tuple[bool, Callable[[Run, str | None], None]] + str, tuple[bool, Callable[[Run, str | None], None], int] ] = { # pylint: disable=consider-using-namedtuple-or-dataclass - "--init-hook": (True, _init_hook), - "--rcfile": (True, _set_rcfile), - "--output": (True, _set_output), - "--load-plugins": (True, _add_plugins), - "--verbose": (False, _set_verbose_mode), - "-v": (False, _set_verbose_mode), - "--enable-all-extensions": (False, _enable_all_extensions), + # pylint: disable=wrong-spelling-in-comment + # Argparse by default allows abbreviations. It behaves differently + # if you turn this off, so we also turn it on. We mimick this + # by allowing some abbreviations or incorrect spelling here. + # The integer at the end of the tuple indicates how many letters + # should match, include the '-'. 0 indicates a full match. + # + # Clashes with --init-(import) + "--init-hook": (True, _init_hook, 8), + # Clashes with --r(ecursive) + "--rcfile": (True, _set_rcfile, 4), + # Clashes with --output(-format) + "--output": (True, _set_output, 0), + # Clashes with --lo(ng-help) + "--load-plugins": (True, _add_plugins, 5), + # Clashes with --v(ariable-rgx) + "--verbose": (False, _set_verbose_mode, 4), + "-v": (False, _set_verbose_mode, 2), + # Clashes with --enable + "--enable-all-extensions": (False, _enable_all_extensions, 9), } +# pylint: enable=wrong-spelling-in-comment def _preprocess_options(run: Run, args: Sequence[str]) -> list[str]: @@ -230,12 +244,21 @@ def _preprocess_options(run: Run, args: Sequence[str]) -> list[str]: except ValueError: option, value = argument, None - if option not in PREPROCESSABLE_OPTIONS: + matched_option = None + for option_name, data in PREPROCESSABLE_OPTIONS.items(): + to_match = data[2] + if to_match == 0: + if option == option_name: + matched_option = option_name + elif option.startswith(option_name[:to_match]): + matched_option = option_name + + if matched_option is None: processed_args.append(argument) i += 1 continue - takearg, cb = PREPROCESSABLE_OPTIONS[option] + takearg, cb, _ = PREPROCESSABLE_OPTIONS[matched_option] if takearg and value is None: i += 1 diff --git a/tests/config/test_find_default_config_files.py b/tests/config/test_find_default_config_files.py index cf588bdd7..9addb6db2 100644 --- a/tests/config/test_find_default_config_files.py +++ b/tests/config/test_find_default_config_files.py @@ -165,6 +165,21 @@ def test_verbose_output_no_config(capsys: CaptureFixture) -> None: assert "No config file found, using default configuration" in out.err +@pytest.mark.usefixtures("pop_pylintrc") +def test_verbose_abbreviation(capsys: CaptureFixture) -> None: + """Test that we correctly handle an abbreviated pre-processable option.""" + with tempdir() as chroot: + with fake_home(): + chroot_path = Path(chroot) + testutils.create_files(["a/b/c/d/__init__.py"]) + os.chdir(chroot_path / "a/b/c") + with pytest.raises(SystemExit): + Run(["--ve"]) + out = capsys.readouterr() + # This output only exists when launched in verbose mode + assert "No config file found, using default configuration" in out.err + + @pytest.mark.parametrize( "content,expected", [ |