From a0a81d2b88c1bfc7088ac50ce84f9ba9706d9bda Mon Sep 17 00:00:00 2001 From: Pierre Sassoulas Date: Fri, 7 Jun 2024 07:14:00 +0200 Subject: [PATCH 1/3] [symilar] Fix crash when giving bad options to symilar --- doc/whatsnew/fragments/9343.bugfix | 3 +++ pylint/checkers/similar.py | 14 +++++++++++--- tests/checkers/unittest_similar.py | 29 +++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 doc/whatsnew/fragments/9343.bugfix diff --git a/doc/whatsnew/fragments/9343.bugfix b/doc/whatsnew/fragments/9343.bugfix new file mode 100644 index 0000000000..bdae77d6ff --- /dev/null +++ b/doc/whatsnew/fragments/9343.bugfix @@ -0,0 +1,3 @@ +Fixed a crash in ``symilar`` when the ``-d`` option was not properly recognized. + +Closes #9343 diff --git a/pylint/checkers/similar.py b/pylint/checkers/similar.py index cfe649b180..9423f053b4 100644 --- a/pylint/checkers/similar.py +++ b/pylint/checkers/similar.py @@ -39,7 +39,7 @@ import warnings from collections import defaultdict from collections.abc import Callable, Generator, Iterable, Sequence -from getopt import getopt +from getopt import GetoptError, getopt from io import BufferedIOBase, BufferedReader, BytesIO from itertools import chain from typing import ( @@ -920,10 +920,18 @@ def Run(argv: Sequence[str] | None = None) -> NoReturn: ignore_docstrings = False ignore_imports = False ignore_signatures = False - opts, args = getopt(list(argv), s_opts, l_opts) + try: + opts, args = getopt(list(argv), s_opts, l_opts) + except GetoptError as e: + print(e) + usage(2) for opt, val in opts: if opt in {"-d", "--duplicates"}: - min_lines = int(val) + try: + min_lines = int(val) + except ValueError as e: + print(e) + usage(2) elif opt in {"-h", "--help"}: usage() elif opt in {"-i", "--ignore-comments"}: diff --git a/tests/checkers/unittest_similar.py b/tests/checkers/unittest_similar.py index 8c00faee54..30279bf966 100644 --- a/tests/checkers/unittest_similar.py +++ b/tests/checkers/unittest_similar.py @@ -497,3 +497,32 @@ def test_set_duplicate_lines_to_zero() -> None: similar.Run(["--duplicates=0", SIMILAR1, SIMILAR2]) assert ex.value.code == 0 assert output.getvalue() == "" + + +@pytest.mark.parametrize("v", ["d", "i"]) +def test_bad_equal_short_form_option(v: str) -> None: + """Regression test for https://github.com/pylint-dev/pylint/issues/9343""" + output = StringIO() + with redirect_stdout(output), pytest.raises(SystemExit) as ex: + similar.Run([f"-{v}=0", SIMILAR1, SIMILAR2]) + assert ex.value.code == 2 + assert "option -= not recognized" in output.getvalue() + + +@pytest.mark.parametrize("v", ["i", "d"]) +def test_space_short_form_option(v: str) -> None: + """Regression test for https://github.com/pylint-dev/pylint/issues/9343""" + output = StringIO() + with redirect_stdout(output), pytest.raises(SystemExit) as ex: + similar.Run([f"-{v} 2", SIMILAR1, SIMILAR2]) + assert ex.value.code == 2 + assert "option - not recognized" in output.getvalue() + + +def test_bad_short_form_option() -> None: + """Regression test for https://github.com/pylint-dev/pylint/issues/9343""" + output = StringIO() + with redirect_stdout(output), pytest.raises(SystemExit) as ex: + similar.Run(["-j=0", SIMILAR1, SIMILAR2]) + assert ex.value.code == 2 + assert "option -j not recognized" in output.getvalue() From b310d3fa0140605c0282bb13cb3696245cee18d5 Mon Sep 17 00:00:00 2001 From: Pierre Sassoulas Date: Fri, 7 Jun 2024 08:10:12 +0200 Subject: [PATCH 2/3] [symilar] Fix the short form options that weren't being processed properly Closes #9343 --- doc/whatsnew/fragments/9343.bugfix | 3 ++- pylint/checkers/similar.py | 2 +- tests/checkers/unittest_similar.py | 8 ++++---- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/doc/whatsnew/fragments/9343.bugfix b/doc/whatsnew/fragments/9343.bugfix index bdae77d6ff..0a3a620809 100644 --- a/doc/whatsnew/fragments/9343.bugfix +++ b/doc/whatsnew/fragments/9343.bugfix @@ -1,3 +1,4 @@ -Fixed a crash in ``symilar`` when the ``-d`` option was not properly recognized. +Fixed a crash in ``symilar`` when the ``-d`` or ``-i`` short option were not properly recognized. +It's still impossible to do ``-d=1`` (you must do ``-d 1``). Closes #9343 diff --git a/pylint/checkers/similar.py b/pylint/checkers/similar.py index 9423f053b4..ada141da36 100644 --- a/pylint/checkers/similar.py +++ b/pylint/checkers/similar.py @@ -906,7 +906,7 @@ def Run(argv: Sequence[str] | None = None) -> NoReturn: if argv is None: argv = sys.argv[1:] - s_opts = "hdi" + s_opts = "hd:i:" l_opts = [ "help", "duplicates=", diff --git a/tests/checkers/unittest_similar.py b/tests/checkers/unittest_similar.py index 30279bf966..91a9e5e545 100644 --- a/tests/checkers/unittest_similar.py +++ b/tests/checkers/unittest_similar.py @@ -499,14 +499,14 @@ def test_set_duplicate_lines_to_zero() -> None: assert output.getvalue() == "" -@pytest.mark.parametrize("v", ["d", "i"]) +@pytest.mark.parametrize("v", ["d"]) def test_bad_equal_short_form_option(v: str) -> None: """Regression test for https://github.com/pylint-dev/pylint/issues/9343""" output = StringIO() with redirect_stdout(output), pytest.raises(SystemExit) as ex: similar.Run([f"-{v}=0", SIMILAR1, SIMILAR2]) assert ex.value.code == 2 - assert "option -= not recognized" in output.getvalue() + assert "invalid literal for int() with base 10: '=0'" in output.getvalue() @pytest.mark.parametrize("v", ["i", "d"]) @@ -515,8 +515,8 @@ def test_space_short_form_option(v: str) -> None: output = StringIO() with redirect_stdout(output), pytest.raises(SystemExit) as ex: similar.Run([f"-{v} 2", SIMILAR1, SIMILAR2]) - assert ex.value.code == 2 - assert "option - not recognized" in output.getvalue() + assert ex.value.code == 0 + assert "similar lines in" in output.getvalue() def test_bad_short_form_option() -> None: From e798acafdfcb933208e1e639257b3bc053c02fb1 Mon Sep 17 00:00:00 2001 From: Pierre Sassoulas Date: Fri, 7 Jun 2024 08:10:12 +0200 Subject: [PATCH 3/3] [symilar] Rename the unittest file that had a typo. --- tests/checkers/{unittest_similar.py => unittest_symilar.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename tests/checkers/{unittest_similar.py => unittest_symilar.py} (100%) diff --git a/tests/checkers/unittest_similar.py b/tests/checkers/unittest_symilar.py similarity index 100% rename from tests/checkers/unittest_similar.py rename to tests/checkers/unittest_symilar.py