feat(data): carry the concrete type inside serialized external distortion parameters - #180
Merged
janickm merged 1 commit intoSep 10, 2026
Conversation
janickm
marked this pull request as draft
September 9, 2026 14:38
|
Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually. Contributors can view more details about this message here. |
janickm
commented
Sep 9, 2026
janickm
force-pushed
the
dev/janickm/external-distortion-discriminator
branch
from
September 10, 2026 12:14
4f1d40a to
bc0be82
Compare
janickm
marked this pull request as ready for review
September 10, 2026 12:15
…tion parameters `CameraModelParameters.external_distortion_parameters` had to name the concrete union rather than the abstract `ExternalDistortionParameters` base, because `dataclasses_json` reconstructs whatever type a field is annotated with and the serialized form carried no discriminator: the type was stored beside the camera parameters by `encode_camera_model_parameters`, not inside the nested object. With a single-member union that resolves by luck; against the abstract base it built the base itself, which is a runtime fault rather than a typing one. Make the serialized form a discriminated union. The concrete `type()` is written inside the object under `EXTERNAL_DISTORTION_TYPE_KEY`, and the field's decoder dispatches on it through a registry that out-of-tree parameter types can join via `register_external_distortion_parameters`, mirroring the model-side registry. The field is then declared against the abstract base, and the four `get_parameters` casts name it too. Compatibility holds both ways, and both directions are covered by tests rather than assumed: - Payloads predating the nested key decode as bivariate-windshield, which is unambiguous because it was the only concrete type at the time. - `decode_camera_model_parameters` migrates the old camera-level type into the nested object, so the previous encoded layout keeps working. - `encode_camera_model_parameters` still writes the camera-level type, so readers predating this change resolve the concrete type from data written by it. That can go once no such reader remains. - A reader predating this change tolerates the added key, verified against the published wheel. Note this widens a field that callers *read*. Downstream consumers passing it to concretely-typed APIs need updating in step with the release. (cherry picked from commit 4f1d40a)
janickm
force-pushed
the
dev/janickm/external-distortion-discriminator
branch
from
September 10, 2026 12:28
bc0be82 to
ea503e5
Compare
janickm
enabled auto-merge
September 10, 2026 12:31
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #179, which introduced the
ExternalDistortionParametersbase but had to leaveCameraModelParameters.external_distortion_parametersnaming the concrete union. This removes that compromise.Why the field could not name the abstract base
dataclasses_jsonreconstructs whatever type a field is annotated with, and the serialized form carried no discriminator: the type was written beside the camera parameters byencode_camera_model_parameters, not inside the nested object. Confirmed directly:With a single-member union that resolves by luck. Against the abstract base,
from_dictbuilds the base itself, which is a runtime fault rather than a typing one — it surfaced downstream asTypeError: Unsupported external distortion type <class '...ExternalDistortionParameters'>, only at the point of use.What changes
The serialized form becomes a discriminated union: the concrete
type()is written inside the object underEXTERNAL_DISTORTION_TYPE_KEY, and the field's decoder dispatches on it through a registry that out-of-tree parameter types join viaregister_external_distortion_parameters, mirroring the model-side registry added in #179.The field is then declared against
ExternalDistortionParameters, and the fourget_parameterscasts name it too.Compatibility
Both directions hold, and each is covered by a test rather than assumed:
bivariate-windshield— unambiguous, it was the only concrete typedecode_camera_model_parametersmigrates it into the nested objectencode_keeps writing the camera-level typeThe camera-level type is therefore written twice for now. That is deliberate and commented; it can be dropped once no reader predating this change remains, and doing so would be the only breaking step — so it is not taken here.
Scope
This widens a field that callers read, so downstream consumers passing it to concretely-typed APIs need updating in step with the release. The remaining read positions (
decode_*return types and the parameter accessors in the compat layers) are deliberately left for a separate change, so this one stays a self-contained format change.Verified: 33/33 tests on 3.8 and 3.11 with
--nocache_test_results,tyaspect clean,//:format.checkclean.