symfonic.devtools.integrations¶
integrations ¶
Integration-adapter boundary checks (plan task T4.2.1).
Reads the repository-owned optional-import map and enforces the static
half of the integration-adapter standard over src/symfonic:
- IA-1 every module that reaches an optional distribution is registered;
- IA-2 the registered roots are the ones the module imports;
- IA-3 the registered import style is the one the source implements;
- IA-4 a missing extra is named as
symfonic-core[<extra>]; - IA-5 no package
__init__imports an adapter at module level.
Run it with python -m symfonic.devtools.integrations.
AdapterEntry
dataclass
¶
AdapterEntry(module: str, family: str, kind: AdapterKind, extras: tuple[str, ...], roots: tuple[str, ...], import_style: ImportStyle, port: str, suite: str, extra_hint: str = 'self', notes: str = '')
One registered module that reaches an optional distribution.
IntegrationMap
dataclass
¶
IntegrationMap(entries: tuple[AdapterEntry, ...], optional_roots: dict[str, tuple[str, ...]], unpinned_roots: dict[str, str] = dict(), adopter_roots: dict[str, str] = dict(), base_transitive: tuple[str, ...] = (), clean_packages: tuple[str, ...] = (), integration_packages: tuple[str, ...] = ())
The optional-import map.
entries registers every module that reaches an optional
distribution; optional_roots names every import root the packaging
extras provide (root -> the extras that ship it), which is what makes
IA-1 a completeness rule rather than a spot check; base_transitive
lists roots that arrive with the base dependencies and therefore
cannot be treated as optional however optional they look.
governed_roots
property
¶
Every root the map governs: optional, unpinned, or adopter-owned.
install_hints ¶
The strings a caller must be able to read when the extra is gone.
Source code in src/symfonic/devtools/integrations/model.py
owning_package ¶
The declared package a module's import cost is attributed to.
Source code in src/symfonic/devtools/integrations/model.py
root_of ¶
The governed root an import target belongs to, if any.
Dotted roots (langgraph.checkpoint.postgres) live in separate
optional distributions under a package that is a base dependency,
so the longest declared root wins.
Source code in src/symfonic/devtools/integrations/model.py
MapError ¶
Bases: ValueError
The optional-import map is missing or structurally invalid.
carrier_modules ¶
carrier_modules(modules: dict[str, ModuleInfo], integration_map: IntegrationMap) -> dict[str, dict[str, bool]]
Every scanned module that reaches an optional root, with its roots.
Source code in src/symfonic/devtools/integrations/introspect.py
collect_violations ¶
collect_violations(modules: dict[str, ModuleInfo], integration_map: IntegrationMap) -> list[Violation]
Run every static rule and return the violations, rule-ordered.
Source code in src/symfonic/devtools/integrations/checks.py
load_map ¶
Parse and validate the map file into an :class:IntegrationMap.
Source code in src/symfonic/devtools/integrations/catalog.py
observed_roots ¶
Optional roots this module imports -> True when at module level.
Type-checking-only imports are ignored: they cost nothing at runtime, which is the only thing the optional-dependency contract is about.
Source code in src/symfonic/devtools/integrations/introspect.py
observed_style ¶
lazy / module-guarded / module-required for one module.