summaryrefslogtreecommitdiffstats
path: root/test/sanity/code-smell/required-and-default-attributes.py
diff options
context:
space:
mode:
Diffstat (limited to 'test/sanity/code-smell/required-and-default-attributes.py')
-rw-r--r--test/sanity/code-smell/required-and-default-attributes.py26
1 files changed, 16 insertions, 10 deletions
diff --git a/test/sanity/code-smell/required-and-default-attributes.py b/test/sanity/code-smell/required-and-default-attributes.py
index 900829dce7..7b1c89f9b8 100644
--- a/test/sanity/code-smell/required-and-default-attributes.py
+++ b/test/sanity/code-smell/required-and-default-attributes.py
@@ -1,19 +1,25 @@
from __future__ import annotations
-import re
+import ast
+import pathlib
import sys
-def main():
- for path in sys.argv[1:] or sys.stdin.read().splitlines():
- with open(path, 'r') as path_fd:
- for line, text in enumerate(path_fd.readlines()):
- match = re.search(r'(FieldAttribute.*(default|required).*(default|required))', text)
+class CallVisitor(ast.NodeVisitor):
+ def __init__(self, path: str) -> None:
+ self.path = path
+
+ def visit_Call(self, node: ast.Call) -> None:
+ if isinstance(node.func, ast.Name) and node.func.id.endswith("FieldAttribute"):
+ if len([kw for kw in node.keywords if kw.arg in ("default", "required")]) > 1:
+ print(f"{self.path}:{node.lineno}:{node.col_offset}: use only one of `default` or `required` with `{node.func.id}`")
- if match:
- print('%s:%d:%d: use only one of `default` or `required` with `FieldAttribute`' % (
- path, line + 1, match.start(1) + 1))
+
+def main() -> None:
+ for path in sys.argv[1:] or sys.stdin.read().splitlines():
+ tree = ast.parse(pathlib.Path(path).read_text(), path)
+ CallVisitor(path).visit(tree)
-if __name__ == '__main__':
+if __name__ == "__main__":
main()