From 009ed91552b1587f35e846c968fb21a384c493a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Eiras?= Date: Mon, 3 Oct 2022 16:40:12 +0200 Subject: [PATCH 1/2] Fix 159: check-docstring-first shall ignore attribute docstring at module top level Now attribute docstrings no longer complain. https://peps.python.org/pep-0257/#what-is-a-docstring --- pre_commit_hooks/check_docstring_first.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/pre_commit_hooks/check_docstring_first.py b/pre_commit_hooks/check_docstring_first.py index d55f08a5..cdf7b4c0 100644 --- a/pre_commit_hooks/check_docstring_first.py +++ b/pre_commit_hooks/check_docstring_first.py @@ -1,6 +1,7 @@ from __future__ import annotations import argparse +import ast import io import tokenize from tokenize import tokenize as tokenize_tokenize @@ -12,6 +13,14 @@ )) +def _push_code(seen_code: io.StringIO, tok_type: int, text: str): + if tok_type == tokenize.ENCODING: + return + seen_code.write(text) + if text and not text.isspace(): + seen_code.write(" ") + + def check_docstring_first(src: bytes, filename: str = '') -> int: """Returns nonzero if the source has what looks like a docstring that is not at the beginning of the source. @@ -21,12 +30,18 @@ def check_docstring_first(src: bytes, filename: str = '') -> int: """ found_docstring_line = None found_code_line = None + seen_code = io.StringIO() tok_gen = tokenize_tokenize(io.BytesIO(src).readline) for tok_type, _, (sline, scol), _, _ in tok_gen: # Looks like a docstring! if tok_type == tokenize.STRING and scol == 0: if found_docstring_line is not None: + tree = ast.parse(seen_code.getvalue()) + assignments = ast.AnnAssign, ast.Assign, ast.AugAssign + if tree.body and isinstance(tree.body[-1], assignments): + return 0 + print( f'{filename}:{sline}: Multiple module docstrings ' f'(first docstring on line {found_docstring_line}).', @@ -41,7 +56,10 @@ def check_docstring_first(src: bytes, filename: str = '') -> int: else: found_docstring_line = sline elif tok_type not in NON_CODE_TOKENS and found_code_line is None: + _push_code(seen_code, tok_type, text) found_code_line = sline + else: + _push_code(seen_code, tok_type, text) return 0 From e45e927656689384badaed9ac5123cfe7ffb3826 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 3 Oct 2022 14:46:22 +0000 Subject: [PATCH 2/2] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- pre_commit_hooks/check_docstring_first.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pre_commit_hooks/check_docstring_first.py b/pre_commit_hooks/check_docstring_first.py index cdf7b4c0..3fc0c98e 100644 --- a/pre_commit_hooks/check_docstring_first.py +++ b/pre_commit_hooks/check_docstring_first.py @@ -18,7 +18,7 @@ def _push_code(seen_code: io.StringIO, tok_type: int, text: str): return seen_code.write(text) if text and not text.isspace(): - seen_code.write(" ") + seen_code.write(' ') def check_docstring_first(src: bytes, filename: str = '') -> int: