Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix inconsistent argument exit code when argparse exit with its own error code #7931

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions doc/whatsnew/fragments/7931.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
When pylint exit due to bad arguments being provided the exit code will now be the expected ``32``.

Refs #7931
9 changes: 6 additions & 3 deletions pylint/config/arguments_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -256,9 +256,12 @@ def _load_default_argument_values(self) -> None:

def _parse_configuration_file(self, arguments: list[str]) -> None:
"""Parse the arguments found in a configuration file into the namespace."""
self.config, parsed_args = self._arg_parser.parse_known_args(
arguments, self.config
)
try:
self.config, parsed_args = self._arg_parser.parse_known_args(
arguments, self.config
)
except SystemExit:
sys.exit(32)
unrecognized_options: list[str] = []
for opt in parsed_args:
if opt.startswith("--"):
Expand Down
5 changes: 4 additions & 1 deletion pylint/config/config_initialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,10 @@ def _config_initialization(
unrecognized_options.append(opt[1:])
if unrecognized_options:
msg = ", ".join(unrecognized_options)
linter._arg_parser.error(f"Unrecognized option found: {msg}")
try:
linter._arg_parser.error(f"Unrecognized option found: {msg}")
except SystemExit:
sys.exit(32)

# Now that config file and command line options have been loaded
# with all disables, it is safe to emit messages
Expand Down
36 changes: 36 additions & 0 deletions tests/lint/test_run_pylint.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
# For details: https://github.com/PyCQA/pylint/blob/main/LICENSE
# Copyright (c) https://github.com/PyCQA/pylint/blob/main/CONTRIBUTORS.txt

from pathlib import Path

import pytest
from _pytest.capture import CaptureFixture

from pylint import run_pylint


def test_run_pylint_with_invalid_argument(capsys: CaptureFixture[str]) -> None:
"""Check that appropriate exit code is used with invalid argument."""
with pytest.raises(SystemExit) as ex:
run_pylint(["--never-use-this"])
captured = capsys.readouterr()
assert captured.err.startswith("usage: pylint [options]")
assert ex.value.code == 32


def test_run_pylint_with_invalid_argument_in_config(
capsys: CaptureFixture[str], tmp_path: Path
) -> None:
"""Check that appropriate exit code is used with an ambiguous
argument in a config file.
"""
test_file = tmp_path / "testpylintrc"
with open(test_file, "w", encoding="utf-8") as f:
f.write("[MASTER]\nno=")

with pytest.raises(SystemExit) as ex:
run_pylint(["--rcfile", f"{test_file}"])
captured = capsys.readouterr()
assert captured.err.startswith("usage: pylint [options]")
assert ex.value.code == 32
9 changes: 9 additions & 0 deletions tests/lint/unittest_expand_modules.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,14 @@ def test__is_in_ignore_list_re_match() -> None:
"path": str(TEST_DIRECTORY / "lint/test_utils.py"),
}

test_run_pylint = {
"basename": "lint",
"basepath": INIT_PATH,
"isarg": False,
"name": "lint.test_run_pylint",
"path": str(TEST_DIRECTORY / "lint/test_run_pylint.py"),
}

test_pylinter = {
"basename": "lint",
"basepath": INIT_PATH,
Expand Down Expand Up @@ -102,6 +110,7 @@ def _list_expected_package_modules(
init_of_package,
test_caching,
test_pylinter,
test_run_pylint,
test_utils,
this_file_from_init_deduplicated if deduplicating else this_file_from_init,
unittest_lint,
Expand Down