summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniƫl van Noord <13665637+DanielNoord@users.noreply.github.com>2022-06-03 10:54:57 +0200
committerPierre Sassoulas <pierre.sassoulas@gmail.com>2022-06-06 22:27:46 +0200
commit2f785dd52a999e880e5b4dc851365ad80c466865 (patch)
tree4c884a919c0dbc7f567a1e1d220951fe9eee5fa9
parent679d739d065419a952737eaf1507c83f675c5186 (diff)
downloadpylint-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.rst4
-rw-r--r--pylint/config/utils.py43
-rw-r--r--tests/config/test_find_default_config_files.py15
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",
[