# Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html # For details: https://github.com/pylint-dev/pylint/blob/main/LICENSE # Copyright (c) https://github.com/pylint-dev/pylint/blob/main/CONTRIBUTORS.txt import itertools import unicodedata from pathlib import Path from typing import cast import astroid import pytest from astroid import nodes import pylint.checkers.unicode import pylint.interfaces import pylint.testutils from . import FakeNode UNICODE_TESTS = Path(__file__).parent.parent.parent / "regrtest_data" / "unicode" class TestBidirectionalUnicodeChecker(pylint.testutils.CheckerTestCase): CHECKER_CLASS = pylint.checkers.unicode.UnicodeChecker checker: pylint.checkers.unicode.UnicodeChecker def test_finds_bidirectional_unicode_that_currently_not_parsed(self) -> None: """Test an example from https://github.com/nickboucher/trojan-source/tree/main/Python that is currently not working Python but producing a syntax error So we test this to make sure it stays like this """ test_file = UNICODE_TESTS / "invisible_function.txt" with pytest.raises(astroid.AstroidSyntaxError): astroid.MANAGER.ast_from_string(test_file.read_text("utf-8")) with pytest.raises(AssertionError): # The following errors are not risen at the moment, # But we keep this in order to allow writing the test fast, if # the condition above isn't met anymore. module = FakeNode(test_file.read_bytes()) with self.assertAddsMessages( pylint.testutils.MessageTest( msg_id="bidirectional-unicode", confidence=pylint.interfaces.HIGH, # node=module, line=6, end_line=10, col_offset=0, end_col_offset=17, ), pylint.testutils.MessageTest( msg_id="bidirectional-unicode", confidence=pylint.interfaces.HIGH, line=10, # node=module, end_line=10, col_offset=0, end_col_offset=20, ), ): self.checker.process_module(cast(nodes.Module, module)) @pytest.mark.parametrize( "bad_string, codec", [ pytest.param( char, codec, id=f"{unicodedata.name(char)}_{codec}".replace(" ", "_"), ) for char, codec in itertools.product( pylint.checkers.unicode.BIDI_UNICODE, ("utf-8", "utf-16le", "utf-16be", "utf-32le", "utf-32be"), ) ], ) def test_find_bidi_string(self, bad_string: str, codec: str) -> None: """Ensure that all Bidirectional strings are detected. Tests also UTF-16 and UTF-32. """ expected = pylint.testutils.MessageTest( msg_id="bidirectional-unicode", confidence=pylint.interfaces.HIGH, line=1, # node=module, end_line=1, col_offset=0, end_col_offset=3, ) with self.assertAddsMessages(expected): self.checker._check_bidi_chars(f"# {bad_string}".encode(codec), 1, codec)