durable-workflow 2.12.2__tar.gz → 2.12.3__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.12.2/src/durable_workflow.egg-info → durable_workflow-2.12.3}/PKG-INFO +1 -1
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/pyproject.toml +3 -3
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow/_activity_process.py +2 -1
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow/_failure_reporting.py +6 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow/invocable.py +4 -3
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow/worker.py +11 -10
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow/workflow.py +7 -6
- {durable_workflow-2.12.2 → durable_workflow-2.12.3/src/durable_workflow.egg-info}/PKG-INFO +1 -1
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow.egg-info/SOURCES.txt +1 -0
- durable_workflow-2.12.3/tests/test_empty_callback_failure.py +156 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_replay_regression_corpus.py +7 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/LICENSE +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/README.md +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/setup.cfg +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow/__init__.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow/_activity_lease.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow/_avro.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow/_cancellation_scope.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow/_cancellation_scope_history.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow/_cooperative_cancellation.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow/_metric_routes.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow/_poll_transport.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow/_prepared_local_activity.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow/_query_task_authority.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow/_sticky_workflow_cache.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow/activity.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow/auth_composition.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow/cancellation.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow/client.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow/errors.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow/external_storage.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow/external_task_input.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow/external_task_result.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow/history_bundle_verify.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow/interceptors.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow/metrics.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow/nexus.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow/py.typed +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow/python_conformance.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow/replay_conformance.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow/replay_verify.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow/retry_policy.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow/serializer.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow/sync.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow/telemetry.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow/telemetry_carrier.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow/testing.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow/worker_session.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow/workflow_updates_conformance.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow.egg-info/dependency_links.txt +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow.egg-info/entry_points.txt +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow.egg-info/requires.txt +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow.egg-info/top_level.txt +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_activity_cancellation_policies.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_activity_context.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_activity_heartbeat_authority.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_activity_lease_authority.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_activity_lease_renewal.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_activity_lease_worker.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_activity_process.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_activity_retry_info.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_auth_composition.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_avro_value_benchmark.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_avro_value_protocol.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_cancellation_context.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_cancellation_remaining_time.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_cancellation_scope_admission.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_cancellation_scope_authoring.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_cancellation_scope_boundary.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_cancellation_scope_opening.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_child_workflow_policies.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_ci_checkout.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_ci_integration_endpoint.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_client.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_client_telemetry.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_client_timeouts.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_codec_regression_corpus.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_committed_cancellation_scope_descendants.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_committed_cancellation_scope_groups.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_committed_cancellation_scope_history.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_committed_cancellation_scope_replay.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_condition_replay_drift.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_control_plane_parity_fixtures.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_cooperative_cancellation.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_cooperative_cancellation_client.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_cooperative_cancellation_worker.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_cooperative_remote_worker.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_docstring_cross_references.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_durable_selection.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_errors.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_external_storage.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_external_task_input.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_external_task_result.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_failure_reporting.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_generator_lifecycle.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_golden_history_replay.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_history_bundle_schema2.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_history_bundle_verify.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_history_event_contract.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_invocable.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_local_failure_reporting.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_message_streams.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_metric_routes.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_metrics.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_nexus_durable_wait.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_nexus_namespace.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_nexus_wire.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_order_processing_example.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_parallel_completion_order_replay.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_parallel_saga_authoring.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_patch_history.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_pending_operation_replay.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_poll_failure_backoff.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_poll_transport.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_prepared_local_activity_client.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_prepared_local_activity_groups.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_prepared_local_activity_policies.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_prepared_local_activity_worker.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_public_boundary_scanner.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_pypi_project_surface.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_python_conformance.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_queries.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_query_task_authority.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_query_timeout_retry.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_readme_quickstart.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_redrive_replay.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_registration_ambiguity.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_release_metadata.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_replay.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_replay_clock.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_replay_conformance.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_replay_verify.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_retry_policy.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_run_cancellation_scope_replay.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_runtime_external_payload_transport.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_schedules.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_scoped_run_cancellation_context.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_sdk_metrics_contract.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_serializer.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_signals.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_sleep.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_standalone_activity_client.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_sticky_execution.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_storage_admission.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_sync.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_sync_activities.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_telemetry.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_telemetry_carrier.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_testing_failures.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_testing_harness.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_testing_nexus.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_threaded_heartbeat_example.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_tls_trust.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_transport_diagnostics.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_update_signal_condition_replay.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_updates.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_wait_condition.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_worker.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_worker_deregistration.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_worker_observation.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_worker_session.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_worker_telemetry_wire.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_workflow_entry_arguments.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_workflow_entrypoint_validation.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_workflow_handler_validation.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_workflow_identity.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_workflow_result_timeout.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_workflow_streams.py +0 -0
- {durable_workflow-2.12.2 → durable_workflow-2.12.3}/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.12.
|
|
7
|
+
version = "2.12.3"
|
|
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"
|
|
@@ -79,8 +79,8 @@ durable-workflow-replay-conformance = "durable_workflow.replay_conformance:main"
|
|
|
79
79
|
durable-workflow-workflow-updates-conformance = "durable_workflow.workflow_updates_conformance:main"
|
|
80
80
|
|
|
81
81
|
[tool.durable-workflow]
|
|
82
|
-
product-train = "2.12.
|
|
83
|
-
registry-version = "2.12.
|
|
82
|
+
product-train = "2.12.3"
|
|
83
|
+
registry-version = "2.12.3"
|
|
84
84
|
supported-server-versions = "2.8.0"
|
|
85
85
|
worker-protocol-version = "1.20"
|
|
86
86
|
control-plane-version = "2"
|
{durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow/_activity_process.py
RENAMED
|
@@ -24,6 +24,7 @@ from multiprocessing.process import BaseProcess
|
|
|
24
24
|
from pathlib import Path
|
|
25
25
|
from typing import Any, cast
|
|
26
26
|
|
|
27
|
+
from ._failure_reporting import exception_message
|
|
27
28
|
from .activity import ActivityContext, ActivityInfo, _set_context
|
|
28
29
|
from .errors import ActivityCancelled, NonRetryableError
|
|
29
30
|
from .interceptors import ActivityInterceptorContext, WorkerInterceptor
|
|
@@ -139,7 +140,7 @@ def _callback(directory: str, channel: socket.socket) -> None:
|
|
|
139
140
|
except BaseException as error:
|
|
140
141
|
code = getattr(error, "code", None)
|
|
141
142
|
_write_payload(directory, "outcome", CallbackOutcome(failure=CallbackFailure(
|
|
142
|
-
message=
|
|
143
|
+
message=exception_message(error), failure_type=type(error).__name__,
|
|
143
144
|
failure_class=f"{type(error).__module__}.{type(error).__qualname__}",
|
|
144
145
|
failure_code=code if isinstance(code, int) and not isinstance(code, bool) else None,
|
|
145
146
|
stack_trace=traceback.format_exc(), non_retryable=isinstance(error, NonRetryableError),
|
{durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow/_failure_reporting.py
RENAMED
|
@@ -26,6 +26,12 @@ _EXCEPTION_IDENTITY = frozenset({
|
|
|
26
26
|
})
|
|
27
27
|
|
|
28
28
|
|
|
29
|
+
def exception_message(error: BaseException, *, fallback: str | None = None) -> str:
|
|
30
|
+
"""Keep useful diagnostic text; blank exceptions still need a valid report."""
|
|
31
|
+
message = str(error)
|
|
32
|
+
return message if message.strip() else fallback or type(error).__name__
|
|
33
|
+
|
|
34
|
+
|
|
29
35
|
def encoded_json(value: Any) -> bytes:
|
|
30
36
|
"""Use HTTPX's actual JSON settings, including escaping and NaN refusal."""
|
|
31
37
|
return httpx.Request("POST", "https://failure.invalid", json=value).content
|
|
@@ -12,6 +12,7 @@ from datetime import datetime, timezone
|
|
|
12
12
|
from typing import Any, cast
|
|
13
13
|
|
|
14
14
|
from . import serializer
|
|
15
|
+
from ._failure_reporting import exception_message
|
|
15
16
|
from .errors import ActivityCancelled, NonRetryableError
|
|
16
17
|
from .external_storage import ExternalPayloadCache, ExternalStorageDriver
|
|
17
18
|
from .external_task_input import ExternalTaskInput, parse_external_task_input
|
|
@@ -105,7 +106,7 @@ class InvocableActivityHandler:
|
|
|
105
106
|
started,
|
|
106
107
|
kind="application",
|
|
107
108
|
classification="application_error",
|
|
108
|
-
message=
|
|
109
|
+
message=exception_message(exc),
|
|
109
110
|
failure_type=type(exc).__name__,
|
|
110
111
|
stack_trace=traceback.format_exc(),
|
|
111
112
|
retryable=False,
|
|
@@ -116,7 +117,7 @@ class InvocableActivityHandler:
|
|
|
116
117
|
started,
|
|
117
118
|
kind="timeout",
|
|
118
119
|
classification="deadline_exceeded",
|
|
119
|
-
message=
|
|
120
|
+
message=exception_message(exc, fallback="Invocable activity handler exceeded its deadline."),
|
|
120
121
|
failure_type=type(exc).__name__,
|
|
121
122
|
stack_trace=traceback.format_exc(),
|
|
122
123
|
timeout_type="deadline_exceeded",
|
|
@@ -140,7 +141,7 @@ class InvocableActivityHandler:
|
|
|
140
141
|
started,
|
|
141
142
|
kind="application",
|
|
142
143
|
classification="application_error",
|
|
143
|
-
message=
|
|
144
|
+
message=exception_message(exc),
|
|
144
145
|
failure_type=type(exc).__name__,
|
|
145
146
|
stack_trace=traceback.format_exc(),
|
|
146
147
|
retryable=True,
|
|
@@ -44,7 +44,7 @@ from ._activity_lease import activity_lease_renewal_supported, current_activity_
|
|
|
44
44
|
from ._activity_process import CallbackFailure, CallbackInvocation, CallbackProcessLost, SupervisedCallback
|
|
45
45
|
from ._cancellation_scope_history import CancellationScopeBudget, CancellationScopeDeliveryReceipt
|
|
46
46
|
from ._cooperative_cancellation import CancellationRequest, read_cancellation_history
|
|
47
|
-
from ._failure_reporting import REQUEST_BYTES, normalize_local_failure
|
|
47
|
+
from ._failure_reporting import REQUEST_BYTES, exception_message, normalize_local_failure
|
|
48
48
|
from ._prepared_local_activity import PreparedAttempt, PreparedCancellationObserved, PreparedLocalRunner
|
|
49
49
|
from ._query_task_authority import QueryTaskAuthority, current_query_authority
|
|
50
50
|
from ._sticky_workflow_cache import CacheKey, StickyWorkflowCache, complete_history
|
|
@@ -3240,7 +3240,7 @@ class Worker:
|
|
|
3240
3240
|
except NonRetryableError as e:
|
|
3241
3241
|
log.exception("activity failed (non-retryable)")
|
|
3242
3242
|
await self._report_activity_task_failure(
|
|
3243
|
-
task_id, attempt_id, "activity failure", message=
|
|
3243
|
+
task_id, attempt_id, "activity failure", message=exception_message(e), failure_type=type(e).__name__,
|
|
3244
3244
|
failure_class=_exception_class_name(e), failure_code=_exception_code(e),
|
|
3245
3245
|
stack_trace=traceback.format_exc(), non_retryable=True,
|
|
3246
3246
|
)
|
|
@@ -3271,7 +3271,8 @@ class Worker:
|
|
|
3271
3271
|
raise error
|
|
3272
3272
|
log.error("activity failed", exc_info=(type(error), error, error.__traceback__))
|
|
3273
3273
|
await self._report_activity_task_failure(
|
|
3274
|
-
task_id, attempt_id, "activity failure", message=
|
|
3274
|
+
task_id, attempt_id, "activity failure", message=exception_message(error),
|
|
3275
|
+
failure_type=type(error).__name__,
|
|
3275
3276
|
failure_class=_exception_class_name(error), failure_code=_exception_code(error),
|
|
3276
3277
|
stack_trace="".join(traceback.format_exception(type(error), error, error.__traceback__)),
|
|
3277
3278
|
)
|
|
@@ -3573,7 +3574,7 @@ class Worker:
|
|
|
3573
3574
|
)
|
|
3574
3575
|
return "failed"
|
|
3575
3576
|
except QueryFailed as e:
|
|
3576
|
-
message =
|
|
3577
|
+
message = exception_message(e)
|
|
3577
3578
|
if "unknown query" in message:
|
|
3578
3579
|
reason = "rejected_unknown_query"
|
|
3579
3580
|
elif message.startswith("workflow replay failed before query:"):
|
|
@@ -3594,7 +3595,7 @@ class Worker:
|
|
|
3594
3595
|
await self._fail_query_task(
|
|
3595
3596
|
query_task_id,
|
|
3596
3597
|
attempt,
|
|
3597
|
-
|
|
3598
|
+
exception_message(e, fallback="query execution failed"),
|
|
3598
3599
|
reason="query_rejected",
|
|
3599
3600
|
failure_type=type(e).__name__,
|
|
3600
3601
|
stack_trace=traceback.format_exc(),
|
|
@@ -3631,7 +3632,7 @@ class Worker:
|
|
|
3631
3632
|
await self._fail_query_task(
|
|
3632
3633
|
query_task_id,
|
|
3633
3634
|
attempt,
|
|
3634
|
-
|
|
3635
|
+
exception_message(e, fallback="query result completion was rejected by the server"),
|
|
3635
3636
|
reason=server_reason if server_reason else "query_result_completion_failed",
|
|
3636
3637
|
failure_type=type(e).__name__,
|
|
3637
3638
|
stack_trace=traceback.format_exc(),
|
|
@@ -3667,7 +3668,7 @@ class Worker:
|
|
|
3667
3668
|
await self._fail_query_task(
|
|
3668
3669
|
query_task_id,
|
|
3669
3670
|
attempt,
|
|
3670
|
-
|
|
3671
|
+
exception_message(e, fallback="query result completion failed"),
|
|
3671
3672
|
reason="query_result_completion_failed",
|
|
3672
3673
|
failure_type=type(e).__name__,
|
|
3673
3674
|
stack_trace=traceback.format_exc(),
|
|
@@ -4075,7 +4076,7 @@ class Worker:
|
|
|
4075
4076
|
return await self._reject_update_validation_task(
|
|
4076
4077
|
task_id,
|
|
4077
4078
|
attempt,
|
|
4078
|
-
|
|
4079
|
+
exception_message(exc, fallback="update validator rejected the request"),
|
|
4079
4080
|
reason="update_validator_rejected",
|
|
4080
4081
|
failure_type=exc.exception_type or type(exc).__name__,
|
|
4081
4082
|
validation_errors=exc.validation_errors,
|
|
@@ -4085,7 +4086,7 @@ class Worker:
|
|
|
4085
4086
|
return await self._reject_update_validation_task(
|
|
4086
4087
|
task_id,
|
|
4087
4088
|
attempt,
|
|
4088
|
-
|
|
4089
|
+
exception_message(exc),
|
|
4089
4090
|
reason="update_validation_worker_failed",
|
|
4090
4091
|
failure_type=type(exc).__name__,
|
|
4091
4092
|
stack_trace=traceback.format_exc(),
|
|
@@ -4094,7 +4095,7 @@ class Worker:
|
|
|
4094
4095
|
return await self._reject_update_validation_task(
|
|
4095
4096
|
task_id,
|
|
4096
4097
|
attempt,
|
|
4097
|
-
|
|
4098
|
+
exception_message(exc, fallback="update validator rejected the request"),
|
|
4098
4099
|
reason="update_validator_rejected",
|
|
4099
4100
|
failure_type=type(exc).__name__,
|
|
4100
4101
|
stack_trace=traceback.format_exc(),
|
|
@@ -43,6 +43,7 @@ from ._cancellation_scope_history import (
|
|
|
43
43
|
ScopeBoundary,
|
|
44
44
|
)
|
|
45
45
|
from ._cooperative_cancellation import CancellationDelivery, read_cancellation_history
|
|
46
|
+
from ._failure_reporting import exception_message
|
|
46
47
|
from .cancellation import (
|
|
47
48
|
CancellationContext,
|
|
48
49
|
CancellationPolicy,
|
|
@@ -3292,7 +3293,7 @@ def _prepare_query_state(
|
|
|
3292
3293
|
raise
|
|
3293
3294
|
except Exception as exc:
|
|
3294
3295
|
state.outcome.close()
|
|
3295
|
-
raise QueryFailed(
|
|
3296
|
+
raise QueryFailed(exception_message(exc, fallback=f"query {query_name!r} failed")) from exc
|
|
3296
3297
|
except BaseException:
|
|
3297
3298
|
state.outcome.close()
|
|
3298
3299
|
raise
|
|
@@ -3594,7 +3595,7 @@ def _invoke_update_validator(
|
|
|
3594
3595
|
except Exception as exc:
|
|
3595
3596
|
errors = exc.errors if isinstance(exc, InvalidArgument) else None
|
|
3596
3597
|
raise UpdateRejected(
|
|
3597
|
-
|
|
3598
|
+
exception_message(exc, fallback=f"update validator {update_name!r} rejected the request"),
|
|
3598
3599
|
exception_type=type(exc).__name__,
|
|
3599
3600
|
validation_errors=errors,
|
|
3600
3601
|
) from exc
|
|
@@ -3614,7 +3615,7 @@ def _accepted_update_payload(
|
|
|
3614
3615
|
|
|
3615
3616
|
|
|
3616
3617
|
def _fail_update_from_exception(update_id: str, prefix: str, exc: Exception) -> FailUpdate:
|
|
3617
|
-
message =
|
|
3618
|
+
message = exception_message(exc)
|
|
3618
3619
|
return FailUpdate(
|
|
3619
3620
|
update_id=update_id,
|
|
3620
3621
|
message=f"{prefix}: {message}",
|
|
@@ -3628,7 +3629,7 @@ def _exception_class_name(exc: BaseException) -> str:
|
|
|
3628
3629
|
|
|
3629
3630
|
|
|
3630
3631
|
def _fail_workflow_from_exception(exc: BaseException, *, prefix: str | None = None) -> FailWorkflow:
|
|
3631
|
-
message =
|
|
3632
|
+
message = exception_message(exc)
|
|
3632
3633
|
if prefix:
|
|
3633
3634
|
message = f"{prefix}: {message}"
|
|
3634
3635
|
|
|
@@ -3645,12 +3646,12 @@ def _fail_workflow_from_exception(exc: BaseException, *, prefix: str | None = No
|
|
|
3645
3646
|
"initiating_failure": {
|
|
3646
3647
|
"type": type(initiating).__name__,
|
|
3647
3648
|
"class": _exception_class_name(initiating),
|
|
3648
|
-
"message":
|
|
3649
|
+
"message": exception_message(initiating),
|
|
3649
3650
|
},
|
|
3650
3651
|
"compensation_failure": {
|
|
3651
3652
|
"type": type(compensation).__name__,
|
|
3652
3653
|
"class": _exception_class_name(compensation),
|
|
3653
|
-
"message":
|
|
3654
|
+
"message": exception_message(compensation),
|
|
3654
3655
|
"activity_type": exc.compensation_activity_type,
|
|
3655
3656
|
"registration_order": exc.compensation_registration_order,
|
|
3656
3657
|
},
|
{durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow.egg-info/SOURCES.txt
RENAMED
|
@@ -83,6 +83,7 @@ tests/test_cooperative_cancellation_worker.py
|
|
|
83
83
|
tests/test_cooperative_remote_worker.py
|
|
84
84
|
tests/test_docstring_cross_references.py
|
|
85
85
|
tests/test_durable_selection.py
|
|
86
|
+
tests/test_empty_callback_failure.py
|
|
86
87
|
tests/test_errors.py
|
|
87
88
|
tests/test_external_storage.py
|
|
88
89
|
tests/test_external_task_input.py
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
from unittest.mock import AsyncMock
|
|
5
|
+
|
|
6
|
+
import pytest
|
|
7
|
+
|
|
8
|
+
from durable_workflow import serializer, workflow
|
|
9
|
+
from durable_workflow.client import Client
|
|
10
|
+
from durable_workflow.errors import NonRetryableError
|
|
11
|
+
from durable_workflow.external_task_result import parse_external_task_result
|
|
12
|
+
from durable_workflow.invocable import handle_invocable_activity
|
|
13
|
+
from durable_workflow.worker import Worker
|
|
14
|
+
from durable_workflow.workflow import _fail_update_from_exception, _fail_workflow_from_exception
|
|
15
|
+
from tests.query_task_helpers import leased_query_task
|
|
16
|
+
from tests.test_cooperative_remote_worker import make_owner, task
|
|
17
|
+
from tests.test_invocable import activity_input
|
|
18
|
+
from tests.test_worker import mock_client # noqa: F401 (shared fixture)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
async def application_failure(kind: str, message: str) -> None:
|
|
22
|
+
if kind == "NonRetryableError":
|
|
23
|
+
raise NonRetryableError(message)
|
|
24
|
+
raise AssertionError(message)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@pytest.mark.parametrize("message", ["", " \t\n", " original failure "])
|
|
28
|
+
@pytest.mark.parametrize("kind", ["AssertionError", "NonRetryableError"])
|
|
29
|
+
@pytest.mark.parametrize("supervised", [False, True])
|
|
30
|
+
async def test_callback_failure_reports_a_nonempty_message_with_original_authority(
|
|
31
|
+
monkeypatch: pytest.MonkeyPatch, message: str, kind: str, supervised: bool,
|
|
32
|
+
) -> None:
|
|
33
|
+
if supervised:
|
|
34
|
+
worker, client = await make_owner(monkeypatch)
|
|
35
|
+
else:
|
|
36
|
+
client = AsyncMock(spec=Client)
|
|
37
|
+
worker = Worker(client, task_queue="queue", worker_id="owner")
|
|
38
|
+
worker.activities["remote"] = application_failure
|
|
39
|
+
try:
|
|
40
|
+
outcome = await worker._run_activity_task(task(kind, message))
|
|
41
|
+
assert outcome == ("failed_non_retryable" if kind == "NonRetryableError" else "failed")
|
|
42
|
+
client.fail_activity_task.assert_awaited_once()
|
|
43
|
+
report = client.fail_activity_task.await_args.kwargs
|
|
44
|
+
assert report["message"] == (message if message.strip() else kind)
|
|
45
|
+
assert report["failure_type"] == kind
|
|
46
|
+
assert report["failure_class"].endswith("." + kind)
|
|
47
|
+
assert report.get("non_retryable", False) is (kind == "NonRetryableError")
|
|
48
|
+
assert report["task_id"] == "remote-task"
|
|
49
|
+
assert report["activity_attempt_id"] == "attempt"
|
|
50
|
+
assert report["lease_owner"] == "owner"
|
|
51
|
+
assert "application_failure" in report["stack_trace"]
|
|
52
|
+
client.complete_activity_task.assert_not_awaited()
|
|
53
|
+
finally:
|
|
54
|
+
await worker.stop()
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
@pytest.mark.parametrize("message", ["", " \t\n", " original failure "])
|
|
58
|
+
@pytest.mark.parametrize("kind", ["AssertionError", "NonRetryableError"])
|
|
59
|
+
async def test_invocable_failure_keeps_a_valid_typed_envelope(message: str, kind: str) -> None:
|
|
60
|
+
output = await handle_invocable_activity(
|
|
61
|
+
activity_input(kind, message), {"billing.charge-card": application_failure},
|
|
62
|
+
)
|
|
63
|
+
failure: Any = parse_external_task_result(output).failure
|
|
64
|
+
assert failure.message == (message if message.strip() else kind)
|
|
65
|
+
assert failure.type == kind
|
|
66
|
+
assert "application_failure" in failure.stack_trace
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
@pytest.mark.parametrize("message", ["", " \t\n", " original failure "])
|
|
70
|
+
def test_workflow_and_update_failures_have_useful_messages(message: str) -> None:
|
|
71
|
+
error = AssertionError(message)
|
|
72
|
+
expected = message if message.strip() else "AssertionError"
|
|
73
|
+
failed = _fail_workflow_from_exception(error)
|
|
74
|
+
assert failed.message == expected
|
|
75
|
+
assert failed.exception_type == "AssertionError"
|
|
76
|
+
update = _fail_update_from_exception("update", "update rejected", error)
|
|
77
|
+
assert update.message == "update rejected: " + expected
|
|
78
|
+
assert update.exception_type == "AssertionError"
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
@workflow.defn(name="tests.blank-query-and-validator")
|
|
82
|
+
class BlankQueryAndValidatorWorkflow:
|
|
83
|
+
message = ""
|
|
84
|
+
|
|
85
|
+
@workflow.query("status")
|
|
86
|
+
def status(self) -> str:
|
|
87
|
+
raise AssertionError(type(self).message)
|
|
88
|
+
|
|
89
|
+
@workflow.update("approve")
|
|
90
|
+
def approve(self) -> None:
|
|
91
|
+
return None
|
|
92
|
+
|
|
93
|
+
@approve.validator # type: ignore[attr-defined]
|
|
94
|
+
def validate_approve(self) -> None:
|
|
95
|
+
raise AssertionError(type(self).message)
|
|
96
|
+
|
|
97
|
+
def run(self, ctx: Any) -> str:
|
|
98
|
+
return "waiting"
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def blank_workflow_task(**fields: Any) -> dict[str, Any]:
|
|
102
|
+
return {
|
|
103
|
+
"workflow_type": "tests.blank-query-and-validator",
|
|
104
|
+
"history_events": [],
|
|
105
|
+
"workflow_arguments": serializer.envelope([], codec="avro"),
|
|
106
|
+
"payload_codec": "avro",
|
|
107
|
+
**fields,
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
@pytest.mark.parametrize("message", ["", " \t\n", " original failure "])
|
|
112
|
+
async def test_query_failure_reports_a_nonempty_message(
|
|
113
|
+
mock_client: AsyncMock, message: str, monkeypatch: pytest.MonkeyPatch, # noqa: F811
|
|
114
|
+
) -> None:
|
|
115
|
+
monkeypatch.setattr(BlankQueryAndValidatorWorkflow, "message", message)
|
|
116
|
+
worker = Worker(mock_client, task_queue="q1", workflows=[BlankQueryAndValidatorWorkflow])
|
|
117
|
+
query = blank_workflow_task(
|
|
118
|
+
query_task_id="qt-blank", query_task_attempt=3, query_name="status",
|
|
119
|
+
query_arguments=serializer.envelope([], codec="avro"),
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
assert await worker._run_query_task(leased_query_task(worker, query)) == "failed"
|
|
123
|
+
|
|
124
|
+
report = mock_client.fail_query_task.await_args.kwargs
|
|
125
|
+
assert report["message"] == (message if message.strip() else "query 'status' failed")
|
|
126
|
+
assert report["reason"] == "query_rejected"
|
|
127
|
+
assert report["query_task_id"] == "qt-blank"
|
|
128
|
+
assert report["query_task_attempt"] == 3
|
|
129
|
+
mock_client.complete_query_task.assert_not_awaited()
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
@pytest.mark.parametrize("message", ["", " \t\n", " original failure "])
|
|
133
|
+
async def test_update_validator_rejection_reports_a_nonempty_message(
|
|
134
|
+
mock_client: AsyncMock, message: str, monkeypatch: pytest.MonkeyPatch, # noqa: F811
|
|
135
|
+
) -> None:
|
|
136
|
+
monkeypatch.setattr(BlankQueryAndValidatorWorkflow, "message", message)
|
|
137
|
+
worker = Worker(
|
|
138
|
+
mock_client, task_queue="q1", workflows=[BlankQueryAndValidatorWorkflow], worker_id="validator",
|
|
139
|
+
)
|
|
140
|
+
validation = blank_workflow_task(
|
|
141
|
+
task_kind="update_validation", update_validation_task_id="uv-blank", update_validation_attempt=2,
|
|
142
|
+
update_name="approve", update_arguments=serializer.envelope([], codec="avro"),
|
|
143
|
+
workflow_id="wf", run_id="run",
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
assert await worker._run_update_validation_task(validation) == "rejected"
|
|
147
|
+
|
|
148
|
+
rejection = mock_client.reject_update_validation_task.await_args.kwargs
|
|
149
|
+
expected = message if message.strip() else "update validator 'approve' rejected the request"
|
|
150
|
+
assert expected in rejection["message"]
|
|
151
|
+
assert rejection["message"].strip()
|
|
152
|
+
assert rejection["reason"] == "update_validator_rejected"
|
|
153
|
+
assert rejection["failure_type"] == "AssertionError"
|
|
154
|
+
assert rejection["update_validation_task_id"] == "uv-blank"
|
|
155
|
+
assert rejection["update_validation_attempt"] == 2
|
|
156
|
+
mock_client.approve_update_validation_task.assert_not_awaited()
|
|
@@ -344,8 +344,15 @@ class NexusCooperativeDeliveryWorkflow:
|
|
|
344
344
|
return error.request_id
|
|
345
345
|
|
|
346
346
|
|
|
347
|
+
@workflow.defn(name="tests.replay.blank-failure")
|
|
348
|
+
class BlankFailureWorkflow:
|
|
349
|
+
def run(self, ctx: WorkflowContext, message: str) -> None:
|
|
350
|
+
raise AssertionError(message)
|
|
351
|
+
|
|
352
|
+
|
|
347
353
|
WORKFLOWS = [
|
|
348
354
|
PendingFinally,
|
|
355
|
+
BlankFailureWorkflow,
|
|
349
356
|
IdentityAcrossReplay,
|
|
350
357
|
IdentityContinueAsNew,
|
|
351
358
|
PersistedClockWorkflow,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow/_cancellation_scope.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow/_prepared_local_activity.py
RENAMED
|
File without changes
|
{durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow/_query_task_authority.py
RENAMED
|
File without changes
|
{durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow/_sticky_workflow_cache.py
RENAMED
|
File without changes
|
|
File without changes
|
{durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow/auth_composition.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow/external_storage.py
RENAMED
|
File without changes
|
{durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow/external_task_input.py
RENAMED
|
File without changes
|
{durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow/external_task_result.py
RENAMED
|
File without changes
|
{durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow/history_bundle_verify.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow/python_conformance.py
RENAMED
|
File without changes
|
{durable_workflow-2.12.2 → durable_workflow-2.12.3}/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
|
{durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow/telemetry_carrier.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow.egg-info/entry_points.txt
RENAMED
|
File without changes
|
{durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow.egg-info/requires.txt
RENAMED
|
File without changes
|
{durable_workflow-2.12.2 → durable_workflow-2.12.3}/src/durable_workflow.egg-info/top_level.txt
RENAMED
|
File without changes
|
{durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_activity_cancellation_policies.py
RENAMED
|
File without changes
|
|
File without changes
|
{durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_activity_heartbeat_authority.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.12.2 → durable_workflow-2.12.3}/tests/test_cancellation_remaining_time.py
RENAMED
|
File without changes
|
{durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_cancellation_scope_admission.py
RENAMED
|
File without changes
|
{durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_cancellation_scope_authoring.py
RENAMED
|
File without changes
|
{durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_cancellation_scope_boundary.py
RENAMED
|
File without changes
|
{durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_cancellation_scope_opening.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
|
{durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_control_plane_parity_fixtures.py
RENAMED
|
File without changes
|
|
File without changes
|
{durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_cooperative_cancellation_client.py
RENAMED
|
File without changes
|
{durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_cooperative_cancellation_worker.py
RENAMED
|
File without changes
|
|
File without changes
|
{durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_docstring_cross_references.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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{durable_workflow-2.12.2 → durable_workflow-2.12.3}/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
|
{durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_prepared_local_activity_client.py
RENAMED
|
File without changes
|
{durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_prepared_local_activity_groups.py
RENAMED
|
File without changes
|
{durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_prepared_local_activity_policies.py
RENAMED
|
File without changes
|
{durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_prepared_local_activity_worker.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
|
|
File without changes
|
|
File without changes
|
{durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_run_cancellation_scope_replay.py
RENAMED
|
File without changes
|
{durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_runtime_external_payload_transport.py
RENAMED
|
File without changes
|
|
File without changes
|
{durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_scoped_run_cancellation_context.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_standalone_activity_client.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.12.2 → durable_workflow-2.12.3}/tests/test_threaded_heartbeat_example.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{durable_workflow-2.12.2 → durable_workflow-2.12.3}/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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_workflow_entrypoint_validation.py
RENAMED
|
File without changes
|
{durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_workflow_handler_validation.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{durable_workflow-2.12.2 → durable_workflow-2.12.3}/tests/test_workflow_updates_conformance.py
RENAMED
|
File without changes
|