Context
#133 covers import-linter and basic candidates for module-level import constraints. This spike extends the evaluation to four additional Python architecture-testing frameworks, plus insights from Mark Richards' "Fitness Function-Driven Architecture" (lesson 215) .
The video reinforces the concept of architecture fitness functions — automated, objective integrity checks that describe architectural goals teams strive toward — and mentions ArchUnit (Java), ArchUnit.NET, ArchUnit TS, pytest-archon, and pytestarch as Python options.
Candidates
1. ArchUnitPython — pip install archunitpython
Attribute
Detail
Stars
150
Latest release
v1.1.0 (Apr 26, 2026)
Commits
39
License
MIT
Python
3.10+
Dependencies
Zero runtime deps
Test integration
pytest (recommended), unittest, any framework
Approach
Fluent API — project_files("src/").should().have_no_cycles()
Strengths:
Richest feature set: circular deps, layer deps, naming conventions, code metrics (LCOM, distance from main sequence), custom rules/metrics, UML diagram adherence (PlantUML), architecture slices, HTML reports
Zero runtime dependencies — uses Python ast module
Clean fluent API with assert_passes() helper
Actively maintained (released today), inspired by ArchUnitTS
Self-hosting (uses itself to test its own architecture)
Weaknesses:
Very new project (39 commits, 2 forks, single maintainer)
File-level analysis only (not class/method granularity for dependencies)
No pre-commit hook integration documented
Small community, no established track record
2. pytestarch — pip install pytestarch
Attribute
Detail
Stars
157
Latest release
v4.0.1 (Aug 8, 2025)
Commits
264
License
Apache-2.0
Python
3.9+ (based on noxfile)
Dependencies
networkx, matplotlib (optional for viz)
Test integration
pytest-native
Approach
Module-level rule DSL — Rule().modules_that().are_named(...)
Strengths:
Most mature of the four (27 releases, 264 commits)
Module-level granularity for import rules
Visualization support (dependency graphs via matplotlib)
Separate evaluable architecture object (can reuse across tests)
Well-documented with mkdocs site
Weaknesses:
Focused purely on import dependencies (no metrics, no naming conventions, no custom rules)
Uses poetry for build (dependency on networkx heavier than needed)
Less active recently (last release Aug 2025 — 8 months ago)
10 open issues, 4 open PRs
3. pytest-imports — pip install pytest-imports
Attribute
Detail
Stars
17
Commits
60
License
Apache-2.0
Python
3.10+ (uses uv)
Dependencies
None beyond pytest plugin
Test integration
pytest plugin (native fixture-based)
Approach
Dict-based rules — imports.check({'foo': must_import('bar')})
Strengths:
Most pythonic/ergonomic API — pytest fixture imports, declarative dict-based rules
Handles absolute vs relative imports (via via='absolute'|'relative')
Built-in predicates: must_not_import_private(), must_not_import_within_parent()
scope() helper for excluding subpackages
Lightweight, uses ast module from stdlib
Lists related tools in README (import-linter, pytestarch, pytest-archon, pytest-importson, findimports, pydeps)
Weaknesses:
Very small community (17 stars, 0 forks)
No releases on PyPI yet (install from git or test PyPI)
Import-only (no metrics, naming, cycles)
Single maintainer
No pre-commit integration documented
4. deply — pip install deply
Attribute
Detail
Stars
170
Latest release
v0.8.2 (stable badge)
Commits
133
License
BSD-3-Clause
Python
3.8–3.14
Dependencies
Minimal (see requirements.txt)
Test integration
Standalone CLI — deply analyze
Approach
YAML config — declarative layers + ruleset
Strengths:
Highest star count of the four (170)
Declarative YAML config (not test-code — can run independently in CI)
Rich collector system: file_regex, class_name_regex, class_inherits, class_decorator, logical AND/OR/NOT
Layer-based rules: disallow_layer_dependencies, enforce_inheritance, etc.
Mermaid diagram generation for visualization
Error suppression via # deply:ignore inline comments
CI-friendly CLI (no test framework dependency)
Broad Python version support (3.8–3.14)
Pre-commit config included
Custom collectors system
Parallel file analysis
Weaknesses:
Newer project (133 commits, 4 forks)
Layer-based only (no code metrics)
YAML config adds another config file to the repo
Single main maintainer
Roadmap items still pending (custom rules, external import restrictions)
Also Noted (from video & snip research)
Tool
Status
import-linter
Evaluated in #133 — strongest established option
pytest-archon
Mentioned in pytest-imports README — small, import-focused
pytest-importson
Another small import-only option
ArchUnit (Java) / ArchUnit.NET / ArchUnit TS
Reference implementations from the video
Comparison Matrix
Criterion
ArchUnitPython
pytestarch
pytest-imports
deply
import-linter (#133 )
Import layer rules
Yes
Yes
Yes
Yes
Yes
Circular dependency detection
Yes
No
No
No
Yes
Code metrics
Yes (LCOM, distance)
No
No
No
No
Naming conventions
Yes
No
No
No
No
Custom rules
Yes (predicates)
No
No
Planned
Limited
CLI / standalone
No (test-only)
No (test-only)
No (test-only)
Yes
Yes
Declarative config
No (code-based)
No (code-based)
No (code-based)
YAML
INI
Visualization
HTML reports
matplotlib graphs
No
Mermaid diagrams
Dep graph
Runtime dependencies
Zero
networkx
Zero
Minimal
Minimal
Pre-commit ready
Via pytest
Via pytest
Via pytest
Yes
Yes
Maturity (releases)
3
27
0
35
Many (est. 2019)
Community (stars)
150
157
17
170
~300+
Active maintenance
Very active (2026)
Slowing (Aug 2025)
Active
Active
Established
Spike Deliverables
Install each candidate in a clean venv, run against app/ codebase
Write equivalent rules for our known constraints (see Spike: enforce module-level import architecture constraints #133 ):
app/routes/ must not import app/db/
app/models/ must not import app/routes/
No circular deps between app/services/, app/models/, app/routes/
External import restrictions for domain layers
Compare ergonomics, error messages, CI integration
Assess security: supply chain risk of each dep, code review of AST parsing logic
Evaluate maintenance risk: bus factor, release cadence, issue response time
Cross-reference with import-linter evaluation from Spike: enforce module-level import architecture constraints #133
Recommend: adopt one, combine, or write custom ruff plugin
Preliminary Assessment
import-linter (from #133 ) remains the strongest established choice for pure import contract enforcement. Among the new candidates:
deply — best fit for standalone CI + YAML-driven config, but less mature than import-linter. Mermaid viz is a nice differentiator.
ArchUnitPython — most feature-rich (metrics + naming + UML), but very new and code-only (no declarative config). Could complement import-linter for fitness functions beyond imports.
pytestarch — mature but narrow (imports only) and slowing. No clear advantage over import-linter.
pytest-imports — nicest API but too early (no releases, tiny community).
Likely recommendation : import-linter for import contracts + deply or ArchUnitPython for broader architectural fitness functions (if needed beyond imports).
Related
Context
#133 covers import-linter and basic candidates for module-level import constraints. This spike extends the evaluation to four additional Python architecture-testing frameworks, plus insights from Mark Richards' "Fitness Function-Driven Architecture" (lesson 215).
The video reinforces the concept of architecture fitness functions — automated, objective integrity checks that describe architectural goals teams strive toward — and mentions ArchUnit (Java), ArchUnit.NET, ArchUnit TS, pytest-archon, and pytestarch as Python options.
Candidates
1. ArchUnitPython —
pip install archunitpythonproject_files("src/").should().have_no_cycles()Strengths:
astmoduleassert_passes()helperWeaknesses:
2. pytestarch —
pip install pytestarchRule().modules_that().are_named(...)Strengths:
Weaknesses:
3. pytest-imports —
pip install pytest-importsimports.check({'foo': must_import('bar')})Strengths:
imports, declarative dict-based rulesvia='absolute'|'relative')must_not_import_private(),must_not_import_within_parent()scope()helper for excluding subpackagesastmodule from stdlibWeaknesses:
4. deply —
pip install deplydeply analyzeStrengths:
file_regex,class_name_regex,class_inherits,class_decorator, logical AND/OR/NOTdisallow_layer_dependencies,enforce_inheritance, etc.# deply:ignoreinline commentsWeaknesses:
Also Noted (from video & snip research)
Comparison Matrix
Spike Deliverables
app/codebaseapp/routes/must not importapp/db/app/models/must not importapp/routes/app/services/,app/models/,app/routes/Preliminary Assessment
import-linter (from #133) remains the strongest established choice for pure import contract enforcement. Among the new candidates:
Likely recommendation: import-linter for import contracts + deply or ArchUnitPython for broader architectural fitness functions (if needed beyond imports).
Related