diff options
-rw-r--r-- | CONTRIBUTORS.txt | 1 | ||||
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | doc/whatsnew/2.13.rst | 4 | ||||
-rw-r--r-- | pylint/utils/pragma_parser.py | 23 | ||||
-rw-r--r-- | tests/checkers/unittest_refactoring.py | 15 | ||||
-rw-r--r-- | tests/regrtest_data/issue_5724.py | 1 |
6 files changed, 37 insertions, 11 deletions
diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 01c49f1b7..989f9297d 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -355,3 +355,4 @@ contributors: - Daniel Brookman - Téo Bouvard - Konrad Weihmann +- Sergey B Kirpichev @@ -201,6 +201,10 @@ Release date: TBA Closes #5569 +* Optimize parsing of long lines when ``missing-final-newline`` is enabled. + + Closes #5724 + * Fix false positives for ``used-before-assignment`` from using named expressions in a ternary operator test and using that expression as a call argument. diff --git a/doc/whatsnew/2.13.rst b/doc/whatsnew/2.13.rst index 629798f42..d0696f1db 100644 --- a/doc/whatsnew/2.13.rst +++ b/doc/whatsnew/2.13.rst @@ -261,6 +261,10 @@ Other Changes Closes #5771 Ref PyCQA/astroid#1382 +* Optimize parsing of long lines when ``missing-final-newline`` is enabled. + + Closes #5724 + * Fix ``unnecessary_dict_index_lookup`` false positive when deleting a dictionary's entry. Closes #4716 diff --git a/pylint/utils/pragma_parser.py b/pylint/utils/pragma_parser.py index 0bf25de7c..e09cba7c9 100644 --- a/pylint/utils/pragma_parser.py +++ b/pylint/utils/pragma_parser.py @@ -9,17 +9,18 @@ from typing import Generator, List, Optional # so that an option can be continued with the reasons # why it is active or disabled. OPTION_RGX = r""" - \s* # Any number of whitespace - \#? # One or zero hash - .* # Anything (as much as possible) - (\s* # Beginning of first matched group and any number of whitespaces - \# # Beginning of comment - .*? # Anything (as little as possible) - \bpylint: # pylint word and column - \s* # Any number of whitespaces - ([^;#\n]+)) # Anything except semicolon or hash or newline (it is the second matched group) - # and end of the first matched group - [;#]{0,1}""" # From 0 to 1 repetition of semicolon or hash + (?:^\s*\#.*|\s*| # Comment line, or whitespaces, + \s*\#.*(?=\#.*?\bpylint:)) # or a beginning of an inline comment + # followed by "pylint:" pragma + (\# # Beginning of comment + .*? # Anything (as little as possible) + \bpylint: # pylint word and column + \s* # Any number of whitespaces + ([^;#\n]+)) # Anything except semicolon or hash or + # newline (it is the second matched group) + # and end of the first matched group + [;#]{0,1} # From 0 to 1 repetition of semicolon or hash +""" OPTION_PO = re.compile(OPTION_RGX, re.VERBOSE) diff --git a/tests/checkers/unittest_refactoring.py b/tests/checkers/unittest_refactoring.py index a2694200b..760eb2fe8 100644 --- a/tests/checkers/unittest_refactoring.py +++ b/tests/checkers/unittest_refactoring.py @@ -32,3 +32,18 @@ def test_process_tokens() -> None: with pytest.raises(SystemExit) as cm: Run([os.path.join(REGR_DATA, "very_long_line.py")], reporter=TextReporter()) assert cm.value.code == 0 + + +@pytest.mark.skipif(not hasattr(signal, "setitimer"), reason="Assumes POSIX signals") +def test_issue_5724() -> None: + """Regression test for parsing of pylint disable pragma's.""" + with timeout(25.0): + with pytest.raises(SystemExit) as cm: + Run( + [ + os.path.join(REGR_DATA, "issue_5724.py"), + "--enable=missing-final-newline", + ], + reporter=TextReporter(), + ) + assert cm.value.code == 0 diff --git a/tests/regrtest_data/issue_5724.py b/tests/regrtest_data/issue_5724.py new file mode 100644 index 000000000..dad184c43 --- /dev/null +++ b/tests/regrtest_data/issue_5724.py @@ -0,0 +1 @@ +a = "a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #a #" |