Namespace Enforcement
Relevant source files
The following files were used as context for generating this wiki page:
Namespace Enforcement is an automated orchestration system within the FLEXT infrastructure designed to ensure structural and architectural consistency across a workspace. It manages the discovery, validation, and optional auto-remediation of namespace violations, such as loose objects, incorrect import aliases, and manual protocol definitions that bypass canonical files.
The system operates by scanning projects within a workspace, detecting architectural "smells" using specialized detectors, and generating comprehensive reports. When the apply flag is enabled, the enforcer can automatically fix specific violations, such as creating missing facade files or rewriting import statements to align with project-specific MRO (Method Resolution Order) aliases.
Sources: src/flext_infra/refactor/namespace_enforcer.py:1-40, src/flext_infra/refactor/_namespace_enforcer_project.py:1-30
Architecture and Core Logic
The system is built on a mixin-based architecture that separates workspace-level orchestration from project-specific enforcement logic.
Orchestration Flow
The FlextInfraNamespaceEnforcer serves as the primary entry point. It resolves project roots by identifying directories where namespace enforcement is enabled and iterates through them to execute the enforcement pipeline.
The diagram shows the top-down flow of the enforcement process from workspace initialization to final report aggregation.
Sources: src/flext_infra/refactor/namespace_enforcer.py:38-66, src/flext_infra/refactor/namespace_enforcer_phases.py:53-76
Detection and Remediation Cycle
Enforcement relies on a "detect -> apply -> re-detect" cycle for every violation type. This ensures that auto-fixes are verified immediately after being applied to the source code.
| Phase | Description |
|---|---|
| Detection | Executes specialized detectors (e.g., FlextInfraLooseObjectDetector) against collected Python files. |
| Rewrite | If apply=True, executes a rewrite_fn that modifies the AST or source code via the Rope library. |
| Validation | Re-runs detection to confirm the violation is cleared and updates the report. |
Sources: src/flext_infra/refactor/namespace_enforcer.py:84-106, src/flext_infra/refactor/_namespace_enforcer_project.py:115-200
Validation Rules (NS-000 to NS-003)
The enforcement logic is grounded in a set of four primary rules (Rules 0-3) implemented using Rope's AST attribute walks.
Rule 0: Facade and Project Prefix
Enforces that facade modules (e.g., constants.py, models.py) contain exactly one public class with the correct project-specific prefix (e.g., FlextCore). It also bans disallowed top-level statements like loose functions or assignments in these specific files.
Sources: src/flext_infra/validate/namespace_rules.py:116-161
Rule 1: Constants Centralization
Ensures that all constants are centralized. It flags loose Final assignments, collection constants (like frozenset), and Enum definitions found outside of the canonical _constants/ directory or constants.py file.
Sources: src/flext_infra/validate/namespace_rules.py:173-201
Rule 2: Types Centralization
Mandates that TypeVar and TypeAlias declarations be located in typings.py or the _typings/ family directory. It also prevents inner classes in types modules from inheriting from BaseModel or Protocol.
Sources: src/flext_infra/validate/namespace_rules.py:255-285
Rule 3: Namespaced MRO Aliases
Requires runtime modules to use namespaced MRO aliases (c, m, p, t, u) for internal package imports rather than direct imports of facade classes.
Sources: src/flext_infra/validate/namespace_rules.py:326-353
Components and Detectors
The FlextInfraNamespaceEnforcerProjectMixin coordinates a wide array of specialized detectors.
The diagram illustrates the relationship between the project mixin and the various detector implementations.
Sources: src/flext_infra/refactor/_namespace_enforcer_project.py:11-45
Key Detectors and Violations
| Detector | Violation Type | Auto-Fixable |
|---|---|---|
FlextInfraLooseObjectDetector | Loose functions, loggers, or constants | Yes |
FlextInfraManualProtocolDetector | Protocol defined outside protocols.py | Yes |
FlextInfraImportAliasDetector | Missing or incorrect c/m/p/t/u aliases | Yes |
FlextInfraCyclicImportDetector | Circular dependencies between modules | No |
FlextInfraFutureAnnotationsDetector | Missing from __future__ import annotations | Yes |
Sources: src/flext_infra/refactor/_namespace_enforcer_project.py:115-255, src/flext_infra/refactor/namespace_enforcer.py:115-145
Reporting Structure
Enforcement results are aggregated into a WorkspaceEnforcementReport, which contains detailed ProjectEnforcementReport objects.
Report Fields
The report tracks metrics across the entire workspace, including:
- Structural Stats: Files scanned and projects processed.
- Architectural Violations: Loose objects, cyclic imports, manual protocols, and MRO completeness issues.
- Python Modernization: Missing future annotations, bare except blocks, and hardcoded versions.
- Integration: Private import bypasses and internal import violations.
Sources: src/flext_infra/refactor/namespace_enforcer.py:111-146, src/flext_infra/_models/refactor_namespace_enforcer.py
Implementation Detail: Facade Normalization
The system includes logic to normalize facade base classes. For example, it ensures that classes in constants.py inherit from FlextCoreConstants (aliased as Constants) and that the appropriate import line exists.
# src/flext_infra/_utilities/namespace.py:590-600
def _normalize_class_header(*, line: str, class_name: str, base_name: str) -> str:
"""Normalize class header to enforce canonical inheritance."""
stripped = line.strip()
prefix = f"class {class_name}"
if not stripped.startswith(prefix) or not stripped.endswith(":"):
return line
indent = line[: len(line) - len(line.lstrip())]
return f"{indent}class {class_name}({base_name}):"
Sources: src/flext_infra/_utilities/namespace.py:590-610
Conclusion
Namespace Enforcement acts as the automated "guardian" of the FLEXT architectural standards. By combining strict AST-based validation with automated Rope-powered refactoring, it maintains a zero-debt baseline across complex, multi-project workspaces. It ensures that developers adhere to centralization patterns for constants and types, while simultaneously enforcing the use of the MRO facade system for internal integrations.