diff --git a/len8/models/checker.py b/len8/models/checker.py index 03c5fb8..adb75dc 100644 --- a/len8/models/checker.py +++ b/len8/models/checker.py @@ -124,7 +124,7 @@ def strict(self, strict: bool) -> None: self._strict = strict def _is_valid(self, path: Path) -> bool: - if path.suffix and path.suffix not in (".py", ".pyw"): + if path.is_file() and path.suffix not in (".py", ".pyw"): return False for e in self.exclude: @@ -148,34 +148,38 @@ def _check(self, path: Path) -> None: in_docs = False in_license = True - with open(path) as f: - for i, line in enumerate(f): - ls = line.lstrip() - rs = line.rstrip() + try: + with open(path, encoding="utf-8") as f: + for i, line in enumerate(f): + ls = line.lstrip() + rs = line.rstrip() - if in_license: - if ls.startswith("#"): - continue + if in_license: + if ls.startswith("#"): + continue - in_license = False + in_license = False - if ls.startswith(('"""', 'r"""')): - in_docs = True + if ls.startswith(('"""', 'r"""')): + in_docs = True - chars = len(rs) - limit: t.Literal[72, 79, 99] = ( - 72 - if in_docs or ls.startswith("#") - else (99 if self.extend else 79) - ) - - if chars > limit: - self._bad_lines.append( - (f"{path.resolve()}", i + 1, chars, limit) + chars = len(rs) + limit: t.Literal[72, 79, 99] = ( + 72 + if in_docs or ls.startswith("#") + else (99 if self.extend else 79) ) - if rs.endswith('"""'): - in_docs = False + if chars > limit: + self._bad_lines.append( + (f"{path.resolve()}", i + 1, chars, limit) + ) + + if rs.endswith('"""'): + in_docs = False + except IsADirectoryError: + # Handle weird directories. + ... def check(self, *paths: t.Union[Path, str]) -> t.Optional[str]: """Checks to ensure the line lengths conform to PEP 8 standards. diff --git a/tests/test_checker.py b/tests/test_checker.py index ebebb93..b318410 100644 --- a/tests/test_checker.py +++ b/tests/test_checker.py @@ -34,6 +34,7 @@ from len8.errors import BadLines, InvalidPath TEST_FILE = Path(__file__).parent / "testdata.py" +TEST_NON_VALID = TEST_FILE.parent / "nsx_simple_app.nsx" @pytest.fixture() @@ -121,7 +122,7 @@ def test_update_excludes(default_checker: len8.Checker) -> None: def test_file_validation(default_checker: len8.Checker) -> None: assert default_checker._is_valid(TEST_FILE) - assert not default_checker._is_valid(Path("test.rs")) + assert not default_checker._is_valid(Path("README.md")) default_checker.exclude = [Path(__file__).parent] assert default_checker._is_valid(Path("len8").absolute()) @@ -145,3 +146,10 @@ def test_pathlib_conversion_on_check(default_checker: len8.Checker) -> None: with pytest.raises(InvalidPath) as exc: assert default_checker.check(f"invalid_dir") == output assert f"{exc.value}" == f"Error: 'invalid_dir' is not a valid path." + + +def test_skip_invalid_files(default_checker: len8.Checker) -> None: + try: + default_checker.check(TEST_NON_VALID) + except UnicodeDecodeError: + pytest.fail()