diff --git a/src/archunitpython/common/fluentapi/checkable.py b/src/archunitpython/common/fluentapi/checkable.py index 10f216c..ec555fb 100644 --- a/src/archunitpython/common/fluentapi/checkable.py +++ b/src/archunitpython/common/fluentapi/checkable.py @@ -9,7 +9,7 @@ from archunitpython.common.logging.types import LoggingOptions -@dataclass(frozen=True) +@dataclass(frozen=True, slots=True) class CheckOptions: """Options for controlling rule check execution.""" diff --git a/src/archunitpython/common/logging/types.py b/src/archunitpython/common/logging/types.py index fc0d744..f54eab8 100644 --- a/src/archunitpython/common/logging/types.py +++ b/src/archunitpython/common/logging/types.py @@ -8,7 +8,7 @@ LogLevel = Literal["debug", "info", "warn", "error"] -@dataclass(frozen=True) +@dataclass(frozen=True, slots=True) class LoggingOptions: """Options for controlling logging during architecture checks.""" diff --git a/src/archunitpython/common/types.py b/src/archunitpython/common/types.py index 4e1839c..24b51c6 100644 --- a/src/archunitpython/common/types.py +++ b/src/archunitpython/common/types.py @@ -13,7 +13,7 @@ MatchType = Literal["exact", "partial"] -@dataclass(frozen=True) +@dataclass(frozen=True, slots=True) class PatternMatchingOptions: """Options controlling how a pattern is matched against file paths.""" @@ -21,7 +21,7 @@ class PatternMatchingOptions: matching: MatchType = "partial" -@dataclass(frozen=True) +@dataclass(frozen=True, slots=True) class Filter: """A compiled regex filter with matching options.""" diff --git a/src/archunitpython/common/util/declaration_detector.py b/src/archunitpython/common/util/declaration_detector.py index 7997eeb..5d85983 100644 --- a/src/archunitpython/common/util/declaration_detector.py +++ b/src/archunitpython/common/util/declaration_detector.py @@ -6,7 +6,7 @@ from dataclasses import dataclass -@dataclass +@dataclass(slots=True) class DeclarationCounts: """Counts of different declaration types in a Python file.""" @@ -88,24 +88,18 @@ def count_declarations(source: str) -> DeclarationCounts: if is_abstract_method(item): counts.abstract_methods += 1 - elif isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)): + for node in tree.body: + if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)): # Only count module-level functions - if _is_module_level(node, tree): - counts.total += 1 - counts.functions += 1 - - elif isinstance(node, ast.Assign) and _is_module_level(node, tree): + counts.functions += 1 counts.total += 1 + if isinstance(node, ast.Assign): counts.variables += 1 + counts.total += 1 return counts -def _is_module_level(node: ast.AST, tree: ast.Module) -> bool: - """Check if a node is directly in the module body.""" - return node in tree.body - - def _get_name(node: ast.expr) -> str: """Extract a name from an AST node.""" if isinstance(node, ast.Name):