Summary
In adcp==6.6.0, the public adcp.types.CreativeAsset symbol has incompatible runtime and static meanings. Runtime resolves it to the legacy CreativeAsset1 branch, while mypy resolves it to the generated CreativeAsset root union over CreativeAsset1 | CreativeAsset2.
This makes code that type-checks against the 3.1+ format_kind branch fail or become impossible when it uses the public runtime symbol.
Reproduction
Python 3.12, adcp==6.6.0:
from typing import get_args, get_origin
from adcp.types import CreativeAsset
print(CreativeAsset)
print(get_origin(CreativeAsset), get_args(CreativeAsset))
Runtime output:
<class 'adcp.types.generated_poc.core.creative_asset.CreativeAsset1'>
None ()
For the same import, mypy 2.3.1 reports:
Revealed type is "def (root: CreativeAsset1 | CreativeAsset2) -> CreativeAsset"
The generated module does define the root union, but _generated.py then deliberately replaces the public runtime binding for subclassing compatibility:
CreativeAssetUnion = CreativeAsset
CreativeAsset = CreativeAsset1 # type: ignore[misc,assignment]
Because the reassignment is ignored statically, the TYPE_CHECKING re-export and runtime lazy re-export disagree.
Impact
A downstream request DTO can subclass or construct CreativeAsset believing it represents both schema branches, while runtime actually fixes it to the legacy branch that requires format_id. The spec-legal format_kind branch is represented by CreativeAsset2 and is unavailable through that public name.
Expected
The public symbol should mean the same thing at runtime and under static analysis. Either:
- export the root union as
CreativeAsset and give the concrete compatibility class a separate explicit name, or
- type
CreativeAsset as CreativeAsset1 and document/use CreativeAssetUnion for the schema union.
SDK 7's canonical CreativeAsset plus explicit LegacyCreativeAsset surface provides a clearer migration seam, but the 6.6.0 mismatch should at least be documented and covered by a runtime/static alias regression test if a 6.x patch is not planned.
Affected version
- Confirmed:
6.6.0
- SDK 7 uses the canonical creative boundary for unqualified
CreativeAsset; its explicit LegacyCreativeAsset imports the generated root model, so this exact mismatch does not appear to apply there.
Summary
In
adcp==6.6.0, the publicadcp.types.CreativeAssetsymbol has incompatible runtime and static meanings. Runtime resolves it to the legacyCreativeAsset1branch, while mypy resolves it to the generatedCreativeAssetroot union overCreativeAsset1 | CreativeAsset2.This makes code that type-checks against the 3.1+
format_kindbranch fail or become impossible when it uses the public runtime symbol.Reproduction
Python 3.12,
adcp==6.6.0:Runtime output:
For the same import, mypy 2.3.1 reports:
The generated module does define the root union, but
_generated.pythen deliberately replaces the public runtime binding for subclassing compatibility:Because the reassignment is ignored statically, the
TYPE_CHECKINGre-export and runtime lazy re-export disagree.Impact
A downstream request DTO can subclass or construct
CreativeAssetbelieving it represents both schema branches, while runtime actually fixes it to the legacy branch that requiresformat_id. The spec-legalformat_kindbranch is represented byCreativeAsset2and is unavailable through that public name.Expected
The public symbol should mean the same thing at runtime and under static analysis. Either:
CreativeAssetand give the concrete compatibility class a separate explicit name, orCreativeAssetasCreativeAsset1and document/useCreativeAssetUnionfor the schema union.SDK 7's canonical
CreativeAssetplus explicitLegacyCreativeAssetsurface provides a clearer migration seam, but the 6.6.0 mismatch should at least be documented and covered by a runtime/static alias regression test if a 6.x patch is not planned.Affected version
6.6.0CreativeAsset; its explicitLegacyCreativeAssetimports the generated root model, so this exact mismatch does not appear to apply there.