| # 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 |
| |
| from __future__ import annotations |
| |
| import contextlib |
| import io |
| import os |
| import sys |
| import warnings |
| from collections.abc import Iterator |
| |
| import pytest |
| from pytest import CaptureFixture |
| |
| from pylint.testutils._run import _Run as Run |
| |
| |
| def is_module(filename: str) -> bool: |
| return filename.endswith(".py") |
| |
| |
| def is_package(filename: str, location: str) -> bool: |
| return os.path.exists(os.path.join(location, filename, "__init__.py")) |
| |
| |
| @contextlib.contextmanager |
| def _patch_stdout(out: io.StringIO) -> Iterator[None]: |
| sys.stdout = out |
| try: |
| yield |
| finally: |
| sys.stdout = sys.__stdout__ |
| |
| |
| LIB_DIRS = [os.path.dirname(os.__file__)] |
| MODULES_TO_CHECK = [ |
| (location, module) |
| for location in LIB_DIRS |
| for module in os.listdir(location) |
| if is_module(module) or is_package(module, location) |
| ] |
| MODULES_NAMES = [m[1] for m in MODULES_TO_CHECK] |
| |
| |
| @pytest.mark.primer_stdlib |
| @pytest.mark.parametrize( |
| ("test_module_location", "test_module_name"), MODULES_TO_CHECK, ids=MODULES_NAMES |
| ) |
| def test_primer_stdlib_no_crash( |
| test_module_location: str, test_module_name: str, capsys: CaptureFixture |
| ) -> None: |
| """Test that pylint does not produce any crashes or fatal errors on stdlib modules.""" |
| __tracebackhide__ = True # pylint: disable=unused-variable |
| os.chdir(test_module_location) |
| with _patch_stdout(io.StringIO()): |
| try: |
| # We want to test all the code we can |
| enables = ["--enable-all-extensions", "--enable=all"] |
| # Duplicate code takes too long and is relatively safe |
| # We don't want to lint the test directory which are repetitive |
| disables = ["--disable=duplicate-code", "--ignore=test"] |
| with warnings.catch_warnings(): |
| warnings.simplefilter("ignore", category=UserWarning) |
| Run([test_module_name, *enables, *disables]) |
| except SystemExit as ex: |
| out, err = capsys.readouterr() |
| assert not err, err |
| assert not out |
| msg = f"Encountered {{}} during primer stlib test for {test_module_name}" |
| assert ex.code != 32, msg.format("a crash") |
| assert ex.code % 2 == 0, msg.format("a message of category 'fatal'") # type: ignore[operator] |