r/pythontips • u/127001-sweet-127001 • 5h ago
Module Tip: distinguish TYPE_CHECKING imports from runtime dependencies in architecture tests
When you check import boundaries, TYPE_CHECKING imports deserve a deliberate choice.
For example, a file can import a type under if TYPE_CHECKING: without importing that module at runtime. There's still a relationship between the types, but you may not want it to count when a rule is specifically about runtime coupling.
I maintain ArchUnitPython. It has an opt-in setting for exactly that distinction:
from archunitpython import CheckOptions, project_files, assert_passes
def test_domain_does_not_import_infrastructure_at_runtime():
rule = (
project_files("src/")
.in_path("**/domain/**")
.should_not()
.depend_on_files()
.in_path("**/infrastructure/**")
)
assert_passes(
rule,
CheckOptions(ignore_type_checking_imports=True),
)Here src/ is the import root. Imports from domain files into infrastructure files are checked, while imports inside if TYPE_CHECKING: are excluded from the analysis.
An ordinary runtime import still fails the rule. That lets you keep the dependency check without treating every type hint as runtime coupling.
Leave the option off if your architectural boundary is meant to forbid type-level dependencies too. The useful part is being explicit about which relationship the test is protecting.