From 196556eab3ed0abbffd20bcec169d2f131535426 Mon Sep 17 00:00:00 2001 From: David McDonald Date: Fri, 28 Mar 2025 15:18:22 -0500 Subject: [PATCH] Test: Allow for other types of coding style violations --- test/check_configurable_requirements.py | 51 +++++++++++++++---------- 1 file changed, 31 insertions(+), 20 deletions(-) diff --git a/test/check_configurable_requirements.py b/test/check_configurable_requirements.py index f856c80b7..89e06e751 100644 --- a/test/check_configurable_requirements.py +++ b/test/check_configurable_requirements.py @@ -14,6 +14,7 @@ The current checks it implements are: completeness of declared requirements. """ +import abc import argparse import ast import importlib @@ -22,7 +23,7 @@ import logging import pkgutil import sys import types -from typing import Any, Iterator, NamedTuple, Optional, Tuple, Type, Union +from typing import Any, Iterator, List, Optional, Tuple, Type, Union from volatility3.framework import configuration, interfaces from volatility3.framework.deprecation import PluginRenameClass @@ -70,27 +71,37 @@ class NodeVisitor: """Default leave behavior.""" -class UnrequiredVersionableUsage(NamedTuple): - versionable_item_class: str - """ - The name of the VersionableInterface class - """ +class CodeViolation(metaclass=abc.ABCMeta): + def __init__(self, module: types.ModuleType, node: ast.AST) -> None: + self.module = module + self.node = node - consuming_class: str - """ - The name of the class that is using the imported VersionableInterface class - """ + def __str__(self): + return f"Code violation in module {self.module.__name__}: line {self.node.lineno}, col {self.node.col_offset}" - node: Union[ast.Name, ast.Attribute] - """ - The tree-sitter node encapsulating the used module component. - """ + +class UnrequiredVersionableUsage(CodeViolation): + + def __init__( + self, + module: types.ModuleType, + node: ast.AST, + consuming_class: str, + versionable_item_class: str, + ) -> None: + super().__init__(module, node) + self.consuming_class = consuming_class + self.versionable_item_class = versionable_item_class def __str__(self) -> str: return ( - f"Found usage of {self.versionable_item_class} " - f"in class {self.consuming_class} that is not declared " - f"in {self.consuming_class}'s `get_requirements()` classmethod" + super().__str__() + + ": " + + ( + f"Found usage of {self.versionable_item_class} " + f"in class {self.consuming_class} that is not declared " + f"in {self.consuming_class}'s `get_requirements()` classmethod" + ) ) @@ -177,7 +188,7 @@ class ConfigurableClassVisitor(NodeVisitor): self._current_object = None self._clazz = clazz self._seen = set() - self._violations = [] + self._violations: List[CodeViolation] = [] @property def versioned_classes(self): @@ -205,7 +216,7 @@ class ConfigurableClassVisitor(NodeVisitor): str(self.versioned_classes), ) result = UnrequiredVersionableUsage( - item.__name__, self._clazz.__name__, node + self._module, node, self._clazz.__name__, item.__name__ ) self._violations.append(result) @@ -333,7 +344,7 @@ def perform_review(): if found: print( - f"Found {found} uses of versionable components not declared in get_requirements()" + f"Found {found} coding standards violations" ) sys.exit(1)