Code Smell Detectors
Relevant source files
The following files were used as context for generating this wiki page:
Code Smell Detectors in the FLEXT infrastructure are specialized tools designed to identify architectural violations, anti-patterns, and maintainability issues within Python source code. These detectors operate as part of the project's quality gates, ensuring that the codebase adheres to defined engineering laws (ENFORCE rules). The system combines localized AST-based analysis for specific patterns with workspace-wide scans using external tools like qlty to capture complex smells such as duplication and logical complexity.
The detectors serve two primary functions: reporting violations as warnings or errors through the check verb and, where possible, applying automated fixes through the fix verb. By integrating these checks into the FlextInfraNamespaceEnforcer, the project maintains a zero-debt baseline by catching issues like bare exceptions, print statements in production code, and excessive boolean logic before they are committed.
Architecture and Components
The code smell detection system is composed of localized detectors, workspace-level quality gates, and automated transformers.
Detection Pipeline Flow
The following diagram illustrates how the infrastructure orchestrates various detectors to scan a project and generate an enforcement report.
Key Components
| Component | Class | Description |
|---|---|---|
| Pattern Detector | FlextInfraPatternSmellDetector | Uses Python's ast and tokenize modules to find specific banned patterns (e.g., print, pdb). |
| Smells Gate | FlextInfraSmellsGate | Orchestrates external qlty scans, parses SARIF output, and filters results per project. |
| Namespace Enforcer | FlextInfraNamespaceEnforcerProjectMixin | High-level orchestrator that runs all detectors over a project root. |
| Fixer Registry | smell_fixer_for | Factory that provides AST-based transformers for auto-fixable violations. |
Sources: src/flext_infra/detectors/pattern_smell_detector.py:30, src/flext_infra/gates/smells.py:33, src/flext_infra/refactor/_namespace_enforcer_project.py:37
Pattern Smell Detection (ENFORCE-026..033)
The FlextInfraPatternSmellDetector is a Rope-backed tool that utilizes an ast.NodeVisitor to perform static analysis on single Python files. It targets a specific set of "smell kinds" that represent forbidden coding practices.
Banned Patterns
The detector identifies several categories of violations:
- Debugging Artifacts: Detects
print()calls,breakpoint(), andimport pdb. - Exception Handling: Identifies "bare"
except:clauses that swallow all exceptions. - Type Annotations: Flags the use of the
dictkeyword in type hints, preferringMappingorTypedDict. - File I/O: Requires explicit
encodingparameters inopen()calls. - Suppression Comments: Binds to
tokenizeto find# type: ignoreand# noqacomments, which are generally forbidden in the project.
Sources: src/flext_infra/detectors/pattern_smell_detector.py:10-25, src/flext_infra/detectors/pattern_smell_detector.py:141-155
Implementation Detail: AST Visitor
The _PatternSmellVisitor overrides specific AST visit methods to flag violations:
@override
def visit_Call(self, node: ast.Call) -> None:
if (
isinstance(node.func, ast.Name)
and node.func.id == "open"
and not any(kw.arg == "encoding" for kw in node.keywords)
):
self._add_violation(
node.lineno,
"open_encoding",
'open() without explicit encoding — add encoding="utf-8"',
)
Sources: src/flext_infra/detectors/pattern_smell_detector.py:169-181
Workspace-Level Smells (QLTY Integration)
Complex code smells that require cross-file or cross-project context are handled by the FlextInfraSmellsGate. This gate integrates with the qlty tool to perform a full workspace scan.
Scan Coordination
To optimize performance, the system performs a single qlty smells --all scan for the entire workspace and caches the results in memory. Per-project quality gates then filter this cached SARIF (Static Analysis Results Interchange Format) payload based on file URI prefixes.
Smell Violation Types
The qlty integration captures the following architectural violations:
- Identical or similar code (duplication).
- High function or file complexity.
- Excessive function parameters or return statements.
- Deeply nested control flow.
- Complex boolean logic.
Sources: src/flext_infra/gates/smells.py:14-20, tests/unit/check/smells_gate_tests.py:27-30
Automated Fixing Logic
The infrastructure supports auto-fixing for specific code smells. This is governed by metadata in the flext-core package, which defines whether a specific smell tag has an auto=true strategy.
Fixing Workflow
When the fix() method is invoked on a project, the system performs the following steps:
- Scan: Retrieves current violations from the cached workspace scan.
- Filter: Identifies issues marked as
auto-fixable. - Transform: For each auto-fixable issue, it resolves a fixer class (e.g.,
FlextInfraBooleanLogicFixer). - Apply: The fixer modifies the source code to resolve the smell (e.g., rewriting a long
orchain into anany()call).
Sources: src/flext_infra/gates/smells.py:53-80, tests/unit/check/smells_gate_tests.py:101-118
Fixer Example: Boolean Logic
The FlextInfraBooleanLogicFixer simplifies long chains of boolean operators into a more readable collection-based approach. For example, a or b or c or d or e is rewritten as any((a, b, c, d, e)).
Sources: tests/unit/check/smells_gate_tests.py:112-118
Configuration and Constants
Detection behavior is influenced by various constants defining excluded directories and regex patterns.
Excluded Directories
During scanning, certain directories are explicitly ignored to avoid analyzing environment artifacts or dependencies:
.git,.venv,node_modules__pycache__,dist,build.reports,.mypy_cache,.ruff_cache
Sources: src/flext_infra/_constants/source_code.py:20-35
Severity Levels
The severity of smell violations depends on the SMELLS_GATE_MODE configuration:
- WARN Mode: Violations are reported as warnings, and the quality gate passes.
- STRICT Mode: Violations are reported as errors, causing the quality gate to fail.
Sources: src/flext_infra/gates/smells.py:155-160, tests/unit/check/smells_gate_tests.py:168-172
Summary
Code Smell Detectors provide the primary defense against architectural decay in the FLEXT project. By combining the FlextInfraPatternSmellDetector for granular, rule-based checks with the FlextInfraSmellsGate for high-level complexity and duplication analysis, the system ensures consistent code quality. The integration with automated refactoring via the fix verb allows developers to rapidly resolve identified smells, maintaining a clean and maintainable codebase.