durable-workflow 2.0.1__tar.gz → 2.0.2__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.0.1/src/durable_workflow.egg-info → durable_workflow-2.0.2}/PKG-INFO +1 -1
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/pyproject.toml +3 -3
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/src/durable_workflow/__init__.py +2 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/src/durable_workflow/client.py +6 -2
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/src/durable_workflow/errors.py +11 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2/src/durable_workflow.egg-info}/PKG-INFO +1 -1
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/src/durable_workflow.egg-info/SOURCES.txt +1 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/tests/test_pypi_project_surface.py +2 -3
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/tests/test_release_metadata.py +2 -2
- durable_workflow-2.0.2/tests/test_workflow_result_timeout.py +61 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/LICENSE +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/README.md +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/setup.cfg +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/src/durable_workflow/_avro.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/src/durable_workflow/activity.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/src/durable_workflow/auth_composition.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/src/durable_workflow/external_storage.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/src/durable_workflow/external_task_input.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/src/durable_workflow/external_task_result.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/src/durable_workflow/history_bundle_verify.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/src/durable_workflow/interceptors.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/src/durable_workflow/invocable.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/src/durable_workflow/metrics.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/src/durable_workflow/nexus.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/src/durable_workflow/py.typed +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/src/durable_workflow/python_conformance.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/src/durable_workflow/replay_conformance.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/src/durable_workflow/replay_verify.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/src/durable_workflow/retry_policy.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/src/durable_workflow/serializer.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/src/durable_workflow/sync.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/src/durable_workflow/testing.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/src/durable_workflow/worker.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/src/durable_workflow/workflow.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/src/durable_workflow/workflow_updates_conformance.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/src/durable_workflow.egg-info/dependency_links.txt +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/src/durable_workflow.egg-info/entry_points.txt +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/src/durable_workflow.egg-info/requires.txt +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/src/durable_workflow.egg-info/top_level.txt +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/tests/test_activity_context.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/tests/test_auth_composition.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/tests/test_avro_value_benchmark.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/tests/test_avro_value_protocol.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/tests/test_ci_checkout.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/tests/test_ci_integration_endpoint.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/tests/test_client.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/tests/test_codec_regression_corpus.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/tests/test_control_plane_parity_fixtures.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/tests/test_docstring_cross_references.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/tests/test_durable_selection.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/tests/test_errors.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/tests/test_external_storage.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/tests/test_external_task_input.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/tests/test_external_task_result.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/tests/test_golden_history_replay.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/tests/test_history_bundle_verify.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/tests/test_history_event_contract.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/tests/test_invocable.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/tests/test_message_streams.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/tests/test_metrics.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/tests/test_order_processing_example.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/tests/test_parallel_completion_order_replay.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/tests/test_parallel_saga_authoring.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/tests/test_public_boundary_scanner.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/tests/test_python_conformance.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/tests/test_queries.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/tests/test_readme_quickstart.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/tests/test_replay.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/tests/test_replay_conformance.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/tests/test_replay_regression_corpus.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/tests/test_replay_verify.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/tests/test_retry_policy.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/tests/test_runtime_external_payload_transport.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/tests/test_schedules.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/tests/test_serializer.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/tests/test_signals.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/tests/test_sleep.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/tests/test_standalone_activity_client.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/tests/test_sync.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/tests/test_testing_harness.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/tests/test_update_signal_condition_replay.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/tests/test_updates.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/tests/test_wait_condition.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/tests/test_worker.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/tests/test_workflow_streams.py +0 -0
- {durable_workflow-2.0.1 → durable_workflow-2.0.2}/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.0.
|
|
7
|
+
version = "2.0.2"
|
|
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.0.
|
|
75
|
-
registry-version = "2.0.
|
|
74
|
+
product-train = "2.0.2"
|
|
75
|
+
registry-version = "2.0.2"
|
|
76
76
|
supported-server-versions = "2.0.0"
|
|
77
77
|
worker-protocol-version = "1.19"
|
|
78
78
|
control-plane-version = "2"
|
|
@@ -95,6 +95,7 @@ from .errors import (
|
|
|
95
95
|
WorkflowNotFound,
|
|
96
96
|
WorkflowPayloadDecodeError,
|
|
97
97
|
WorkflowTerminated,
|
|
98
|
+
WorkflowTimedOut,
|
|
98
99
|
)
|
|
99
100
|
from .external_storage import (
|
|
100
101
|
EXTERNAL_PAYLOAD_REFERENCE_SCHEMA,
|
|
@@ -374,6 +375,7 @@ __all__ = [
|
|
|
374
375
|
"WorkflowFailed",
|
|
375
376
|
"WorkflowNotFound",
|
|
376
377
|
"WorkflowTerminated",
|
|
378
|
+
"WorkflowTimedOut",
|
|
377
379
|
"EXTERNAL_TASK_INPUT_CONTRACT_SCHEMA",
|
|
378
380
|
"EXTERNAL_TASK_INPUT_MEDIA_TYPE",
|
|
379
381
|
"EXTERNAL_TASK_INPUT_SCHEMA",
|
|
@@ -46,6 +46,7 @@ from .errors import (
|
|
|
46
46
|
WorkflowCancelled,
|
|
47
47
|
WorkflowFailed,
|
|
48
48
|
WorkflowTerminated,
|
|
49
|
+
WorkflowTimedOut,
|
|
49
50
|
_raise_for_status,
|
|
50
51
|
)
|
|
51
52
|
from .external_storage import (
|
|
@@ -4141,8 +4142,9 @@ class Client:
|
|
|
4141
4142
|
Raises :class:`~durable_workflow.errors.WorkflowFailed`,
|
|
4142
4143
|
:class:`~durable_workflow.errors.WorkflowCancelled`, or
|
|
4143
4144
|
:class:`~durable_workflow.errors.WorkflowTerminated` if the workflow
|
|
4144
|
-
ended in a non-success state
|
|
4145
|
-
|
|
4145
|
+
ended in a non-success state. A persisted execution or run deadline
|
|
4146
|
+
raises :class:`~durable_workflow.errors.WorkflowTimedOut`; a caller's
|
|
4147
|
+
:class:`TimeoutError` means ``timeout`` seconds elapsed while waiting.
|
|
4146
4148
|
"""
|
|
4147
4149
|
deadline = asyncio.get_running_loop().time() + timeout
|
|
4148
4150
|
while True:
|
|
@@ -4177,6 +4179,8 @@ class Client:
|
|
|
4177
4179
|
raise WorkflowCancelled(
|
|
4178
4180
|
payload.get("reason", "workflow was cancelled")
|
|
4179
4181
|
)
|
|
4182
|
+
if etype == "WorkflowTimedOut":
|
|
4183
|
+
raise WorkflowTimedOut()
|
|
4180
4184
|
return None
|
|
4181
4185
|
if asyncio.get_running_loop().time() > deadline:
|
|
4182
4186
|
raise TimeoutError(
|
|
@@ -560,6 +560,17 @@ class WorkflowTerminated(DurableWorkflowError):
|
|
|
560
560
|
super().__init__(message)
|
|
561
561
|
|
|
562
562
|
|
|
563
|
+
class WorkflowTimedOut(DurableWorkflowError):
|
|
564
|
+
"""A persisted workflow execution or run deadline expired.
|
|
565
|
+
|
|
566
|
+
Unlike a caller's :class:`TimeoutError` while polling, this is a terminal
|
|
567
|
+
workflow outcome recorded by the runtime.
|
|
568
|
+
"""
|
|
569
|
+
|
|
570
|
+
def __init__(self, message: str = "workflow execution timed out") -> None:
|
|
571
|
+
super().__init__(message)
|
|
572
|
+
|
|
573
|
+
|
|
563
574
|
class SagaCompensationFailed(DurableWorkflowError):
|
|
564
575
|
"""A saga compensation failed after an earlier workflow failure.
|
|
565
576
|
|
|
@@ -348,7 +348,7 @@ def test_stable_audit_requires_root_and_bare_install(
|
|
|
348
348
|
assert evidence["historical_versions"] == ["0.4.105", "0.4.106"]
|
|
349
349
|
|
|
350
350
|
|
|
351
|
-
def
|
|
351
|
+
def test_stable_root_preserves_historical_files_without_overriding_yanks() -> None:
|
|
352
352
|
source = source_metadata(stable=True)
|
|
353
353
|
exact_urls = verify_exact_version_json(exact_version_payload(source), source)
|
|
354
354
|
|
|
@@ -356,8 +356,7 @@ def test_stable_root_preserves_non_yanked_historical_files() -> None:
|
|
|
356
356
|
|
|
357
357
|
payload = stable_project_payload()
|
|
358
358
|
payload["releases"]["0.4.106"][0]["yanked"] = True
|
|
359
|
-
|
|
360
|
-
verify_stable_project_json(payload, source, exact_urls)
|
|
359
|
+
assert verify_stable_project_json(payload, source, exact_urls) == ("0.4.105", "0.4.106")
|
|
361
360
|
|
|
362
361
|
|
|
363
362
|
def test_prerelease_evidence_records_deferred_default_surface(
|
|
@@ -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"] == "2.0.
|
|
44
|
+
assert project["version"] == "2.0.2"
|
|
45
45
|
assert release["product-train"] == project["version"]
|
|
46
|
-
assert release["registry-version"] == "2.0.
|
|
46
|
+
assert release["registry-version"] == "2.0.2"
|
|
47
47
|
assert release["supported-server-versions"] == "2.0.0"
|
|
48
48
|
assert release["worker-protocol-version"] == PROTOCOL_VERSION == "1.19"
|
|
49
49
|
assert release["durable-selection"] is True
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
from unittest.mock import AsyncMock
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
|
|
5
|
+
from durable_workflow import Client, WorkflowTimedOut
|
|
6
|
+
from durable_workflow.client import WorkflowExecution, WorkflowHandle
|
|
7
|
+
from durable_workflow.errors import WorkflowCancelled, WorkflowFailed, WorkflowTerminated
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def result_client(status: str, event_type: str, payload: dict) -> tuple[Client, WorkflowHandle]:
|
|
11
|
+
client = Client("https://unused.example")
|
|
12
|
+
client.describe_workflow = AsyncMock(
|
|
13
|
+
return_value=WorkflowExecution(
|
|
14
|
+
workflow_id="order", run_id="current-run", workflow_type="order", status=status,
|
|
15
|
+
)
|
|
16
|
+
)
|
|
17
|
+
client.get_history = AsyncMock(
|
|
18
|
+
return_value={"events": [{"event_type": event_type, "payload": payload}]}
|
|
19
|
+
)
|
|
20
|
+
return client, WorkflowHandle(client, workflow_id="order", run_id="selected-run", workflow_type="order")
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@pytest.mark.parametrize("kind", ["execution_timeout", "run_timeout"])
|
|
24
|
+
async def test_persisted_deadline_raises_typed_timeout_for_selected_history(kind: str) -> None:
|
|
25
|
+
client, handle = result_client(
|
|
26
|
+
"failed", "WorkflowTimedOut", {"timeout_kind": kind, "deadline_at": "2026-01-01T00:00:00Z"},
|
|
27
|
+
)
|
|
28
|
+
try:
|
|
29
|
+
with pytest.raises(WorkflowTimedOut, match="workflow execution timed out"):
|
|
30
|
+
await client.get_result(handle, timeout=0)
|
|
31
|
+
client.get_history.assert_awaited_once_with("order", "selected-run")
|
|
32
|
+
finally:
|
|
33
|
+
await client.aclose()
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
async def test_polling_timeout_is_not_a_terminal_workflow_timeout() -> None:
|
|
37
|
+
client, handle = result_client("waiting", "ConditionWaitOpened", {})
|
|
38
|
+
try:
|
|
39
|
+
with pytest.raises(TimeoutError, match="not terminal") as caught:
|
|
40
|
+
await client.get_result(handle, timeout=0)
|
|
41
|
+
assert not isinstance(caught.value, WorkflowTimedOut)
|
|
42
|
+
client.get_history.assert_not_awaited()
|
|
43
|
+
finally:
|
|
44
|
+
await client.aclose()
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
@pytest.mark.parametrize(
|
|
48
|
+
("status", "event_type", "exception"),
|
|
49
|
+
[
|
|
50
|
+
("failed", "WorkflowFailed", WorkflowFailed),
|
|
51
|
+
("cancelled", "WorkflowCancelled", WorkflowCancelled),
|
|
52
|
+
("terminated", "WorkflowTerminated", WorkflowTerminated),
|
|
53
|
+
],
|
|
54
|
+
)
|
|
55
|
+
async def test_other_terminal_failures_preserve_their_exception(status, event_type, exception) -> None:
|
|
56
|
+
client, handle = result_client(status, event_type, {"message": "stopped", "reason": "stopped"})
|
|
57
|
+
try:
|
|
58
|
+
with pytest.raises(exception, match="stopped"):
|
|
59
|
+
await client.get_result(handle, timeout=0)
|
|
60
|
+
finally:
|
|
61
|
+
await client.aclose()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{durable_workflow-2.0.1 → durable_workflow-2.0.2}/src/durable_workflow/external_task_input.py
RENAMED
|
File without changes
|
{durable_workflow-2.0.1 → durable_workflow-2.0.2}/src/durable_workflow/external_task_result.py
RENAMED
|
File without changes
|
{durable_workflow-2.0.1 → durable_workflow-2.0.2}/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.0.1 → durable_workflow-2.0.2}/src/durable_workflow/python_conformance.py
RENAMED
|
File without changes
|
{durable_workflow-2.0.1 → durable_workflow-2.0.2}/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.0.1 → durable_workflow-2.0.2}/src/durable_workflow.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{durable_workflow-2.0.1 → durable_workflow-2.0.2}/src/durable_workflow.egg-info/entry_points.txt
RENAMED
|
File without changes
|
{durable_workflow-2.0.1 → durable_workflow-2.0.2}/src/durable_workflow.egg-info/requires.txt
RENAMED
|
File without changes
|
{durable_workflow-2.0.1 → durable_workflow-2.0.2}/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.0.1 → durable_workflow-2.0.2}/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.0.1 → durable_workflow-2.0.2}/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
|
|
File without changes
|
{durable_workflow-2.0.1 → durable_workflow-2.0.2}/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
|
{durable_workflow-2.0.1 → durable_workflow-2.0.2}/tests/test_update_signal_condition_replay.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{durable_workflow-2.0.1 → durable_workflow-2.0.2}/tests/test_workflow_updates_conformance.py
RENAMED
|
File without changes
|