Repository navigation
fix(serialization): support dict, Mapping, and tuple container traversal in can_reconstruct - #346
Conversation
…onstruct Signed-off-by: Hardik Kaurani <hardikkaurani1@gmail.com>
… support to can_reconstruct Signed-off-by: Hardik Kaurani <hardikkaurani1@gmail.com>
…uple types Signed-off-by: Hardik Kaurani <hardikkaurani1@gmail.com>
… for dict and tuple containers Signed-off-by: Hardik Kaurani <hardikkaurani1@gmail.com>
…an_reconstruct Signed-off-by: Hardik Kaurani <hardikkaurani1@gmail.com>
|
Hi Bernd Verst (@berndverst) andystaples, I've opened this PR to resolve #344 across five focused commits.
This ensures that inbound type discovery in activity and orchestrator executors preserves these annotations, allowing Comprehensive unit and worker-level tests have also been added to verify the behavior. Thank you for your time! |
andystaples
left a comment
There was a problem hiding this comment.
This is a replay-breaking bug fix that can be enabled by default without opt-in, provided the compatibility impact is explicitly scoped and covered. The accepted replay incompatibility is where previously rejected container annotations now cause recorded payloads to be reconstructed differently, including orchestrator inputs and inferred activity results; this does not mean every affected orchestration was already failing.
Please update the core and Azure Managed Unreleased changelogs following the existing Replay-breaking bug fix precedent: describe the affected annotations, warn about replay failures or changed behavior, and include guidance for keeping affected instances on the previous SDK. Azure Functions overrides can_reconstruct() to always return True, so this change does not alter its discovery behavior and does not need a changelog entry claiming otherwise.
Please add regression tests demonstrating the affected old-history replay behavior for orchestration inputs and inferred activity results, and confirming unaffected annotations, explicit reconstruction, and custom converter policies remain unchanged. Include coverage verifying that Azure Functions remains unaffected.
… for dict and tuple containers Signed-off-by: Hardik Kaurani <hardikkaurani1@gmail.com>
…ions unaffected coverage Signed-off-by: Hardik Kaurani <hardikkaurani1@gmail.com>
… core and azuremanaged changelogs Signed-off-by: Hardik Kaurani <hardikkaurani1@gmail.com>
|
Hi andystaples, I've pushed an update addressing the feedback across three focused commits:
All unit and executor tests pass cleanly. Whenever convenient, please take another look! |
There was a problem hiding this comment.
The replay regression coverage addresses the earlier concerns. The remaining correction is to shorten and accurately scope the changelog warning, following the repository guidance to narrow an overly broad claim rather than expand it into a catalogue of exceptions.
Please remove the assurance that list, Optional, and custom converter policies remain unchanged. Discovery is recursive, so annotations such as list[dict[str, Order]] and Optional[dict[str, Order]] are affected too, as are custom converters wherever they delegate to the base policy. Rather than documenting all the exceptions, keep the entry focused on the user-visible fix and actionable upgrade risk. The discussion of whether affected orchestrations were already failing can also be removed from the changelog.
Suggested core warning:
Warning
Replay-breaking bug fix: Container annotations involving dict, Mapping,
or tuple wrapping reconstructable types, including nested annotations, now
reconstruct orchestration inputs and inferred activity results by default.
Existing instances that relied on raw dictionaries or lists can change behavior
or fail replay with NonDeterminismError.
Drain affected instances on the previous SDK, or keep their task hub on the
previous SDK and use a separate task hub for new instances. Pin or lock the core
durabletask dependency, including when using the Azure Managed provider.
The Azure Managed entry can briefly describe the inherited fix and link to the core warning rather than repeat it. This is a documentation correction to the accepted replay-breaking fix, not a request for opt-in. I found no new implementation blocker in the updated diff.
…r reconstruction warning Signed-off-by: Hardik Kaurani <hardikkaurani1@gmail.com>
|
Hi andystaples, Updated both changelogs per the feedback:
|
Bernd Verst (berndverst)
left a comment
There was a problem hiding this comment.
Reviewed the complete diff against the target base. The dict/Mapping and tuple discovery paths now match the existing reconstruction support, including nested annotations and converter policy delegation. I found no actionable introduced defects or material performance concern. This intentionally changes replay behavior for affected existing instances; the regression coverage and core/Azure Managed upgrade warnings now document that risk and the required draining or dependency-pinning guidance. The latest changelog revision addresses the outstanding review feedback.
|
Hardik K (@hardikkaurani) |
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
22125b1
Summary of Changes
Closes #344
While
_coerce_generic()indurabletask/serialization.pyalready supports type-directed coercion fordict/Mappingandtuplecontainers,_can_reconstruct()previously omitted support for these types.As a result,
converter.can_reconstruct()returnedFalsefor annotations such asdict[str, MyModel],Mapping[str, MyModel],tuple[MyModel, ...], andtuple[MyModel, int].Consequently, inbound type discovery in
type_discovery.activity_input_typeandorchestrator_input_typediscarded these annotations and returnedNone, causing activities and orchestrators to receive uncoerced dictionaries and lists instead of typed model instances.Changes Across Commits
Commit 1:
fix(serialization): add dict and Mapping container support to can_reconstructorigin in (dict, Mapping)check in_can_reconstruct()to recursively inspect the value type (args[1]) whenlen(args) == 2.Commit 2:
fix(serialization): add homogeneous and heterogeneous tuple container support to can_reconstructorigin is tuplecheck in_can_reconstruct(), supporting both homogeneoustuple[T, ...]and fixed-length heterogeneoustuple[T1, T2, ...]annotations.Commit 3:
test(serialization): verify can_reconstruct with dict, Mapping, and tuple typescan_reconstruct()returnsTruefor dictionaries, mappings, and tuples of dataclasses, including nested container compositions.Commit 4:
test(worker): verify type discovery and activity input reconstruction for dict and tuple containersdict[str, Order]andtuple[Order, ...]correctly receive reconstructed dataclass instances.Commit 5:
docs(serialization): document dict, Mapping, and tuple traversal in can_reconstruct_can_reconstruct()docstring to document container recursion across wrapped type hints.Verification
pytest tests/durabletask/test_serialization.py tests/durabletask/test_type_discovery.py