durable-workflow 2.1.0__tar.gz → 2.1.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {durable_workflow-2.1.0/src/durable_workflow.egg-info → durable_workflow-2.1.1}/PKG-INFO +1 -1
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/pyproject.toml +3 -3
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/src/durable_workflow/workflow.py +12 -2
- {durable_workflow-2.1.0 → durable_workflow-2.1.1/src/durable_workflow.egg-info}/PKG-INFO +1 -1
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/tests/test_pypi_project_surface.py +5 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/tests/test_release_metadata.py +2 -2
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/tests/test_replay.py +51 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/tests/test_replay_regression_corpus.py +10 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/LICENSE +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/README.md +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/setup.cfg +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/src/durable_workflow/__init__.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/src/durable_workflow/_avro.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/src/durable_workflow/activity.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/src/durable_workflow/auth_composition.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/src/durable_workflow/client.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/src/durable_workflow/errors.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/src/durable_workflow/external_storage.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/src/durable_workflow/external_task_input.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/src/durable_workflow/external_task_result.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/src/durable_workflow/history_bundle_verify.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/src/durable_workflow/interceptors.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/src/durable_workflow/invocable.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/src/durable_workflow/metrics.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/src/durable_workflow/nexus.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/src/durable_workflow/py.typed +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/src/durable_workflow/python_conformance.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/src/durable_workflow/replay_conformance.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/src/durable_workflow/replay_verify.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/src/durable_workflow/retry_policy.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/src/durable_workflow/serializer.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/src/durable_workflow/sync.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/src/durable_workflow/testing.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/src/durable_workflow/worker.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/src/durable_workflow/workflow_updates_conformance.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/src/durable_workflow.egg-info/SOURCES.txt +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/src/durable_workflow.egg-info/dependency_links.txt +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/src/durable_workflow.egg-info/entry_points.txt +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/src/durable_workflow.egg-info/requires.txt +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/src/durable_workflow.egg-info/top_level.txt +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/tests/test_activity_context.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/tests/test_auth_composition.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/tests/test_avro_value_benchmark.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/tests/test_avro_value_protocol.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/tests/test_ci_checkout.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/tests/test_ci_integration_endpoint.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/tests/test_client.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/tests/test_codec_regression_corpus.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/tests/test_control_plane_parity_fixtures.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/tests/test_docstring_cross_references.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/tests/test_durable_selection.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/tests/test_errors.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/tests/test_external_storage.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/tests/test_external_task_input.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/tests/test_external_task_result.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/tests/test_golden_history_replay.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/tests/test_history_bundle_verify.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/tests/test_history_event_contract.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/tests/test_invocable.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/tests/test_message_streams.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/tests/test_metrics.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/tests/test_order_processing_example.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/tests/test_parallel_completion_order_replay.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/tests/test_parallel_saga_authoring.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/tests/test_public_boundary_scanner.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/tests/test_python_conformance.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/tests/test_queries.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/tests/test_readme_quickstart.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/tests/test_redrive_replay.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/tests/test_replay_conformance.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/tests/test_replay_verify.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/tests/test_retry_policy.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/tests/test_runtime_external_payload_transport.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/tests/test_schedules.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/tests/test_serializer.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/tests/test_signals.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/tests/test_sleep.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/tests/test_standalone_activity_client.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/tests/test_storage_admission.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/tests/test_sync.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/tests/test_testing_harness.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/tests/test_update_signal_condition_replay.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/tests/test_updates.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/tests/test_wait_condition.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/tests/test_worker.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/tests/test_workflow_result_timeout.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/tests/test_workflow_streams.py +0 -0
- {durable_workflow-2.1.0 → durable_workflow-2.1.1}/tests/test_workflow_updates_conformance.py +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "durable-workflow"
|
|
7
|
-
version = "2.1.
|
|
7
|
+
version = "2.1.1"
|
|
8
8
|
description = "Python client and worker SDK for Durable Workflow Cloud and self-hosted Server"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -71,8 +71,8 @@ durable-workflow-replay-conformance = "durable_workflow.replay_conformance:main"
|
|
|
71
71
|
durable-workflow-workflow-updates-conformance = "durable_workflow.workflow_updates_conformance:main"
|
|
72
72
|
|
|
73
73
|
[tool.durable-workflow]
|
|
74
|
-
product-train = "2.1.
|
|
75
|
-
registry-version = "2.1.
|
|
74
|
+
product-train = "2.1.1"
|
|
75
|
+
registry-version = "2.1.1"
|
|
76
76
|
supported-server-versions = "2.4.0"
|
|
77
77
|
worker-protocol-version = "1.19"
|
|
78
78
|
control-plane-version = "2"
|
|
@@ -762,6 +762,7 @@ class RecordSideEffect:
|
|
|
762
762
|
|
|
763
763
|
result: Any
|
|
764
764
|
workflow_stream: dict[str, Any] | None = None
|
|
765
|
+
_effect: Callable[[], Any] | None = field(default=None, repr=False, compare=False)
|
|
765
766
|
|
|
766
767
|
def to_server_command(
|
|
767
768
|
self,
|
|
@@ -1799,8 +1800,7 @@ class WorkflowContext:
|
|
|
1799
1800
|
return SelectGroup(entries)
|
|
1800
1801
|
|
|
1801
1802
|
def side_effect(self, fn: Callable[[], Any]) -> RecordSideEffect:
|
|
1802
|
-
result =
|
|
1803
|
-
return RecordSideEffect(result=result)
|
|
1803
|
+
return RecordSideEffect(result=None, _effect=fn)
|
|
1804
1804
|
|
|
1805
1805
|
def append_workflow_stream(
|
|
1806
1806
|
self,
|
|
@@ -5139,6 +5139,16 @@ def _replay_state(
|
|
|
5139
5139
|
continue
|
|
5140
5140
|
ctx.logger._set_replaying(False)
|
|
5141
5141
|
_assert_pending_step_matches(cmd)
|
|
5142
|
+
if cmd._effect is not None:
|
|
5143
|
+
try:
|
|
5144
|
+
cmd.result = cmd._effect()
|
|
5145
|
+
except Exception as exc:
|
|
5146
|
+
try:
|
|
5147
|
+
advanced_cmd = gen.throw(exc)
|
|
5148
|
+
continue
|
|
5149
|
+
except StopIteration as stop:
|
|
5150
|
+
return _terminal_state(stop.value, include_pending=True)
|
|
5151
|
+
cmd._effect = None
|
|
5142
5152
|
pending.append(cmd)
|
|
5143
5153
|
next_value = cmd.result
|
|
5144
5154
|
continue
|
|
@@ -2,6 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import json
|
|
4
4
|
import subprocess
|
|
5
|
+
from dataclasses import replace
|
|
5
6
|
from pathlib import Path
|
|
6
7
|
from typing import Any
|
|
7
8
|
|
|
@@ -91,6 +92,10 @@ def pip_report(version: str) -> dict[str, object]:
|
|
|
91
92
|
def test_release_channel_distinguishes_prerelease_and_stable() -> None:
|
|
92
93
|
assert release_channel(source_metadata()) == "prerelease"
|
|
93
94
|
assert release_channel(source_metadata(stable=True)) == "stable"
|
|
95
|
+
stable_minor = replace(source_metadata(stable=True), version="2.1.0", registry_version="2.1.0")
|
|
96
|
+
prerelease_minor = replace(source_metadata(), version="2.1.0-rc.1", registry_version="2.1.0rc1")
|
|
97
|
+
assert release_channel(stable_minor) == "stable"
|
|
98
|
+
assert release_channel(prerelease_minor) == "prerelease"
|
|
94
99
|
|
|
95
100
|
|
|
96
101
|
def test_prerelease_with_existing_final_skips_project_root_and_bare_install(
|
|
@@ -41,9 +41,9 @@ def test_worker_release_identity_matches_supported_server_and_protocol() -> None
|
|
|
41
41
|
project = manifest["project"]
|
|
42
42
|
release = manifest["tool"]["durable-workflow"]
|
|
43
43
|
|
|
44
|
-
assert project["version"]
|
|
44
|
+
assert check_release_metadata.VERSION_PATTERN.fullmatch(project["version"]) is not None
|
|
45
45
|
assert release["product-train"] == project["version"]
|
|
46
|
-
assert release["registry-version"] == "
|
|
46
|
+
assert release["registry-version"] == project["version"].replace("-rc.", "rc")
|
|
47
47
|
assert release["supported-server-versions"] == "2.4.0"
|
|
48
48
|
assert release["worker-protocol-version"] == PROTOCOL_VERSION == "1.19"
|
|
49
49
|
assert release["durable-selection"] is True
|
|
@@ -1158,6 +1158,57 @@ class TestContinueAsNew:
|
|
|
1158
1158
|
|
|
1159
1159
|
|
|
1160
1160
|
class TestSideEffect:
|
|
1161
|
+
def test_user_callable_runs_only_for_an_unrecorded_side_effect(self) -> None:
|
|
1162
|
+
calls: list[str] = []
|
|
1163
|
+
|
|
1164
|
+
@workflow.defn(name="side-effect-call-count-wf")
|
|
1165
|
+
class CountedSideEffectWorkflow:
|
|
1166
|
+
def run(self, ctx: WorkflowContext): # type: ignore[no-untyped-def]
|
|
1167
|
+
value = yield ctx.side_effect(lambda: calls.append("called") or 42)
|
|
1168
|
+
return value
|
|
1169
|
+
|
|
1170
|
+
first = replay(CountedSideEffectWorkflow, [], [])
|
|
1171
|
+
assert calls == ["called"]
|
|
1172
|
+
assert isinstance(first.commands[0], RecordSideEffect)
|
|
1173
|
+
assert first.commands[0].result == 42
|
|
1174
|
+
|
|
1175
|
+
history = [{"event_type": "SideEffectRecorded", "payload": {"result": _avro(99)}}]
|
|
1176
|
+
replayed = replay(CountedSideEffectWorkflow, history, [])
|
|
1177
|
+
assert calls == ["called"]
|
|
1178
|
+
assert isinstance(replayed.commands[0], CompleteWorkflow)
|
|
1179
|
+
assert replayed.commands[0].result == 99
|
|
1180
|
+
|
|
1181
|
+
def test_user_callable_is_not_run_when_history_shape_mismatches(self) -> None:
|
|
1182
|
+
calls: list[str] = []
|
|
1183
|
+
|
|
1184
|
+
@workflow.defn(name="side-effect-mismatch-wf")
|
|
1185
|
+
class MismatchedSideEffectWorkflow:
|
|
1186
|
+
def run(self, ctx: WorkflowContext): # type: ignore[no-untyped-def]
|
|
1187
|
+
return (yield ctx.side_effect(lambda: calls.append("called") or 42))
|
|
1188
|
+
|
|
1189
|
+
history = [{"event_type": "TimerScheduled", "payload": {"sequence": 1, "timer_kind": "durable_timer"}}]
|
|
1190
|
+
with pytest.raises(NonDeterministicReplayError):
|
|
1191
|
+
replay(MismatchedSideEffectWorkflow, history, [])
|
|
1192
|
+
assert calls == []
|
|
1193
|
+
|
|
1194
|
+
def test_user_callable_error_can_be_handled_by_workflow(self) -> None:
|
|
1195
|
+
@workflow.defn(name="side-effect-error-wf")
|
|
1196
|
+
class HandledSideEffectWorkflow:
|
|
1197
|
+
def run(self, ctx: WorkflowContext): # type: ignore[no-untyped-def]
|
|
1198
|
+
def fail() -> int:
|
|
1199
|
+
raise ValueError("expected failure")
|
|
1200
|
+
|
|
1201
|
+
try:
|
|
1202
|
+
yield ctx.side_effect(fail)
|
|
1203
|
+
except ValueError:
|
|
1204
|
+
return "handled"
|
|
1205
|
+
return "unexpected"
|
|
1206
|
+
|
|
1207
|
+
outcome = replay(HandledSideEffectWorkflow, [], [])
|
|
1208
|
+
assert len(outcome.commands) == 1
|
|
1209
|
+
assert isinstance(outcome.commands[0], CompleteWorkflow)
|
|
1210
|
+
assert outcome.commands[0].result == "handled"
|
|
1211
|
+
|
|
1161
1212
|
def test_first_replay_records_and_continues(self) -> None:
|
|
1162
1213
|
outcome = replay(SideEffectWorkflow, [], [])
|
|
1163
1214
|
assert len(outcome.commands) == 2
|
|
@@ -147,6 +147,15 @@ class WorkflowStreamAuthorWorkflow:
|
|
|
147
147
|
return "done"
|
|
148
148
|
|
|
149
149
|
|
|
150
|
+
@workflow.defn(name="tests.replay.recorded-side-effect")
|
|
151
|
+
class RecordedSideEffectWorkflow:
|
|
152
|
+
def run(self, ctx: WorkflowContext): # type: ignore[no-untyped-def]
|
|
153
|
+
def unexpected_execution() -> int:
|
|
154
|
+
raise AssertionError("recorded side effect callable ran during replay")
|
|
155
|
+
|
|
156
|
+
return (yield ctx.side_effect(unexpected_execution))
|
|
157
|
+
|
|
158
|
+
|
|
150
159
|
@workflow.defn(name="tests.replay.message-stream-consumer")
|
|
151
160
|
class MessageStreamConsumerWorkflow:
|
|
152
161
|
def run(self, ctx: WorkflowContext): # type: ignore[no-untyped-def]
|
|
@@ -197,6 +206,7 @@ WORKFLOWS = [
|
|
|
197
206
|
ParallelMetadataProducerWorkflow,
|
|
198
207
|
ParallelResultBindingWorkflow,
|
|
199
208
|
PostConditionReceiversWorkflow,
|
|
209
|
+
RecordedSideEffectWorkflow,
|
|
200
210
|
SelectionAwaitMarkerWorkflow,
|
|
201
211
|
SelectionCancellationQueryWorkflow,
|
|
202
212
|
SelectionMissingNestedOpeningWorkflow,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{durable_workflow-2.1.0 → durable_workflow-2.1.1}/src/durable_workflow/external_task_input.py
RENAMED
|
File without changes
|
{durable_workflow-2.1.0 → durable_workflow-2.1.1}/src/durable_workflow/external_task_result.py
RENAMED
|
File without changes
|
{durable_workflow-2.1.0 → durable_workflow-2.1.1}/src/durable_workflow/history_bundle_verify.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{durable_workflow-2.1.0 → durable_workflow-2.1.1}/src/durable_workflow/python_conformance.py
RENAMED
|
File without changes
|
{durable_workflow-2.1.0 → durable_workflow-2.1.1}/src/durable_workflow/replay_conformance.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{durable_workflow-2.1.0 → durable_workflow-2.1.1}/src/durable_workflow.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{durable_workflow-2.1.0 → durable_workflow-2.1.1}/src/durable_workflow.egg-info/entry_points.txt
RENAMED
|
File without changes
|
{durable_workflow-2.1.0 → durable_workflow-2.1.1}/src/durable_workflow.egg-info/requires.txt
RENAMED
|
File without changes
|
{durable_workflow-2.1.0 → durable_workflow-2.1.1}/src/durable_workflow.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{durable_workflow-2.1.0 → durable_workflow-2.1.1}/tests/test_control_plane_parity_fixtures.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{durable_workflow-2.1.0 → durable_workflow-2.1.1}/tests/test_parallel_completion_order_replay.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{durable_workflow-2.1.0 → durable_workflow-2.1.1}/tests/test_runtime_external_payload_transport.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{durable_workflow-2.1.0 → durable_workflow-2.1.1}/tests/test_update_signal_condition_replay.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{durable_workflow-2.1.0 → durable_workflow-2.1.1}/tests/test_workflow_updates_conformance.py
RENAMED
|
File without changes
|