Skip to content

Instantly share code, notes, and snippets.

@MarcoGorelli
Created August 6, 2023 09:35
Show Gist options
  • Save MarcoGorelli/4f4b77d4e0c7270c05dc001f37d75b1f to your computer and use it in GitHub Desktop.
Save MarcoGorelli/4f4b77d4e0c7270c05dc001f37d75b1f to your computer and use it in GitHub Desktop.
docstring-checker
if __name__ == "__main__":
files = subprocess.run(
["git", "ls-files"], capture_output=True, text=True
).stdout.split()
ret = 0
for file in files:
if not file.endswith(".py"):
continue
with open(file) as fd:
content = fd.read()
matches = re.findall(r"\n\n( \w+.*)\n >>>", content)
if matches:
lines = content.splitlines()
for match in matches:
lineno = lines.index(match) + 1
print(
f"{file}:{lineno}:9: Found docstring example which probably will not render."
)
ret = 1
sys.exit(ret)
###
import sys
import re
import ast
for file in sys.argv[1:]:
with open(file) as fd:
content = fd.read()
tree = ast.parse(content)
for node in ast.walk(tree):
if isinstance(node, (ast.FunctionDef, ast.ClassDef)):
body = node.body
if len(body) > 0 and isinstance(body[0], ast.Expr) and isinstance(body[0].value, ast.Constant):
docstring = body[0].value.value
pattern = r"(?m)^[^\n]+\n\[*-] .+(?=\n[^\n])"
if isinstance(docstring, str):
lines = docstring.split("\n")
for i, line in enumerate(lines[1:], start=1):
prev_line = lines[i-1]
spaces = len(line) - len(line.lstrip())
prev_spaces = len(lines[i-1]) - len(lines[i-1].lstrip())
if spaces == prev_spaces and not prev_line.lstrip().startswith('*') and not prev_line.lstrip().startswith('-') and (line.lstrip().startswith('- ') or line.lstrip().startswith('* ')):
print('***')
print(file)
print(prev_line)
print(line)
print('***')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment