From 5095180c93094af1c8c8a4c029afa5d110895382 Mon Sep 17 00:00:00 2001 From: johndoknjas Date: Thu, 22 Aug 2024 19:33:20 -0700 Subject: [PATCH] Show all linting errors, not just the first one. --- lintception/linters.py | 25 +++++++++++++------------ lintception/main.py | 14 +++++++------- lintception/my_linter.py | 3 ++- tests.py | 2 +- 4 files changed, 23 insertions(+), 21 deletions(-) diff --git a/lintception/linters.py b/lintception/linters.py index 170ede4..837ab2e 100644 --- a/lintception/linters.py +++ b/lintception/linters.py @@ -13,8 +13,7 @@ from .Utils import Func, Line class LintResult(Enum): - SUCCESS, MYPY_ERR, VULTURE_ERR, VERMIN_ERR, PYLINT_ERR, NO_FUTURE_ANNOT_ERR, \ - NO_FUNC_ANNOT_ERR = range(7) + MYPY_ERR, VULTURE_ERR, VERMIN_ERR, PYLINT_ERR, NO_FUTURE_ANNOT_ERR, NO_FUNC_ANNOT_ERR = range(6) def test_vulture(settings: dict) -> bool: # https://stackoverflow.com/a/59564370/7743427 @@ -76,20 +75,22 @@ def func_has_annotations(lines: list[Line], func: Func) -> bool: def test_function_annotations() -> bool: lines = Utils.get_lines_all_py_files(['tests.py']) - return all([func_has_annotations(lines, func) for func in Utils.find_funcs(lines)]) - # Using a list comprehension instead of a generator expression so that all functions without + has_annotations = [func_has_annotations(lines, func) for func in Utils.find_funcs(lines)] + # Using a list instead of a generator expression so that all functions without # annotations are printed to the screen in `func_has_annotations`. + print('\n\n') + return all(has_annotations) -def run_linters() -> LintResult: +def run_linters() -> list[LintResult]: settings: dict[str, float | int] = {'MinVersion': 3.8, 'NumIncompatibleVersions': 2} settings.update(Utils.read_json_file('.lintception')) Utils.assertions_for_settings_dict(settings) tests = ( - (lambda: test_vulture(settings), LintResult.VULTURE_ERR), - (test_mypy, LintResult.MYPY_ERR), - (lambda: test_vermin(settings), LintResult.VERMIN_ERR), - (lambda: test_pylint(settings), LintResult.PYLINT_ERR), - (lambda: test_future_annotations(settings), LintResult.NO_FUTURE_ANNOT_ERR), - (test_function_annotations, LintResult.NO_FUNC_ANNOT_ERR), + (test_future_annotations(settings), LintResult.NO_FUTURE_ANNOT_ERR), + (test_function_annotations(), LintResult.NO_FUNC_ANNOT_ERR), + (test_vulture(settings), LintResult.VULTURE_ERR), + (test_mypy(), LintResult.MYPY_ERR), + (test_vermin(settings), LintResult.VERMIN_ERR), + (test_pylint(settings), LintResult.PYLINT_ERR), ) - return next((x[1] for x in tests if not x[0]()), LintResult.SUCCESS) + return [x[1] for x in tests if not x[0]] \ No newline at end of file diff --git a/lintception/main.py b/lintception/main.py index bdf3e8f..e3ad501 100644 --- a/lintception/main.py +++ b/lintception/main.py @@ -1,5 +1,4 @@ from __future__ import annotations -import sys from . import linters from . import my_linter @@ -7,13 +6,14 @@ def main() -> None: if not __debug__: raise RuntimeError("Python isn't running in the default debug mode.") - if (result := linters.run_linters()) != linters.LintResult.SUCCESS: - print(f"Error: {result.name}") - sys.exit(0) - print('\nvulture, mypy, vermin, and pylint found no errors.') - print('Also, all python files have a future annotations import at the top, and ', end='') - print('all functions have a return type annotation.\n') my_linter.main() + if errors := linters.run_linters(): + for error in errors: + print(f"Error: {error.name}") + else: + print('\nvulture, mypy, vermin, and pylint found no errors.') + print('Also, all python files have a future annotations import at the top, and ', end='') + print('all functions have a return type annotation.\n') if __name__ == '__main__': main() diff --git a/lintception/my_linter.py b/lintception/my_linter.py index 23e3c24..18ecdcd 100644 --- a/lintception/my_linter.py +++ b/lintception/my_linter.py @@ -33,4 +33,5 @@ def main() -> None: print("\n\nFunctions used only once:\n") for f in funcs_used_once: print(f"Func {f[0].name} (line {f[0].line_loc.line_index} of {f[0].line_loc.filename}) " + - f"is only referenced at line {f[1].line_loc.line_index} of {f[1].line_loc.filename}") \ No newline at end of file + f"is only referenced at line {f[1].line_loc.line_index} of {f[1].line_loc.filename}") + print('\n\n\n') \ No newline at end of file diff --git a/tests.py b/tests.py index 0bf0801..195a5d9 100644 --- a/tests.py +++ b/tests.py @@ -10,7 +10,7 @@ def example_fixture(self): """ def test_self(self): - assert linters.run_linters() == linters.LintResult.SUCCESS + assert linters.run_linters() == [] if __name__ == '__main__': raise RuntimeError("Should call with pytest")