Repository navigation
fix(types): make the domain package roots lazy so a types package imports first in any order - #1798
Conversation
| "from adcp.types.domains.creative.list_creative_formats_response import " | ||
| "ListCreativeFormatsResponseCreativeAgent", |
There was a problem hiding this comment.
Ladon verdict: Approve
Approve — backport of #1797 to the 9.x line making 24 domain package roots lazy (PEP 562) to fix import-order re-entrancy (#1784).
The only non-generated source change is consolidate_exports.generate_domain_exports (scripts/consolidate_exports.py:972-1011), which emits a TYPE_CHECKING static-import block, _DECLARED_IN, and a guarded __getattr__/__dir__ matching the established types/__init__.py pattern. The AttributeError fall-through preserves submodule imports and import *. Regenerated roots preserve the public surface exactly (core: base __all__=1440, head __all__=1440, _DECLARED_IN=1440 in lockstep), so there is no public-API break and fix(types): is the correct semver signal. The new tests/test_domain_roots_import_in_any_order.py exercises the reported import-order paths in fresh interpreters.
No blocking or medium findings. high_risk is false, gated_paths is false, no author team gate. Although review_decision is REVIEW_REQUIRED, the gated-paths hard gate (row 2) only applies when gated_paths is true — it is not here — so this falls through to row 9.
…orts first in any order Backport of the SDK 10 fix for #1784 to the 9.x line, where the cycle reproduces identically: ``from adcp.types.domains.formats import Slot`` raised ImportError when it was the first adcp import in a process, because the domain roots imported every schema module eagerly and ``formats/canonical/_base.py`` re-entered ``formats/canonical`` through ``core/__init__`` while half built. Each domain root is now a PEP 562 module: ``__all__`` and a TYPE_CHECKING import block keep the static surface, ``_DECLARED_IN`` names each name's schema module, and ``__getattr__`` imports the declaring module on first read and caches the binding. Nothing is renamed and every name still resolves. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
12297a9 to
959ff18
Compare
There was a problem hiding this comment.
Ladon verdict: Approve
Approve — clean backport of #1797 making the 22 domain package roots lazy (PEP 562) to resolve the #1784 import-order cycle.
Checked:
- Generator (
scripts/consolidate_exports.py):__all__and the new_DECLARED_INmap both derive from the samerowsdict, so every exported name resolves via__getattr__; AttributeError fallthrough preserves submodule imports. - The runtime
__getattr__/__dir__sit correctly underif not TYPE_CHECKING:, with the static surface in theTYPE_CHECKINGblock — preserving type-checker coverage per the repo's PEP 562 facade invariant. - Public surface preserved: no renames,
__all__unchanged, non-breaking — no semver signal required. - New fresh-interpreter import-order test suite is thorough.
No critical/high/medium findings. Consistent with the prior approve on head 12297a9.
Decision path: high_risk=false, gated_paths=false (no gate applies), no no-auto-approve team match, zero findings → decision table rows 1–8 do not fire → row 9 approve.
Summary
Backport of #1797 (SDK 10) to the 9.x line, where #1784 reproduces identically:
from adcp.types.domains.formats import SlotraisedImportErrorwhen it was the first adcp import in a process, because the domain roots imported every schema module eagerly andformats/canonical/_base.pyre-enteredformats/canonicalthroughcore/__init__while half built.consolidate_exports.generate_domain_exportswrites each domain root as a PEP 562 module:__all__and aTYPE_CHECKINGimport block keep the static surface,_DECLARED_INnames each name's schema module, and__getattr__imports the declaring module on first read and caches the binding. An unknown name raisesAttributeError, so submodule imports still fall through. Nothing is renamed; every name still resolves;import *still binds everything.make validate-generated✓,make lint✓,make typecheck-all✓. Surface, layering, lazy-types, public-API and codegen suites pass (365 tests).tests/test_domain_roots_import_in_any_order.py: each domain root and the reported entry points import first in a fresh interpreter.Non-breaking: import-order fix only.
🤖 Generated with Claude Code