From f04d1478150b7fdf15b75cd9cfd12c5110ce7ba8 Mon Sep 17 00:00:00 2001 From: dosisod <39638017+dosisod@users.noreply.github.com> Date: Mon, 8 Jan 2024 20:49:59 -0800 Subject: [PATCH] Fix syntax errors in docstring code snippets: Some of the code examples in the docstrings where not valid Python code, so I wrote a small test to ensure all the checks have valid Python code. This doesn't do anything fancy like checking for imports (though maybe it should), it merely checks that the AST tree can be built. --- docs/checks.md | 6 +++--- refurb/checks/hashlib/simplify_ctor.py | 2 +- refurb/checks/logical/use_equal_chain.py | 2 +- refurb/checks/readability/use_str_func.py | 2 +- test/test_check_formatting.py | 25 +++++++++++++++++++++++ 5 files changed, 31 insertions(+), 6 deletions(-) diff --git a/docs/checks.md b/docs/checks.md index e48b1e7..ef7178d 100644 --- a/docs/checks.md +++ b/docs/checks.md @@ -601,7 +601,7 @@ if x == y and x == z: # and -if x is None and y is None +if x is None and y is None: pass ``` @@ -2150,7 +2150,7 @@ Bad: from hashlib import sha512 h = sha512() -h.update(b"data) +h.update(b"data") ``` Good: @@ -2172,7 +2172,7 @@ Bad: ```python nums = [123, 456] -num = f"{num[0]}") +num = f"{num[0]}" ``` Good: diff --git a/refurb/checks/hashlib/simplify_ctor.py b/refurb/checks/hashlib/simplify_ctor.py index 390bc46..e8a279c 100644 --- a/refurb/checks/hashlib/simplify_ctor.py +++ b/refurb/checks/hashlib/simplify_ctor.py @@ -30,7 +30,7 @@ class ErrorInfo(Error): from hashlib import sha512 h = sha512() - h.update(b"data) + h.update(b"data") ``` Good: diff --git a/refurb/checks/logical/use_equal_chain.py b/refurb/checks/logical/use_equal_chain.py index 8e70710..a79d1e5 100644 --- a/refurb/checks/logical/use_equal_chain.py +++ b/refurb/checks/logical/use_equal_chain.py @@ -20,7 +20,7 @@ class ErrorInfo(Error): # and - if x is None and y is None + if x is None and y is None: pass ``` diff --git a/refurb/checks/readability/use_str_func.py b/refurb/checks/readability/use_str_func.py index d8d5c85..7ef618b 100644 --- a/refurb/checks/readability/use_str_func.py +++ b/refurb/checks/readability/use_str_func.py @@ -18,7 +18,7 @@ class ErrorInfo(Error): ``` nums = [123, 456] - num = f"{num[0]}") + num = f"{num[0]}" ``` Good: diff --git a/test/test_check_formatting.py b/test/test_check_formatting.py index eefc90a..6a7a35d 100644 --- a/test/test_check_formatting.py +++ b/test/test_check_formatting.py @@ -1,6 +1,10 @@ +import ast import re from functools import cache from pathlib import Path +from textwrap import dedent + +import pytest import refurb from refurb.error import Error @@ -55,6 +59,26 @@ def get_categories_from_docs() -> list[str]: return categories +def assert_python_snippets_are_parseable(error: type[Error]) -> None: + # This check is simple enough that it doesn't need detailed docs + if error.code == 105: + return + + docs = dedent(error(0, 0, "").__doc__ or "") + + groups = re.findall(r"```([\S\s]*?)```", docs) + assert groups, "Missing docstring" + + assert len(groups) >= 2, 'Expected at least 2 "good" and "bad" code examples in docstring' + + try: + for code in groups: + ast.parse(code.strip()) + + except SyntaxError as ex: + pytest.fail(f"Python code in docs is invalid: {ex.msg}") + + def test_checks_are_formatted_properly() -> None: error_names: set[str] = set() @@ -68,6 +92,7 @@ def test_checks_are_formatted_properly() -> None: assert_category_exists(error) assert_categories_are_sorted(error) assert_categories_are_valid(error, get_categories_from_docs()) + assert_python_snippets_are_parseable(error) assert error.name, "name field missing for class"