From 80766bc6d361ab56289d8777707a6b7de061d889 Mon Sep 17 00:00:00 2001 From: Tim Conley Date: Wed, 3 Dec 2025 13:43:50 -0800 Subject: [PATCH 01/10] WIP pyupgrade --- scripts/gen_payload_visitor.py | 4 +- scripts/gen_protos.py | 5 +- scripts/run_bench.py | 2 +- temporalio/activity.py | 72 +- temporalio/bridge/_visitor.py | 3 +- temporalio/bridge/client.py | 41 +- temporalio/bridge/metric.py | 31 +- temporalio/bridge/runtime.py | 27 +- temporalio/bridge/services_generated.py | 687 ++--- temporalio/bridge/testing.py | 21 +- temporalio/bridge/worker.py | 20 +- temporalio/client.py | 1630 ++++++----- temporalio/common.py | 118 +- .../openai_agents/_heartbeat_decorator.py | 3 +- .../openai_agents/_invoke_model_activity.py | 20 +- temporalio/contrib/openai_agents/_mcp.py | 73 +- .../openai_agents/_model_parameters.py | 30 +- .../contrib/openai_agents/_openai_runner.py | 12 +- .../openai_agents/_temporal_model_stub.py | 31 +- .../openai_agents/_temporal_openai_agents.py | 13 +- .../openai_agents/_temporal_trace_provider.py | 8 +- .../openai_agents/_trace_interceptor.py | 11 +- temporalio/contrib/openai_agents/testing.py | 27 +- temporalio/contrib/openai_agents/workflow.py | 35 +- temporalio/contrib/opentelemetry.py | 56 +- temporalio/contrib/pydantic.py | 8 +- temporalio/converter.py | 119 +- temporalio/envconfig.py | 69 +- temporalio/exceptions.py | 33 +- temporalio/nexus/_decorators.py | 22 +- temporalio/nexus/_link_conversion.py | 2 +- temporalio/nexus/_operation_context.py | 207 +- temporalio/nexus/_operation_handlers.py | 3 +- temporalio/nexus/_token.py | 4 +- temporalio/nexus/_util.py | 15 +- temporalio/plugin.py | 19 +- temporalio/runtime.py | 61 +- temporalio/service.py | 59 +- temporalio/testing/_activity.py | 15 +- temporalio/testing/_workflow.py | 63 +- temporalio/types.py | 9 +- temporalio/worker/_activity.py | 55 +- temporalio/worker/_command_aware_visitor.py | 5 +- temporalio/worker/_interceptor.py | 108 +- temporalio/worker/_nexus.py | 14 +- temporalio/worker/_plugin.py | 3 +- temporalio/worker/_replayer.py | 33 +- temporalio/worker/_tuning.py | 41 +- temporalio/worker/_worker.py | 114 +- temporalio/worker/_workflow.py | 54 +- temporalio/worker/_workflow_instance.py | 397 ++- .../worker/workflow_sandbox/_importer.py | 44 +- .../worker/workflow_sandbox/_in_sandbox.py | 8 +- .../worker/workflow_sandbox/_restrictions.py | 54 +- temporalio/worker/workflow_sandbox/_runner.py | 15 +- temporalio/workflow.py | 2458 ++++++++--------- tests/api/test_grpc_stub.py | 7 +- tests/bridge/test_runtime.py | 2 +- tests/conftest.py | 2 +- tests/contrib/openai_agents/test_openai.py | 72 +- tests/contrib/pydantic/activities.py | 4 +- tests/contrib/pydantic/models.py | 32 +- tests/contrib/pydantic/models_2.py | 17 +- tests/contrib/pydantic/workflows.py | 8 +- tests/contrib/test_opentelemetry.py | 35 +- tests/helpers/__init__.py | 30 +- tests/helpers/external_coroutine.py | 4 +- tests/helpers/nexus.py | 13 +- tests/helpers/worker.py | 63 +- tests/nexus/test_handler.py | 16 +- tests/nexus/test_handler_async_operation.py | 7 +- .../test_handler_interface_implementation.py | 2 +- .../test_handler_operation_definitions.py | 4 +- .../test_use_existing_conflict_policy.py | 2 +- tests/nexus/test_workflow_caller.py | 15 +- ...test_workflow_caller_cancellation_types.py | 4 +- ...llation_types_when_cancel_handler_fails.py | 8 +- .../test_workflow_caller_error_chains.py | 3 +- tests/nexus/test_workflow_run_operation.py | 2 +- tests/test_client.py | 17 +- tests/test_converter.py | 93 +- tests/test_plugins.py | 5 +- tests/test_runtime.py | 6 +- tests/test_serialization_context.py | 59 +- tests/test_service.py | 21 +- tests/test_workflow.py | 19 +- tests/testing/test_workflow.py | 4 +- tests/worker/test_activity.py | 49 +- tests/worker/test_command_aware_visitor.py | 7 +- tests/worker/test_interceptor.py | 11 +- tests/worker/test_replayer.py | 4 +- tests/worker/test_update_with_start.py | 7 +- tests/worker/test_visitor.py | 2 +- tests/worker/test_worker.py | 17 +- tests/worker/test_workflow.py | 187 +- .../workflow_sandbox/test_restrictions.py | 4 +- tests/worker/workflow_sandbox/test_runner.py | 25 +- 97 files changed, 3921 insertions(+), 4059 deletions(-) diff --git a/scripts/gen_payload_visitor.py b/scripts/gen_payload_visitor.py index f2482cae1..eabfd9e6a 100644 --- a/scripts/gen_payload_visitor.py +++ b/scripts/gen_payload_visitor.py @@ -44,7 +44,7 @@ def emit_loop( def emit_singular( - field_name: str, access_expr: str, child_method: str, presence_word: Optional[str] + field_name: str, access_expr: str, child_method: str, presence_word: str | None ) -> str: # Helper to emit a singular field visit with presence check and optional headers guard if presence_word: @@ -152,7 +152,7 @@ async def _visit_payload_container(self, fs, o): """, ] - def check_repeated(self, child_desc, field, iter_expr) -> Optional[str]: + def check_repeated(self, child_desc, field, iter_expr) -> str | None: # Special case for repeated payloads, handle them directly if child_desc.full_name == Payload.DESCRIPTOR.full_name: return emit_singular(field.name, iter_expr, "payload_container", None) diff --git a/scripts/gen_protos.py b/scripts/gen_protos.py index 6fadb9ff6..131f094f4 100644 --- a/scripts/gen_protos.py +++ b/scripts/gen_protos.py @@ -4,9 +4,10 @@ import subprocess import sys import tempfile +from collections.abc import Mapping from functools import partial from pathlib import Path -from typing import List, Mapping +from typing import List base_dir = Path(__file__).parent.parent proto_dir = ( @@ -64,7 +65,7 @@ def fix_generated_output(base_path: Path): - protoc doesn't generate the correct import paths (https://github.com/protocolbuffers/protobuf/issues/1491) """ - imports: Mapping[str, List[str]] = collections.defaultdict(list) + imports: Mapping[str, list[str]] = collections.defaultdict(list) for p in base_path.iterdir(): if p.is_dir(): fix_generated_output(p) diff --git a/scripts/run_bench.py b/scripts/run_bench.py index decbe4810..ba5a6923e 100644 --- a/scripts/run_bench.py +++ b/scripts/run_bench.py @@ -5,9 +5,9 @@ import sys import time import uuid +from collections.abc import AsyncIterator from contextlib import asynccontextmanager from datetime import timedelta -from typing import AsyncIterator from temporalio import activity, workflow from temporalio.testing import WorkflowEnvironment diff --git a/temporalio/activity.py b/temporalio/activity.py index d726b9ef2..5d7857161 100644 --- a/temporalio/activity.py +++ b/temporalio/activity.py @@ -15,20 +15,16 @@ import inspect import logging import threading +from collections.abc import Callable, Iterator, Mapping, MutableMapping, Sequence from contextlib import AbstractContextManager, contextmanager from dataclasses import dataclass from datetime import datetime, timedelta from typing import ( TYPE_CHECKING, Any, - Callable, - Iterator, List, - Mapping, - MutableMapping, NoReturn, Optional, - Sequence, Tuple, Type, Union, @@ -53,7 +49,7 @@ def defn(fn: CallableType) -> CallableType: ... @overload def defn( - *, name: Optional[str] = None, no_thread_cancel_exception: bool = False + *, name: str | None = None, no_thread_cancel_exception: bool = False ) -> Callable[[CallableType], CallableType]: ... @@ -64,9 +60,9 @@ def defn( def defn( - fn: Optional[CallableType] = None, + fn: CallableType | None = None, # type: ignore[reportInvalidTypeVarUse] *, - name: Optional[str] = None, + name: str | None = None, no_thread_cancel_exception: bool = False, dynamic: bool = False, ): @@ -111,11 +107,11 @@ class Info: attempt: int current_attempt_scheduled_time: datetime heartbeat_details: Sequence[Any] - heartbeat_timeout: Optional[timedelta] + heartbeat_timeout: timedelta | None is_local: bool - schedule_to_close_timeout: Optional[timedelta] + schedule_to_close_timeout: timedelta | None scheduled_time: datetime - start_to_close_timeout: Optional[timedelta] + start_to_close_timeout: timedelta | None started_time: datetime task_queue: str task_token: bytes @@ -124,7 +120,7 @@ class Info: workflow_run_id: str workflow_type: str priority: temporalio.common.Priority - retry_policy: Optional[temporalio.common.RetryPolicy] + retry_policy: temporalio.common.RetryPolicy | None """The retry policy of this activity. Note that the server may have set a different policy than the one provided when scheduling the activity. @@ -151,7 +147,7 @@ def _logger_details(self) -> Mapping[str, Any]: @dataclass class _ActivityCancellationDetailsHolder: - details: Optional[ActivityCancellationDetails] = None + details: ActivityCancellationDetails | None = None @dataclass(frozen=True) @@ -183,20 +179,20 @@ def _from_proto( class _Context: info: Callable[[], Info] # This is optional because during interceptor init it is not present - heartbeat: Optional[Callable[..., None]] + heartbeat: Callable[..., None] | None cancelled_event: _CompositeEvent worker_shutdown_event: _CompositeEvent - shield_thread_cancel_exception: Optional[Callable[[], AbstractContextManager]] - payload_converter_class_or_instance: Union[ - Type[temporalio.converter.PayloadConverter], - temporalio.converter.PayloadConverter, - ] - runtime_metric_meter: Optional[temporalio.common.MetricMeter] - client: Optional[Client] + shield_thread_cancel_exception: Callable[[], AbstractContextManager] | None + payload_converter_class_or_instance: ( + type[temporalio.converter.PayloadConverter] + | temporalio.converter.PayloadConverter + ) + runtime_metric_meter: temporalio.common.MetricMeter | None + client: Client | None cancellation_details: _ActivityCancellationDetailsHolder - _logger_details: Optional[Mapping[str, Any]] = None - _payload_converter: Optional[temporalio.converter.PayloadConverter] = None - _metric_meter: Optional[temporalio.common.MetricMeter] = None + _logger_details: Mapping[str, Any] | None = None + _payload_converter: temporalio.converter.PayloadConverter | None = None + _metric_meter: temporalio.common.MetricMeter | None = None @staticmethod def current() -> _Context: @@ -258,9 +254,9 @@ def metric_meter(self) -> temporalio.common.MetricMeter: @dataclass class _CompositeEvent: # This should always be present, but is sometimes lazily set internally - thread_event: Optional[threading.Event] + thread_event: threading.Event | None # Async event only for async activities - async_event: Optional[asyncio.Event] + async_event: asyncio.Event | None def set(self) -> None: if not self.thread_event: @@ -279,7 +275,7 @@ async def wait(self) -> None: raise RuntimeError("not in async activity") await self.async_event.wait() - def wait_sync(self, timeout: Optional[float] = None) -> None: + def wait_sync(self, timeout: float | None = None) -> None: if not self.thread_event: raise RuntimeError("Missing event") self.thread_event.wait(timeout) @@ -330,7 +326,7 @@ def info() -> Info: return _Context.current().info() -def cancellation_details() -> Optional[ActivityCancellationDetails]: +def cancellation_details() -> ActivityCancellationDetails | None: """Cancellation details of the current activity, if any. Once set, cancellation details do not change.""" return _Context.current().cancellation_details.details @@ -398,7 +394,7 @@ async def wait_for_cancelled() -> None: await _Context.current().cancelled_event.wait() -def wait_for_cancelled_sync(timeout: Optional[Union[timedelta, float]] = None) -> None: +def wait_for_cancelled_sync(timeout: timedelta | float | None = None) -> None: """Synchronously block while waiting for a cancellation request on this activity. @@ -437,7 +433,7 @@ async def wait_for_worker_shutdown() -> None: def wait_for_worker_shutdown_sync( - timeout: Optional[Union[timedelta, float]] = None, + timeout: timedelta | float | None = None, ) -> None: """Synchronously block while waiting for shutdown to be called on the worker. @@ -511,9 +507,7 @@ class LoggerAdapter(logging.LoggerAdapter): use by others. Default is False. """ - def __init__( - self, logger: logging.Logger, extra: Optional[Mapping[str, Any]] - ) -> None: + def __init__(self, logger: logging.Logger, extra: Mapping[str, Any] | None) -> None: """Create the logger adapter.""" super().__init__(logger, extra or {}) self.activity_info_on_message = True @@ -522,7 +516,7 @@ def __init__( def process( self, msg: Any, kwargs: MutableMapping[str, Any] - ) -> Tuple[Any, MutableMapping[str, Any]]: + ) -> tuple[Any, MutableMapping[str, Any]]: """Override to add activity details.""" if ( self.activity_info_on_message @@ -559,16 +553,16 @@ def base_logger(self) -> logging.Logger: @dataclass(frozen=True) class _Definition: - name: Optional[str] + name: str | None fn: Callable is_async: bool no_thread_cancel_exception: bool # Types loaded on post init if both are None - arg_types: Optional[List[Type]] = None - ret_type: Optional[Type] = None + arg_types: list[type] | None = None + ret_type: type | None = None @staticmethod - def from_callable(fn: Callable) -> Optional[_Definition]: + def from_callable(fn: Callable) -> _Definition | None: defn = getattr(fn, "__temporal_activity_definition", None) if isinstance(defn, _Definition): # We have to replace the function with the given callable here @@ -592,7 +586,7 @@ def must_from_callable(fn: Callable) -> _Definition: def _apply_to_callable( fn: Callable, *, - activity_name: Optional[str], + activity_name: str | None, no_thread_cancel_exception: bool = False, ) -> None: # Validate the activity diff --git a/temporalio/bridge/_visitor.py b/temporalio/bridge/_visitor.py index 04ec95b3e..e0396cd8d 100644 --- a/temporalio/bridge/_visitor.py +++ b/temporalio/bridge/_visitor.py @@ -1,6 +1,7 @@ # This file is generated by gen_payload_visitor.py. Changes should be made there. import abc -from typing import Any, MutableSequence +from collections.abc import MutableSequence +from typing import Any from temporalio.api.common.v1.message_pb2 import Payload diff --git a/temporalio/bridge/client.py b/temporalio/bridge/client.py index dafd6fb71..d89b330fb 100644 --- a/temporalio/bridge/client.py +++ b/temporalio/bridge/client.py @@ -5,9 +5,10 @@ from __future__ import annotations +from collections.abc import Mapping from dataclasses import dataclass from datetime import timedelta -from typing import Mapping, Optional, Tuple, Type, TypeVar, Union +from typing import Optional, Tuple, Type, TypeVar, Union import google.protobuf.message @@ -20,10 +21,10 @@ class ClientTlsConfig: """Python representation of the Rust struct for configuring TLS.""" - server_root_ca_cert: Optional[bytes] - domain: Optional[str] - client_cert: Optional[bytes] - client_private_key: Optional[bytes] + server_root_ca_cert: bytes | None + domain: str | None + client_cert: bytes | None + client_private_key: bytes | None @dataclass @@ -34,7 +35,7 @@ class ClientRetryConfig: randomization_factor: float multiplier: float max_interval_millis: int - max_elapsed_time_millis: Optional[int] + max_elapsed_time_millis: int | None max_retries: int @@ -51,7 +52,7 @@ class ClientHttpConnectProxyConfig: """Python representation of the Rust struct for configuring HTTP proxy.""" target_host: str - basic_auth: Optional[Tuple[str, str]] + basic_auth: tuple[str, str] | None @dataclass @@ -59,15 +60,15 @@ class ClientConfig: """Python representation of the Rust struct for configuring the client.""" target_url: str - metadata: Mapping[str, Union[str, bytes]] - api_key: Optional[str] + metadata: Mapping[str, str | bytes] + api_key: str | None identity: str - tls_config: Optional[ClientTlsConfig] - retry_config: Optional[ClientRetryConfig] - keep_alive_config: Optional[ClientKeepAliveConfig] + tls_config: ClientTlsConfig | None + retry_config: ClientRetryConfig | None + keep_alive_config: ClientKeepAliveConfig | None client_name: str client_version: str - http_connect_proxy_config: Optional[ClientHttpConnectProxyConfig] + http_connect_proxy_config: ClientHttpConnectProxyConfig | None @dataclass @@ -77,8 +78,8 @@ class RpcCall: rpc: str req: bytes retry: bool - metadata: Mapping[str, Union[str, bytes]] - timeout_millis: Optional[int] + metadata: Mapping[str, str | bytes] + timeout_millis: int | None ProtoMessage = TypeVar("ProtoMessage", bound=google.protobuf.message.Message) @@ -108,11 +109,11 @@ def __init__( self._runtime = runtime self._ref = ref - def update_metadata(self, metadata: Mapping[str, Union[str, bytes]]) -> None: + def update_metadata(self, metadata: Mapping[str, str | bytes]) -> None: """Update underlying metadata on Core client.""" self._ref.update_metadata(metadata) - def update_api_key(self, api_key: Optional[str]) -> None: + def update_api_key(self, api_key: str | None) -> None: """Update underlying API key on Core client.""" self._ref.update_api_key(api_key) @@ -122,10 +123,10 @@ async def call( service: str, rpc: str, req: google.protobuf.message.Message, - resp_type: Type[ProtoMessage], + resp_type: type[ProtoMessage], retry: bool, - metadata: Mapping[str, Union[str, bytes]], - timeout: Optional[timedelta], + metadata: Mapping[str, str | bytes], + timeout: timedelta | None, ) -> ProtoMessage: """Make RPC call using SDK Core.""" # Prepare call diff --git a/temporalio/bridge/metric.py b/temporalio/bridge/metric.py index 399fe5cc5..6bccb82cc 100644 --- a/temporalio/bridge/metric.py +++ b/temporalio/bridge/metric.py @@ -5,7 +5,8 @@ from __future__ import annotations -from typing import Mapping, Optional, Union +from collections.abc import Mapping +from typing import Optional, Union import temporalio.bridge.runtime import temporalio.bridge.temporal_sdk_bridge @@ -15,7 +16,7 @@ class MetricMeter: """Metric meter using SDK Core.""" @staticmethod - def create(runtime: temporalio.bridge.runtime.Runtime) -> Optional[MetricMeter]: + def create(runtime: temporalio.bridge.runtime.Runtime) -> MetricMeter | None: """Create optional metric meter.""" ref = temporalio.bridge.temporal_sdk_bridge.new_metric_meter(runtime._ref) if not ref: @@ -42,8 +43,8 @@ def __init__( self, meter: MetricMeter, name: str, - description: Optional[str], - unit: Optional[str], + description: str | None, + unit: str | None, ) -> None: """Initialize counter metric.""" self._ref = meter._ref.new_counter(name, description, unit) @@ -62,8 +63,8 @@ def __init__( self, meter: MetricMeter, name: str, - description: Optional[str], - unit: Optional[str], + description: str | None, + unit: str | None, ) -> None: """Initialize histogram.""" self._ref = meter._ref.new_histogram(name, description, unit) @@ -82,8 +83,8 @@ def __init__( self, meter: MetricMeter, name: str, - description: Optional[str], - unit: Optional[str], + description: str | None, + unit: str | None, ) -> None: """Initialize histogram.""" self._ref = meter._ref.new_histogram_float(name, description, unit) @@ -102,8 +103,8 @@ def __init__( self, meter: MetricMeter, name: str, - description: Optional[str], - unit: Optional[str], + description: str | None, + unit: str | None, ) -> None: """Initialize histogram.""" self._ref = meter._ref.new_histogram_duration(name, description, unit) @@ -122,8 +123,8 @@ def __init__( self, meter: MetricMeter, name: str, - description: Optional[str], - unit: Optional[str], + description: str | None, + unit: str | None, ) -> None: """Initialize gauge.""" self._ref = meter._ref.new_gauge(name, description, unit) @@ -142,8 +143,8 @@ def __init__( self, meter: MetricMeter, name: str, - description: Optional[str], - unit: Optional[str], + description: str | None, + unit: str | None, ) -> None: """Initialize gauge.""" self._ref = meter._ref.new_gauge_float(name, description, unit) @@ -168,7 +169,7 @@ def __init__( self._ref = ref def with_additional_attributes( - self, new_attrs: Mapping[str, Union[str, int, float, bool]] + self, new_attrs: Mapping[str, str | int | float | bool] ) -> MetricAttributes: """Create new attributes with new attributes appended.""" return MetricAttributes( diff --git a/temporalio/bridge/runtime.py b/temporalio/bridge/runtime.py index 3583c1d46..6d718fe03 100644 --- a/temporalio/bridge/runtime.py +++ b/temporalio/bridge/runtime.py @@ -5,8 +5,9 @@ from __future__ import annotations +from collections.abc import Callable, Mapping, Sequence from dataclasses import dataclass -from typing import Any, Callable, Dict, Mapping, Optional, Sequence, Type +from typing import Any, Dict, Optional, Type from typing_extensions import Protocol @@ -17,7 +18,7 @@ class Runtime: """Runtime for SDK Core.""" @staticmethod - def _raise_in_thread(thread_id: int, exc_type: Type[BaseException]) -> bool: + def _raise_in_thread(thread_id: int, exc_type: type[BaseException]) -> bool: """Internal helper for raising an exception in thread.""" return temporalio.bridge.temporal_sdk_bridge.raise_in_thread( thread_id, exc_type @@ -45,19 +46,19 @@ class LoggingConfig: """Python representation of the Rust struct for logging config.""" filter: str - forward_to: Optional[Callable[[Sequence[BufferedLogEntry]], None]] + forward_to: Callable[[Sequence[BufferedLogEntry]], None] | None @dataclass(frozen=True) class MetricsConfig: """Python representation of the Rust struct for metrics config.""" - opentelemetry: Optional[OpenTelemetryConfig] - prometheus: Optional[PrometheusConfig] + opentelemetry: OpenTelemetryConfig | None + prometheus: PrometheusConfig | None buffered_with_size: int attach_service_name: bool - global_tags: Optional[Mapping[str, str]] - metric_prefix: Optional[str] + global_tags: Mapping[str, str] | None + metric_prefix: str | None @dataclass(frozen=True) @@ -66,7 +67,7 @@ class OpenTelemetryConfig: url: str headers: Mapping[str, str] - metric_periodicity_millis: Optional[int] + metric_periodicity_millis: int | None metric_temporality_delta: bool durations_as_seconds: bool http: bool @@ -80,15 +81,15 @@ class PrometheusConfig: counters_total_suffix: bool unit_suffix: bool durations_as_seconds: bool - histogram_bucket_overrides: Optional[Mapping[str, Sequence[float]]] = None + histogram_bucket_overrides: Mapping[str, Sequence[float]] | None = None @dataclass(frozen=True) class TelemetryConfig: """Python representation of the Rust struct for telemetry config.""" - logging: Optional[LoggingConfig] - metrics: Optional[MetricsConfig] + logging: LoggingConfig | None + metrics: MetricsConfig | None @dataclass(frozen=True) @@ -96,7 +97,7 @@ class RuntimeOptions: """Python representation of the Rust struct for runtime options.""" telemetry: TelemetryConfig - worker_heartbeat_interval_millis: Optional[int] = 60_000 # 60s + worker_heartbeat_interval_millis: int | None = 60_000 # 60s # WARNING: This must match Rust runtime::BufferedLogEntry @@ -124,7 +125,7 @@ def level(self) -> int: ... @property - def fields(self) -> Dict[str, Any]: + def fields(self) -> dict[str, Any]: """Additional log entry fields. Requesting this property performs a conversion from the internal representation to the Python representation on every request. Therefore diff --git a/temporalio/bridge/services_generated.py b/temporalio/bridge/services_generated.py index 036a5198d..ea9af6de7 100644 --- a/temporalio/bridge/services_generated.py +++ b/temporalio/bridge/services_generated.py @@ -3,8 +3,9 @@ from __future__ import annotations +from collections.abc import Mapping from datetime import timedelta -from typing import TYPE_CHECKING, Mapping, Optional, Union +from typing import TYPE_CHECKING, Optional, Union import google.protobuf.empty_pb2 @@ -30,8 +31,8 @@ async def count_workflow_executions( self, req: temporalio.api.workflowservice.v1.CountWorkflowExecutionsRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.CountWorkflowExecutionsResponse: """Invokes the WorkflowService.count_workflow_executions rpc method.""" return await self._client._rpc_call( @@ -48,8 +49,8 @@ async def create_schedule( self, req: temporalio.api.workflowservice.v1.CreateScheduleRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.CreateScheduleResponse: """Invokes the WorkflowService.create_schedule rpc method.""" return await self._client._rpc_call( @@ -66,8 +67,8 @@ async def create_workflow_rule( self, req: temporalio.api.workflowservice.v1.CreateWorkflowRuleRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.CreateWorkflowRuleResponse: """Invokes the WorkflowService.create_workflow_rule rpc method.""" return await self._client._rpc_call( @@ -84,8 +85,8 @@ async def delete_schedule( self, req: temporalio.api.workflowservice.v1.DeleteScheduleRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.DeleteScheduleResponse: """Invokes the WorkflowService.delete_schedule rpc method.""" return await self._client._rpc_call( @@ -102,8 +103,8 @@ async def delete_worker_deployment( self, req: temporalio.api.workflowservice.v1.DeleteWorkerDeploymentRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.DeleteWorkerDeploymentResponse: """Invokes the WorkflowService.delete_worker_deployment rpc method.""" return await self._client._rpc_call( @@ -120,8 +121,8 @@ async def delete_worker_deployment_version( self, req: temporalio.api.workflowservice.v1.DeleteWorkerDeploymentVersionRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.DeleteWorkerDeploymentVersionResponse: """Invokes the WorkflowService.delete_worker_deployment_version rpc method.""" return await self._client._rpc_call( @@ -138,8 +139,8 @@ async def delete_workflow_execution( self, req: temporalio.api.workflowservice.v1.DeleteWorkflowExecutionRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.DeleteWorkflowExecutionResponse: """Invokes the WorkflowService.delete_workflow_execution rpc method.""" return await self._client._rpc_call( @@ -156,8 +157,8 @@ async def delete_workflow_rule( self, req: temporalio.api.workflowservice.v1.DeleteWorkflowRuleRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.DeleteWorkflowRuleResponse: """Invokes the WorkflowService.delete_workflow_rule rpc method.""" return await self._client._rpc_call( @@ -174,8 +175,8 @@ async def deprecate_namespace( self, req: temporalio.api.workflowservice.v1.DeprecateNamespaceRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.DeprecateNamespaceResponse: """Invokes the WorkflowService.deprecate_namespace rpc method.""" return await self._client._rpc_call( @@ -192,8 +193,8 @@ async def describe_batch_operation( self, req: temporalio.api.workflowservice.v1.DescribeBatchOperationRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.DescribeBatchOperationResponse: """Invokes the WorkflowService.describe_batch_operation rpc method.""" return await self._client._rpc_call( @@ -210,8 +211,8 @@ async def describe_deployment( self, req: temporalio.api.workflowservice.v1.DescribeDeploymentRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.DescribeDeploymentResponse: """Invokes the WorkflowService.describe_deployment rpc method.""" return await self._client._rpc_call( @@ -228,8 +229,8 @@ async def describe_namespace( self, req: temporalio.api.workflowservice.v1.DescribeNamespaceRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.DescribeNamespaceResponse: """Invokes the WorkflowService.describe_namespace rpc method.""" return await self._client._rpc_call( @@ -246,8 +247,8 @@ async def describe_schedule( self, req: temporalio.api.workflowservice.v1.DescribeScheduleRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.DescribeScheduleResponse: """Invokes the WorkflowService.describe_schedule rpc method.""" return await self._client._rpc_call( @@ -264,8 +265,8 @@ async def describe_task_queue( self, req: temporalio.api.workflowservice.v1.DescribeTaskQueueRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.DescribeTaskQueueResponse: """Invokes the WorkflowService.describe_task_queue rpc method.""" return await self._client._rpc_call( @@ -282,8 +283,8 @@ async def describe_worker( self, req: temporalio.api.workflowservice.v1.DescribeWorkerRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.DescribeWorkerResponse: """Invokes the WorkflowService.describe_worker rpc method.""" return await self._client._rpc_call( @@ -300,8 +301,8 @@ async def describe_worker_deployment( self, req: temporalio.api.workflowservice.v1.DescribeWorkerDeploymentRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.DescribeWorkerDeploymentResponse: """Invokes the WorkflowService.describe_worker_deployment rpc method.""" return await self._client._rpc_call( @@ -318,8 +319,8 @@ async def describe_worker_deployment_version( self, req: temporalio.api.workflowservice.v1.DescribeWorkerDeploymentVersionRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.DescribeWorkerDeploymentVersionResponse: """Invokes the WorkflowService.describe_worker_deployment_version rpc method.""" return await self._client._rpc_call( @@ -336,8 +337,8 @@ async def describe_workflow_execution( self, req: temporalio.api.workflowservice.v1.DescribeWorkflowExecutionRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.DescribeWorkflowExecutionResponse: """Invokes the WorkflowService.describe_workflow_execution rpc method.""" return await self._client._rpc_call( @@ -354,8 +355,8 @@ async def describe_workflow_rule( self, req: temporalio.api.workflowservice.v1.DescribeWorkflowRuleRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.DescribeWorkflowRuleResponse: """Invokes the WorkflowService.describe_workflow_rule rpc method.""" return await self._client._rpc_call( @@ -372,8 +373,8 @@ async def execute_multi_operation( self, req: temporalio.api.workflowservice.v1.ExecuteMultiOperationRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.ExecuteMultiOperationResponse: """Invokes the WorkflowService.execute_multi_operation rpc method.""" return await self._client._rpc_call( @@ -390,8 +391,8 @@ async def fetch_worker_config( self, req: temporalio.api.workflowservice.v1.FetchWorkerConfigRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.FetchWorkerConfigResponse: """Invokes the WorkflowService.fetch_worker_config rpc method.""" return await self._client._rpc_call( @@ -408,8 +409,8 @@ async def get_cluster_info( self, req: temporalio.api.workflowservice.v1.GetClusterInfoRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.GetClusterInfoResponse: """Invokes the WorkflowService.get_cluster_info rpc method.""" return await self._client._rpc_call( @@ -426,8 +427,8 @@ async def get_current_deployment( self, req: temporalio.api.workflowservice.v1.GetCurrentDeploymentRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.GetCurrentDeploymentResponse: """Invokes the WorkflowService.get_current_deployment rpc method.""" return await self._client._rpc_call( @@ -444,8 +445,8 @@ async def get_deployment_reachability( self, req: temporalio.api.workflowservice.v1.GetDeploymentReachabilityRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.GetDeploymentReachabilityResponse: """Invokes the WorkflowService.get_deployment_reachability rpc method.""" return await self._client._rpc_call( @@ -462,8 +463,8 @@ async def get_search_attributes( self, req: temporalio.api.workflowservice.v1.GetSearchAttributesRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.GetSearchAttributesResponse: """Invokes the WorkflowService.get_search_attributes rpc method.""" return await self._client._rpc_call( @@ -480,8 +481,8 @@ async def get_system_info( self, req: temporalio.api.workflowservice.v1.GetSystemInfoRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.GetSystemInfoResponse: """Invokes the WorkflowService.get_system_info rpc method.""" return await self._client._rpc_call( @@ -498,8 +499,8 @@ async def get_worker_build_id_compatibility( self, req: temporalio.api.workflowservice.v1.GetWorkerBuildIdCompatibilityRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.GetWorkerBuildIdCompatibilityResponse: """Invokes the WorkflowService.get_worker_build_id_compatibility rpc method.""" return await self._client._rpc_call( @@ -516,8 +517,8 @@ async def get_worker_task_reachability( self, req: temporalio.api.workflowservice.v1.GetWorkerTaskReachabilityRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.GetWorkerTaskReachabilityResponse: """Invokes the WorkflowService.get_worker_task_reachability rpc method.""" return await self._client._rpc_call( @@ -534,8 +535,8 @@ async def get_worker_versioning_rules( self, req: temporalio.api.workflowservice.v1.GetWorkerVersioningRulesRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.GetWorkerVersioningRulesResponse: """Invokes the WorkflowService.get_worker_versioning_rules rpc method.""" return await self._client._rpc_call( @@ -552,8 +553,8 @@ async def get_workflow_execution_history( self, req: temporalio.api.workflowservice.v1.GetWorkflowExecutionHistoryRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.GetWorkflowExecutionHistoryResponse: """Invokes the WorkflowService.get_workflow_execution_history rpc method.""" return await self._client._rpc_call( @@ -570,8 +571,8 @@ async def get_workflow_execution_history_reverse( self, req: temporalio.api.workflowservice.v1.GetWorkflowExecutionHistoryReverseRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.GetWorkflowExecutionHistoryReverseResponse: """Invokes the WorkflowService.get_workflow_execution_history_reverse rpc method.""" return await self._client._rpc_call( @@ -588,8 +589,8 @@ async def list_archived_workflow_executions( self, req: temporalio.api.workflowservice.v1.ListArchivedWorkflowExecutionsRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.ListArchivedWorkflowExecutionsResponse: """Invokes the WorkflowService.list_archived_workflow_executions rpc method.""" return await self._client._rpc_call( @@ -606,8 +607,8 @@ async def list_batch_operations( self, req: temporalio.api.workflowservice.v1.ListBatchOperationsRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.ListBatchOperationsResponse: """Invokes the WorkflowService.list_batch_operations rpc method.""" return await self._client._rpc_call( @@ -624,8 +625,8 @@ async def list_closed_workflow_executions( self, req: temporalio.api.workflowservice.v1.ListClosedWorkflowExecutionsRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.ListClosedWorkflowExecutionsResponse: """Invokes the WorkflowService.list_closed_workflow_executions rpc method.""" return await self._client._rpc_call( @@ -642,8 +643,8 @@ async def list_deployments( self, req: temporalio.api.workflowservice.v1.ListDeploymentsRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.ListDeploymentsResponse: """Invokes the WorkflowService.list_deployments rpc method.""" return await self._client._rpc_call( @@ -660,8 +661,8 @@ async def list_namespaces( self, req: temporalio.api.workflowservice.v1.ListNamespacesRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.ListNamespacesResponse: """Invokes the WorkflowService.list_namespaces rpc method.""" return await self._client._rpc_call( @@ -678,8 +679,8 @@ async def list_open_workflow_executions( self, req: temporalio.api.workflowservice.v1.ListOpenWorkflowExecutionsRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.ListOpenWorkflowExecutionsResponse: """Invokes the WorkflowService.list_open_workflow_executions rpc method.""" return await self._client._rpc_call( @@ -696,8 +697,8 @@ async def list_schedule_matching_times( self, req: temporalio.api.workflowservice.v1.ListScheduleMatchingTimesRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.ListScheduleMatchingTimesResponse: """Invokes the WorkflowService.list_schedule_matching_times rpc method.""" return await self._client._rpc_call( @@ -714,8 +715,8 @@ async def list_schedules( self, req: temporalio.api.workflowservice.v1.ListSchedulesRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.ListSchedulesResponse: """Invokes the WorkflowService.list_schedules rpc method.""" return await self._client._rpc_call( @@ -732,8 +733,8 @@ async def list_task_queue_partitions( self, req: temporalio.api.workflowservice.v1.ListTaskQueuePartitionsRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.ListTaskQueuePartitionsResponse: """Invokes the WorkflowService.list_task_queue_partitions rpc method.""" return await self._client._rpc_call( @@ -750,8 +751,8 @@ async def list_worker_deployments( self, req: temporalio.api.workflowservice.v1.ListWorkerDeploymentsRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.ListWorkerDeploymentsResponse: """Invokes the WorkflowService.list_worker_deployments rpc method.""" return await self._client._rpc_call( @@ -768,8 +769,8 @@ async def list_workers( self, req: temporalio.api.workflowservice.v1.ListWorkersRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.ListWorkersResponse: """Invokes the WorkflowService.list_workers rpc method.""" return await self._client._rpc_call( @@ -786,8 +787,8 @@ async def list_workflow_executions( self, req: temporalio.api.workflowservice.v1.ListWorkflowExecutionsRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.ListWorkflowExecutionsResponse: """Invokes the WorkflowService.list_workflow_executions rpc method.""" return await self._client._rpc_call( @@ -804,8 +805,8 @@ async def list_workflow_rules( self, req: temporalio.api.workflowservice.v1.ListWorkflowRulesRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.ListWorkflowRulesResponse: """Invokes the WorkflowService.list_workflow_rules rpc method.""" return await self._client._rpc_call( @@ -822,8 +823,8 @@ async def patch_schedule( self, req: temporalio.api.workflowservice.v1.PatchScheduleRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.PatchScheduleResponse: """Invokes the WorkflowService.patch_schedule rpc method.""" return await self._client._rpc_call( @@ -840,8 +841,8 @@ async def pause_activity( self, req: temporalio.api.workflowservice.v1.PauseActivityRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.PauseActivityResponse: """Invokes the WorkflowService.pause_activity rpc method.""" return await self._client._rpc_call( @@ -858,8 +859,8 @@ async def poll_activity_task_queue( self, req: temporalio.api.workflowservice.v1.PollActivityTaskQueueRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.PollActivityTaskQueueResponse: """Invokes the WorkflowService.poll_activity_task_queue rpc method.""" return await self._client._rpc_call( @@ -876,8 +877,8 @@ async def poll_nexus_task_queue( self, req: temporalio.api.workflowservice.v1.PollNexusTaskQueueRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.PollNexusTaskQueueResponse: """Invokes the WorkflowService.poll_nexus_task_queue rpc method.""" return await self._client._rpc_call( @@ -894,8 +895,8 @@ async def poll_workflow_execution_update( self, req: temporalio.api.workflowservice.v1.PollWorkflowExecutionUpdateRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.PollWorkflowExecutionUpdateResponse: """Invokes the WorkflowService.poll_workflow_execution_update rpc method.""" return await self._client._rpc_call( @@ -912,8 +913,8 @@ async def poll_workflow_task_queue( self, req: temporalio.api.workflowservice.v1.PollWorkflowTaskQueueRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.PollWorkflowTaskQueueResponse: """Invokes the WorkflowService.poll_workflow_task_queue rpc method.""" return await self._client._rpc_call( @@ -930,8 +931,8 @@ async def query_workflow( self, req: temporalio.api.workflowservice.v1.QueryWorkflowRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.QueryWorkflowResponse: """Invokes the WorkflowService.query_workflow rpc method.""" return await self._client._rpc_call( @@ -948,8 +949,8 @@ async def record_activity_task_heartbeat( self, req: temporalio.api.workflowservice.v1.RecordActivityTaskHeartbeatRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.RecordActivityTaskHeartbeatResponse: """Invokes the WorkflowService.record_activity_task_heartbeat rpc method.""" return await self._client._rpc_call( @@ -966,8 +967,8 @@ async def record_activity_task_heartbeat_by_id( self, req: temporalio.api.workflowservice.v1.RecordActivityTaskHeartbeatByIdRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.RecordActivityTaskHeartbeatByIdResponse: """Invokes the WorkflowService.record_activity_task_heartbeat_by_id rpc method.""" return await self._client._rpc_call( @@ -984,8 +985,8 @@ async def record_worker_heartbeat( self, req: temporalio.api.workflowservice.v1.RecordWorkerHeartbeatRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.RecordWorkerHeartbeatResponse: """Invokes the WorkflowService.record_worker_heartbeat rpc method.""" return await self._client._rpc_call( @@ -1002,8 +1003,8 @@ async def register_namespace( self, req: temporalio.api.workflowservice.v1.RegisterNamespaceRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.RegisterNamespaceResponse: """Invokes the WorkflowService.register_namespace rpc method.""" return await self._client._rpc_call( @@ -1020,8 +1021,8 @@ async def request_cancel_workflow_execution( self, req: temporalio.api.workflowservice.v1.RequestCancelWorkflowExecutionRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.RequestCancelWorkflowExecutionResponse: """Invokes the WorkflowService.request_cancel_workflow_execution rpc method.""" return await self._client._rpc_call( @@ -1038,8 +1039,8 @@ async def reset_activity( self, req: temporalio.api.workflowservice.v1.ResetActivityRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.ResetActivityResponse: """Invokes the WorkflowService.reset_activity rpc method.""" return await self._client._rpc_call( @@ -1056,8 +1057,8 @@ async def reset_sticky_task_queue( self, req: temporalio.api.workflowservice.v1.ResetStickyTaskQueueRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.ResetStickyTaskQueueResponse: """Invokes the WorkflowService.reset_sticky_task_queue rpc method.""" return await self._client._rpc_call( @@ -1074,8 +1075,8 @@ async def reset_workflow_execution( self, req: temporalio.api.workflowservice.v1.ResetWorkflowExecutionRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.ResetWorkflowExecutionResponse: """Invokes the WorkflowService.reset_workflow_execution rpc method.""" return await self._client._rpc_call( @@ -1092,8 +1093,8 @@ async def respond_activity_task_canceled( self, req: temporalio.api.workflowservice.v1.RespondActivityTaskCanceledRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.RespondActivityTaskCanceledResponse: """Invokes the WorkflowService.respond_activity_task_canceled rpc method.""" return await self._client._rpc_call( @@ -1110,8 +1111,8 @@ async def respond_activity_task_canceled_by_id( self, req: temporalio.api.workflowservice.v1.RespondActivityTaskCanceledByIdRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.RespondActivityTaskCanceledByIdResponse: """Invokes the WorkflowService.respond_activity_task_canceled_by_id rpc method.""" return await self._client._rpc_call( @@ -1128,8 +1129,8 @@ async def respond_activity_task_completed( self, req: temporalio.api.workflowservice.v1.RespondActivityTaskCompletedRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.RespondActivityTaskCompletedResponse: """Invokes the WorkflowService.respond_activity_task_completed rpc method.""" return await self._client._rpc_call( @@ -1146,8 +1147,8 @@ async def respond_activity_task_completed_by_id( self, req: temporalio.api.workflowservice.v1.RespondActivityTaskCompletedByIdRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.RespondActivityTaskCompletedByIdResponse: """Invokes the WorkflowService.respond_activity_task_completed_by_id rpc method.""" return await self._client._rpc_call( @@ -1164,8 +1165,8 @@ async def respond_activity_task_failed( self, req: temporalio.api.workflowservice.v1.RespondActivityTaskFailedRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.RespondActivityTaskFailedResponse: """Invokes the WorkflowService.respond_activity_task_failed rpc method.""" return await self._client._rpc_call( @@ -1182,8 +1183,8 @@ async def respond_activity_task_failed_by_id( self, req: temporalio.api.workflowservice.v1.RespondActivityTaskFailedByIdRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.RespondActivityTaskFailedByIdResponse: """Invokes the WorkflowService.respond_activity_task_failed_by_id rpc method.""" return await self._client._rpc_call( @@ -1200,8 +1201,8 @@ async def respond_nexus_task_completed( self, req: temporalio.api.workflowservice.v1.RespondNexusTaskCompletedRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.RespondNexusTaskCompletedResponse: """Invokes the WorkflowService.respond_nexus_task_completed rpc method.""" return await self._client._rpc_call( @@ -1218,8 +1219,8 @@ async def respond_nexus_task_failed( self, req: temporalio.api.workflowservice.v1.RespondNexusTaskFailedRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.RespondNexusTaskFailedResponse: """Invokes the WorkflowService.respond_nexus_task_failed rpc method.""" return await self._client._rpc_call( @@ -1236,8 +1237,8 @@ async def respond_query_task_completed( self, req: temporalio.api.workflowservice.v1.RespondQueryTaskCompletedRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.RespondQueryTaskCompletedResponse: """Invokes the WorkflowService.respond_query_task_completed rpc method.""" return await self._client._rpc_call( @@ -1254,8 +1255,8 @@ async def respond_workflow_task_completed( self, req: temporalio.api.workflowservice.v1.RespondWorkflowTaskCompletedRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.RespondWorkflowTaskCompletedResponse: """Invokes the WorkflowService.respond_workflow_task_completed rpc method.""" return await self._client._rpc_call( @@ -1272,8 +1273,8 @@ async def respond_workflow_task_failed( self, req: temporalio.api.workflowservice.v1.RespondWorkflowTaskFailedRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.RespondWorkflowTaskFailedResponse: """Invokes the WorkflowService.respond_workflow_task_failed rpc method.""" return await self._client._rpc_call( @@ -1290,8 +1291,8 @@ async def scan_workflow_executions( self, req: temporalio.api.workflowservice.v1.ScanWorkflowExecutionsRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.ScanWorkflowExecutionsResponse: """Invokes the WorkflowService.scan_workflow_executions rpc method.""" return await self._client._rpc_call( @@ -1308,8 +1309,8 @@ async def set_current_deployment( self, req: temporalio.api.workflowservice.v1.SetCurrentDeploymentRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.SetCurrentDeploymentResponse: """Invokes the WorkflowService.set_current_deployment rpc method.""" return await self._client._rpc_call( @@ -1326,8 +1327,8 @@ async def set_worker_deployment_current_version( self, req: temporalio.api.workflowservice.v1.SetWorkerDeploymentCurrentVersionRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.SetWorkerDeploymentCurrentVersionResponse: """Invokes the WorkflowService.set_worker_deployment_current_version rpc method.""" return await self._client._rpc_call( @@ -1344,8 +1345,8 @@ async def set_worker_deployment_manager( self, req: temporalio.api.workflowservice.v1.SetWorkerDeploymentManagerRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.SetWorkerDeploymentManagerResponse: """Invokes the WorkflowService.set_worker_deployment_manager rpc method.""" return await self._client._rpc_call( @@ -1362,8 +1363,8 @@ async def set_worker_deployment_ramping_version( self, req: temporalio.api.workflowservice.v1.SetWorkerDeploymentRampingVersionRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.SetWorkerDeploymentRampingVersionResponse: """Invokes the WorkflowService.set_worker_deployment_ramping_version rpc method.""" return await self._client._rpc_call( @@ -1380,8 +1381,8 @@ async def shutdown_worker( self, req: temporalio.api.workflowservice.v1.ShutdownWorkerRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.ShutdownWorkerResponse: """Invokes the WorkflowService.shutdown_worker rpc method.""" return await self._client._rpc_call( @@ -1398,8 +1399,8 @@ async def signal_with_start_workflow_execution( self, req: temporalio.api.workflowservice.v1.SignalWithStartWorkflowExecutionRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.SignalWithStartWorkflowExecutionResponse: """Invokes the WorkflowService.signal_with_start_workflow_execution rpc method.""" return await self._client._rpc_call( @@ -1416,8 +1417,8 @@ async def signal_workflow_execution( self, req: temporalio.api.workflowservice.v1.SignalWorkflowExecutionRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.SignalWorkflowExecutionResponse: """Invokes the WorkflowService.signal_workflow_execution rpc method.""" return await self._client._rpc_call( @@ -1434,8 +1435,8 @@ async def start_batch_operation( self, req: temporalio.api.workflowservice.v1.StartBatchOperationRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.StartBatchOperationResponse: """Invokes the WorkflowService.start_batch_operation rpc method.""" return await self._client._rpc_call( @@ -1452,8 +1453,8 @@ async def start_workflow_execution( self, req: temporalio.api.workflowservice.v1.StartWorkflowExecutionRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.StartWorkflowExecutionResponse: """Invokes the WorkflowService.start_workflow_execution rpc method.""" return await self._client._rpc_call( @@ -1470,8 +1471,8 @@ async def stop_batch_operation( self, req: temporalio.api.workflowservice.v1.StopBatchOperationRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.StopBatchOperationResponse: """Invokes the WorkflowService.stop_batch_operation rpc method.""" return await self._client._rpc_call( @@ -1488,8 +1489,8 @@ async def terminate_workflow_execution( self, req: temporalio.api.workflowservice.v1.TerminateWorkflowExecutionRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.TerminateWorkflowExecutionResponse: """Invokes the WorkflowService.terminate_workflow_execution rpc method.""" return await self._client._rpc_call( @@ -1506,8 +1507,8 @@ async def trigger_workflow_rule( self, req: temporalio.api.workflowservice.v1.TriggerWorkflowRuleRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.TriggerWorkflowRuleResponse: """Invokes the WorkflowService.trigger_workflow_rule rpc method.""" return await self._client._rpc_call( @@ -1524,8 +1525,8 @@ async def unpause_activity( self, req: temporalio.api.workflowservice.v1.UnpauseActivityRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.UnpauseActivityResponse: """Invokes the WorkflowService.unpause_activity rpc method.""" return await self._client._rpc_call( @@ -1542,8 +1543,8 @@ async def update_activity_options( self, req: temporalio.api.workflowservice.v1.UpdateActivityOptionsRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.UpdateActivityOptionsResponse: """Invokes the WorkflowService.update_activity_options rpc method.""" return await self._client._rpc_call( @@ -1560,8 +1561,8 @@ async def update_namespace( self, req: temporalio.api.workflowservice.v1.UpdateNamespaceRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.UpdateNamespaceResponse: """Invokes the WorkflowService.update_namespace rpc method.""" return await self._client._rpc_call( @@ -1578,8 +1579,8 @@ async def update_schedule( self, req: temporalio.api.workflowservice.v1.UpdateScheduleRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.UpdateScheduleResponse: """Invokes the WorkflowService.update_schedule rpc method.""" return await self._client._rpc_call( @@ -1596,8 +1597,8 @@ async def update_task_queue_config( self, req: temporalio.api.workflowservice.v1.UpdateTaskQueueConfigRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.UpdateTaskQueueConfigResponse: """Invokes the WorkflowService.update_task_queue_config rpc method.""" return await self._client._rpc_call( @@ -1614,8 +1615,8 @@ async def update_worker_build_id_compatibility( self, req: temporalio.api.workflowservice.v1.UpdateWorkerBuildIdCompatibilityRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.UpdateWorkerBuildIdCompatibilityResponse: """Invokes the WorkflowService.update_worker_build_id_compatibility rpc method.""" return await self._client._rpc_call( @@ -1632,8 +1633,8 @@ async def update_worker_config( self, req: temporalio.api.workflowservice.v1.UpdateWorkerConfigRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.UpdateWorkerConfigResponse: """Invokes the WorkflowService.update_worker_config rpc method.""" return await self._client._rpc_call( @@ -1650,8 +1651,8 @@ async def update_worker_deployment_version_metadata( self, req: temporalio.api.workflowservice.v1.UpdateWorkerDeploymentVersionMetadataRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> ( temporalio.api.workflowservice.v1.UpdateWorkerDeploymentVersionMetadataResponse ): @@ -1670,8 +1671,8 @@ async def update_worker_versioning_rules( self, req: temporalio.api.workflowservice.v1.UpdateWorkerVersioningRulesRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.UpdateWorkerVersioningRulesResponse: """Invokes the WorkflowService.update_worker_versioning_rules rpc method.""" return await self._client._rpc_call( @@ -1688,8 +1689,8 @@ async def update_workflow_execution( self, req: temporalio.api.workflowservice.v1.UpdateWorkflowExecutionRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.UpdateWorkflowExecutionResponse: """Invokes the WorkflowService.update_workflow_execution rpc method.""" return await self._client._rpc_call( @@ -1706,8 +1707,8 @@ async def update_workflow_execution_options( self, req: temporalio.api.workflowservice.v1.UpdateWorkflowExecutionOptionsRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.UpdateWorkflowExecutionOptionsResponse: """Invokes the WorkflowService.update_workflow_execution_options rpc method.""" return await self._client._rpc_call( @@ -1733,8 +1734,8 @@ async def add_or_update_remote_cluster( self, req: temporalio.api.operatorservice.v1.AddOrUpdateRemoteClusterRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.operatorservice.v1.AddOrUpdateRemoteClusterResponse: """Invokes the OperatorService.add_or_update_remote_cluster rpc method.""" return await self._client._rpc_call( @@ -1751,8 +1752,8 @@ async def add_search_attributes( self, req: temporalio.api.operatorservice.v1.AddSearchAttributesRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.operatorservice.v1.AddSearchAttributesResponse: """Invokes the OperatorService.add_search_attributes rpc method.""" return await self._client._rpc_call( @@ -1769,8 +1770,8 @@ async def create_nexus_endpoint( self, req: temporalio.api.operatorservice.v1.CreateNexusEndpointRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.operatorservice.v1.CreateNexusEndpointResponse: """Invokes the OperatorService.create_nexus_endpoint rpc method.""" return await self._client._rpc_call( @@ -1787,8 +1788,8 @@ async def delete_namespace( self, req: temporalio.api.operatorservice.v1.DeleteNamespaceRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.operatorservice.v1.DeleteNamespaceResponse: """Invokes the OperatorService.delete_namespace rpc method.""" return await self._client._rpc_call( @@ -1805,8 +1806,8 @@ async def delete_nexus_endpoint( self, req: temporalio.api.operatorservice.v1.DeleteNexusEndpointRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.operatorservice.v1.DeleteNexusEndpointResponse: """Invokes the OperatorService.delete_nexus_endpoint rpc method.""" return await self._client._rpc_call( @@ -1823,8 +1824,8 @@ async def get_nexus_endpoint( self, req: temporalio.api.operatorservice.v1.GetNexusEndpointRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.operatorservice.v1.GetNexusEndpointResponse: """Invokes the OperatorService.get_nexus_endpoint rpc method.""" return await self._client._rpc_call( @@ -1841,8 +1842,8 @@ async def list_clusters( self, req: temporalio.api.operatorservice.v1.ListClustersRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.operatorservice.v1.ListClustersResponse: """Invokes the OperatorService.list_clusters rpc method.""" return await self._client._rpc_call( @@ -1859,8 +1860,8 @@ async def list_nexus_endpoints( self, req: temporalio.api.operatorservice.v1.ListNexusEndpointsRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.operatorservice.v1.ListNexusEndpointsResponse: """Invokes the OperatorService.list_nexus_endpoints rpc method.""" return await self._client._rpc_call( @@ -1877,8 +1878,8 @@ async def list_search_attributes( self, req: temporalio.api.operatorservice.v1.ListSearchAttributesRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.operatorservice.v1.ListSearchAttributesResponse: """Invokes the OperatorService.list_search_attributes rpc method.""" return await self._client._rpc_call( @@ -1895,8 +1896,8 @@ async def remove_remote_cluster( self, req: temporalio.api.operatorservice.v1.RemoveRemoteClusterRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.operatorservice.v1.RemoveRemoteClusterResponse: """Invokes the OperatorService.remove_remote_cluster rpc method.""" return await self._client._rpc_call( @@ -1913,8 +1914,8 @@ async def remove_search_attributes( self, req: temporalio.api.operatorservice.v1.RemoveSearchAttributesRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.operatorservice.v1.RemoveSearchAttributesResponse: """Invokes the OperatorService.remove_search_attributes rpc method.""" return await self._client._rpc_call( @@ -1931,8 +1932,8 @@ async def update_nexus_endpoint( self, req: temporalio.api.operatorservice.v1.UpdateNexusEndpointRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.operatorservice.v1.UpdateNexusEndpointResponse: """Invokes the OperatorService.update_nexus_endpoint rpc method.""" return await self._client._rpc_call( @@ -1958,8 +1959,8 @@ async def add_namespace_region( self, req: temporalio.api.cloud.cloudservice.v1.AddNamespaceRegionRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.AddNamespaceRegionResponse: """Invokes the CloudService.add_namespace_region rpc method.""" return await self._client._rpc_call( @@ -1976,8 +1977,8 @@ async def add_user_group_member( self, req: temporalio.api.cloud.cloudservice.v1.AddUserGroupMemberRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.AddUserGroupMemberResponse: """Invokes the CloudService.add_user_group_member rpc method.""" return await self._client._rpc_call( @@ -1994,8 +1995,8 @@ async def create_api_key( self, req: temporalio.api.cloud.cloudservice.v1.CreateApiKeyRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.CreateApiKeyResponse: """Invokes the CloudService.create_api_key rpc method.""" return await self._client._rpc_call( @@ -2012,8 +2013,8 @@ async def create_connectivity_rule( self, req: temporalio.api.cloud.cloudservice.v1.CreateConnectivityRuleRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.CreateConnectivityRuleResponse: """Invokes the CloudService.create_connectivity_rule rpc method.""" return await self._client._rpc_call( @@ -2030,8 +2031,8 @@ async def create_namespace( self, req: temporalio.api.cloud.cloudservice.v1.CreateNamespaceRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.CreateNamespaceResponse: """Invokes the CloudService.create_namespace rpc method.""" return await self._client._rpc_call( @@ -2048,8 +2049,8 @@ async def create_namespace_export_sink( self, req: temporalio.api.cloud.cloudservice.v1.CreateNamespaceExportSinkRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.CreateNamespaceExportSinkResponse: """Invokes the CloudService.create_namespace_export_sink rpc method.""" return await self._client._rpc_call( @@ -2066,8 +2067,8 @@ async def create_nexus_endpoint( self, req: temporalio.api.cloud.cloudservice.v1.CreateNexusEndpointRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.CreateNexusEndpointResponse: """Invokes the CloudService.create_nexus_endpoint rpc method.""" return await self._client._rpc_call( @@ -2084,8 +2085,8 @@ async def create_service_account( self, req: temporalio.api.cloud.cloudservice.v1.CreateServiceAccountRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.CreateServiceAccountResponse: """Invokes the CloudService.create_service_account rpc method.""" return await self._client._rpc_call( @@ -2102,8 +2103,8 @@ async def create_user( self, req: temporalio.api.cloud.cloudservice.v1.CreateUserRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.CreateUserResponse: """Invokes the CloudService.create_user rpc method.""" return await self._client._rpc_call( @@ -2120,8 +2121,8 @@ async def create_user_group( self, req: temporalio.api.cloud.cloudservice.v1.CreateUserGroupRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.CreateUserGroupResponse: """Invokes the CloudService.create_user_group rpc method.""" return await self._client._rpc_call( @@ -2138,8 +2139,8 @@ async def delete_api_key( self, req: temporalio.api.cloud.cloudservice.v1.DeleteApiKeyRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.DeleteApiKeyResponse: """Invokes the CloudService.delete_api_key rpc method.""" return await self._client._rpc_call( @@ -2156,8 +2157,8 @@ async def delete_connectivity_rule( self, req: temporalio.api.cloud.cloudservice.v1.DeleteConnectivityRuleRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.DeleteConnectivityRuleResponse: """Invokes the CloudService.delete_connectivity_rule rpc method.""" return await self._client._rpc_call( @@ -2174,8 +2175,8 @@ async def delete_namespace( self, req: temporalio.api.cloud.cloudservice.v1.DeleteNamespaceRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.DeleteNamespaceResponse: """Invokes the CloudService.delete_namespace rpc method.""" return await self._client._rpc_call( @@ -2192,8 +2193,8 @@ async def delete_namespace_export_sink( self, req: temporalio.api.cloud.cloudservice.v1.DeleteNamespaceExportSinkRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.DeleteNamespaceExportSinkResponse: """Invokes the CloudService.delete_namespace_export_sink rpc method.""" return await self._client._rpc_call( @@ -2210,8 +2211,8 @@ async def delete_namespace_region( self, req: temporalio.api.cloud.cloudservice.v1.DeleteNamespaceRegionRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.DeleteNamespaceRegionResponse: """Invokes the CloudService.delete_namespace_region rpc method.""" return await self._client._rpc_call( @@ -2228,8 +2229,8 @@ async def delete_nexus_endpoint( self, req: temporalio.api.cloud.cloudservice.v1.DeleteNexusEndpointRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.DeleteNexusEndpointResponse: """Invokes the CloudService.delete_nexus_endpoint rpc method.""" return await self._client._rpc_call( @@ -2246,8 +2247,8 @@ async def delete_service_account( self, req: temporalio.api.cloud.cloudservice.v1.DeleteServiceAccountRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.DeleteServiceAccountResponse: """Invokes the CloudService.delete_service_account rpc method.""" return await self._client._rpc_call( @@ -2264,8 +2265,8 @@ async def delete_user( self, req: temporalio.api.cloud.cloudservice.v1.DeleteUserRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.DeleteUserResponse: """Invokes the CloudService.delete_user rpc method.""" return await self._client._rpc_call( @@ -2282,8 +2283,8 @@ async def delete_user_group( self, req: temporalio.api.cloud.cloudservice.v1.DeleteUserGroupRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.DeleteUserGroupResponse: """Invokes the CloudService.delete_user_group rpc method.""" return await self._client._rpc_call( @@ -2300,8 +2301,8 @@ async def failover_namespace_region( self, req: temporalio.api.cloud.cloudservice.v1.FailoverNamespaceRegionRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.FailoverNamespaceRegionResponse: """Invokes the CloudService.failover_namespace_region rpc method.""" return await self._client._rpc_call( @@ -2318,8 +2319,8 @@ async def get_account( self, req: temporalio.api.cloud.cloudservice.v1.GetAccountRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.GetAccountResponse: """Invokes the CloudService.get_account rpc method.""" return await self._client._rpc_call( @@ -2336,8 +2337,8 @@ async def get_api_key( self, req: temporalio.api.cloud.cloudservice.v1.GetApiKeyRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.GetApiKeyResponse: """Invokes the CloudService.get_api_key rpc method.""" return await self._client._rpc_call( @@ -2354,8 +2355,8 @@ async def get_api_keys( self, req: temporalio.api.cloud.cloudservice.v1.GetApiKeysRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.GetApiKeysResponse: """Invokes the CloudService.get_api_keys rpc method.""" return await self._client._rpc_call( @@ -2372,8 +2373,8 @@ async def get_async_operation( self, req: temporalio.api.cloud.cloudservice.v1.GetAsyncOperationRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.GetAsyncOperationResponse: """Invokes the CloudService.get_async_operation rpc method.""" return await self._client._rpc_call( @@ -2390,8 +2391,8 @@ async def get_connectivity_rule( self, req: temporalio.api.cloud.cloudservice.v1.GetConnectivityRuleRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.GetConnectivityRuleResponse: """Invokes the CloudService.get_connectivity_rule rpc method.""" return await self._client._rpc_call( @@ -2408,8 +2409,8 @@ async def get_connectivity_rules( self, req: temporalio.api.cloud.cloudservice.v1.GetConnectivityRulesRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.GetConnectivityRulesResponse: """Invokes the CloudService.get_connectivity_rules rpc method.""" return await self._client._rpc_call( @@ -2426,8 +2427,8 @@ async def get_namespace( self, req: temporalio.api.cloud.cloudservice.v1.GetNamespaceRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.GetNamespaceResponse: """Invokes the CloudService.get_namespace rpc method.""" return await self._client._rpc_call( @@ -2444,8 +2445,8 @@ async def get_namespace_export_sink( self, req: temporalio.api.cloud.cloudservice.v1.GetNamespaceExportSinkRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.GetNamespaceExportSinkResponse: """Invokes the CloudService.get_namespace_export_sink rpc method.""" return await self._client._rpc_call( @@ -2462,8 +2463,8 @@ async def get_namespace_export_sinks( self, req: temporalio.api.cloud.cloudservice.v1.GetNamespaceExportSinksRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.GetNamespaceExportSinksResponse: """Invokes the CloudService.get_namespace_export_sinks rpc method.""" return await self._client._rpc_call( @@ -2480,8 +2481,8 @@ async def get_namespaces( self, req: temporalio.api.cloud.cloudservice.v1.GetNamespacesRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.GetNamespacesResponse: """Invokes the CloudService.get_namespaces rpc method.""" return await self._client._rpc_call( @@ -2498,8 +2499,8 @@ async def get_nexus_endpoint( self, req: temporalio.api.cloud.cloudservice.v1.GetNexusEndpointRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.GetNexusEndpointResponse: """Invokes the CloudService.get_nexus_endpoint rpc method.""" return await self._client._rpc_call( @@ -2516,8 +2517,8 @@ async def get_nexus_endpoints( self, req: temporalio.api.cloud.cloudservice.v1.GetNexusEndpointsRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.GetNexusEndpointsResponse: """Invokes the CloudService.get_nexus_endpoints rpc method.""" return await self._client._rpc_call( @@ -2534,8 +2535,8 @@ async def get_region( self, req: temporalio.api.cloud.cloudservice.v1.GetRegionRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.GetRegionResponse: """Invokes the CloudService.get_region rpc method.""" return await self._client._rpc_call( @@ -2552,8 +2553,8 @@ async def get_regions( self, req: temporalio.api.cloud.cloudservice.v1.GetRegionsRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.GetRegionsResponse: """Invokes the CloudService.get_regions rpc method.""" return await self._client._rpc_call( @@ -2570,8 +2571,8 @@ async def get_service_account( self, req: temporalio.api.cloud.cloudservice.v1.GetServiceAccountRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.GetServiceAccountResponse: """Invokes the CloudService.get_service_account rpc method.""" return await self._client._rpc_call( @@ -2588,8 +2589,8 @@ async def get_service_accounts( self, req: temporalio.api.cloud.cloudservice.v1.GetServiceAccountsRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.GetServiceAccountsResponse: """Invokes the CloudService.get_service_accounts rpc method.""" return await self._client._rpc_call( @@ -2606,8 +2607,8 @@ async def get_usage( self, req: temporalio.api.cloud.cloudservice.v1.GetUsageRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.GetUsageResponse: """Invokes the CloudService.get_usage rpc method.""" return await self._client._rpc_call( @@ -2624,8 +2625,8 @@ async def get_user( self, req: temporalio.api.cloud.cloudservice.v1.GetUserRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.GetUserResponse: """Invokes the CloudService.get_user rpc method.""" return await self._client._rpc_call( @@ -2642,8 +2643,8 @@ async def get_user_group( self, req: temporalio.api.cloud.cloudservice.v1.GetUserGroupRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.GetUserGroupResponse: """Invokes the CloudService.get_user_group rpc method.""" return await self._client._rpc_call( @@ -2660,8 +2661,8 @@ async def get_user_group_members( self, req: temporalio.api.cloud.cloudservice.v1.GetUserGroupMembersRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.GetUserGroupMembersResponse: """Invokes the CloudService.get_user_group_members rpc method.""" return await self._client._rpc_call( @@ -2678,8 +2679,8 @@ async def get_user_groups( self, req: temporalio.api.cloud.cloudservice.v1.GetUserGroupsRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.GetUserGroupsResponse: """Invokes the CloudService.get_user_groups rpc method.""" return await self._client._rpc_call( @@ -2696,8 +2697,8 @@ async def get_users( self, req: temporalio.api.cloud.cloudservice.v1.GetUsersRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.GetUsersResponse: """Invokes the CloudService.get_users rpc method.""" return await self._client._rpc_call( @@ -2714,8 +2715,8 @@ async def remove_user_group_member( self, req: temporalio.api.cloud.cloudservice.v1.RemoveUserGroupMemberRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.RemoveUserGroupMemberResponse: """Invokes the CloudService.remove_user_group_member rpc method.""" return await self._client._rpc_call( @@ -2732,8 +2733,8 @@ async def rename_custom_search_attribute( self, req: temporalio.api.cloud.cloudservice.v1.RenameCustomSearchAttributeRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.RenameCustomSearchAttributeResponse: """Invokes the CloudService.rename_custom_search_attribute rpc method.""" return await self._client._rpc_call( @@ -2750,8 +2751,8 @@ async def set_service_account_namespace_access( self, req: temporalio.api.cloud.cloudservice.v1.SetServiceAccountNamespaceAccessRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.SetServiceAccountNamespaceAccessResponse: """Invokes the CloudService.set_service_account_namespace_access rpc method.""" return await self._client._rpc_call( @@ -2768,8 +2769,8 @@ async def set_user_group_namespace_access( self, req: temporalio.api.cloud.cloudservice.v1.SetUserGroupNamespaceAccessRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.SetUserGroupNamespaceAccessResponse: """Invokes the CloudService.set_user_group_namespace_access rpc method.""" return await self._client._rpc_call( @@ -2786,8 +2787,8 @@ async def set_user_namespace_access( self, req: temporalio.api.cloud.cloudservice.v1.SetUserNamespaceAccessRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.SetUserNamespaceAccessResponse: """Invokes the CloudService.set_user_namespace_access rpc method.""" return await self._client._rpc_call( @@ -2804,8 +2805,8 @@ async def update_account( self, req: temporalio.api.cloud.cloudservice.v1.UpdateAccountRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.UpdateAccountResponse: """Invokes the CloudService.update_account rpc method.""" return await self._client._rpc_call( @@ -2822,8 +2823,8 @@ async def update_api_key( self, req: temporalio.api.cloud.cloudservice.v1.UpdateApiKeyRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.UpdateApiKeyResponse: """Invokes the CloudService.update_api_key rpc method.""" return await self._client._rpc_call( @@ -2840,8 +2841,8 @@ async def update_namespace( self, req: temporalio.api.cloud.cloudservice.v1.UpdateNamespaceRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.UpdateNamespaceResponse: """Invokes the CloudService.update_namespace rpc method.""" return await self._client._rpc_call( @@ -2858,8 +2859,8 @@ async def update_namespace_export_sink( self, req: temporalio.api.cloud.cloudservice.v1.UpdateNamespaceExportSinkRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.UpdateNamespaceExportSinkResponse: """Invokes the CloudService.update_namespace_export_sink rpc method.""" return await self._client._rpc_call( @@ -2876,8 +2877,8 @@ async def update_namespace_tags( self, req: temporalio.api.cloud.cloudservice.v1.UpdateNamespaceTagsRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.UpdateNamespaceTagsResponse: """Invokes the CloudService.update_namespace_tags rpc method.""" return await self._client._rpc_call( @@ -2894,8 +2895,8 @@ async def update_nexus_endpoint( self, req: temporalio.api.cloud.cloudservice.v1.UpdateNexusEndpointRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.UpdateNexusEndpointResponse: """Invokes the CloudService.update_nexus_endpoint rpc method.""" return await self._client._rpc_call( @@ -2912,8 +2913,8 @@ async def update_service_account( self, req: temporalio.api.cloud.cloudservice.v1.UpdateServiceAccountRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.UpdateServiceAccountResponse: """Invokes the CloudService.update_service_account rpc method.""" return await self._client._rpc_call( @@ -2930,8 +2931,8 @@ async def update_user( self, req: temporalio.api.cloud.cloudservice.v1.UpdateUserRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.UpdateUserResponse: """Invokes the CloudService.update_user rpc method.""" return await self._client._rpc_call( @@ -2948,8 +2949,8 @@ async def update_user_group( self, req: temporalio.api.cloud.cloudservice.v1.UpdateUserGroupRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.UpdateUserGroupResponse: """Invokes the CloudService.update_user_group rpc method.""" return await self._client._rpc_call( @@ -2966,8 +2967,8 @@ async def validate_account_audit_log_sink( self, req: temporalio.api.cloud.cloudservice.v1.ValidateAccountAuditLogSinkRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.ValidateAccountAuditLogSinkResponse: """Invokes the CloudService.validate_account_audit_log_sink rpc method.""" return await self._client._rpc_call( @@ -2984,8 +2985,8 @@ async def validate_namespace_export_sink( self, req: temporalio.api.cloud.cloudservice.v1.ValidateNamespaceExportSinkRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.cloud.cloudservice.v1.ValidateNamespaceExportSinkResponse: """Invokes the CloudService.validate_namespace_export_sink rpc method.""" return await self._client._rpc_call( @@ -3011,8 +3012,8 @@ async def get_current_time( self, req: google.protobuf.empty_pb2.Empty, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.testservice.v1.GetCurrentTimeResponse: """Invokes the TestService.get_current_time rpc method.""" return await self._client._rpc_call( @@ -3029,8 +3030,8 @@ async def lock_time_skipping( self, req: temporalio.api.testservice.v1.LockTimeSkippingRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.testservice.v1.LockTimeSkippingResponse: """Invokes the TestService.lock_time_skipping rpc method.""" return await self._client._rpc_call( @@ -3047,8 +3048,8 @@ async def sleep( self, req: temporalio.api.testservice.v1.SleepRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.testservice.v1.SleepResponse: """Invokes the TestService.sleep rpc method.""" return await self._client._rpc_call( @@ -3065,8 +3066,8 @@ async def sleep_until( self, req: temporalio.api.testservice.v1.SleepUntilRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.testservice.v1.SleepResponse: """Invokes the TestService.sleep_until rpc method.""" return await self._client._rpc_call( @@ -3083,8 +3084,8 @@ async def unlock_time_skipping( self, req: temporalio.api.testservice.v1.UnlockTimeSkippingRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.testservice.v1.UnlockTimeSkippingResponse: """Invokes the TestService.unlock_time_skipping rpc method.""" return await self._client._rpc_call( @@ -3101,8 +3102,8 @@ async def unlock_time_skipping_with_sleep( self, req: temporalio.api.testservice.v1.SleepRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.testservice.v1.SleepResponse: """Invokes the TestService.unlock_time_skipping_with_sleep rpc method.""" return await self._client._rpc_call( @@ -3128,8 +3129,8 @@ async def check( self, req: temporalio.bridge.proto.health.v1.HealthCheckRequest, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.bridge.proto.health.v1.HealthCheckResponse: """Invokes the HealthService.check rpc method.""" return await self._client._rpc_call( diff --git a/temporalio/bridge/testing.py b/temporalio/bridge/testing.py index 667ec13ea..8db2edc2a 100644 --- a/temporalio/bridge/testing.py +++ b/temporalio/bridge/testing.py @@ -5,8 +5,9 @@ from __future__ import annotations +from collections.abc import Sequence from dataclasses import dataclass -from typing import Optional, Sequence +from typing import Optional import temporalio.bridge.runtime import temporalio.bridge.temporal_sdk_bridge @@ -16,16 +17,16 @@ class DevServerConfig: """Python representation of the Rust struct for configuring dev server.""" - existing_path: Optional[str] + existing_path: str | None sdk_name: str sdk_version: str download_version: str - download_dest_dir: Optional[str] - download_ttl_ms: Optional[int] + download_dest_dir: str | None + download_ttl_ms: int | None namespace: str ip: str - port: Optional[int] - database_filename: Optional[str] + port: int | None + database_filename: str | None ui: bool log_format: str log_level: str @@ -36,13 +37,13 @@ class DevServerConfig: class TestServerConfig: """Python representation of the Rust struct for configuring test server.""" - existing_path: Optional[str] + existing_path: str | None sdk_name: str sdk_version: str download_version: str - download_dest_dir: Optional[str] - download_ttl_ms: Optional[int] - port: Optional[int] + download_dest_dir: str | None + download_ttl_ms: int | None + port: int | None extra_args: Sequence[str] diff --git a/temporalio/bridge/worker.py b/temporalio/bridge/worker.py index 0332d1099..b8488bade 100644 --- a/temporalio/bridge/worker.py +++ b/temporalio/bridge/worker.py @@ -5,21 +5,17 @@ from __future__ import annotations +from collections.abc import Awaitable, Callable, MutableSequence, Sequence from dataclasses import dataclass from typing import ( - Awaitable, - Callable, List, - MutableSequence, Optional, - Sequence, Set, Tuple, + TypeAlias, Union, ) -from typing_extensions import TypeAlias - import temporalio.api.common.v1 import temporalio.api.history.v1 import temporalio.bridge.client @@ -48,7 +44,7 @@ class WorkerConfig: namespace: str task_queue: str versioning_strategy: WorkerVersioningStrategy - identity_override: Optional[str] + identity_override: str | None max_cached_workflows: int tuner: TunerHolder workflow_task_poller_behavior: PollerBehavior @@ -59,11 +55,11 @@ class WorkerConfig: sticky_queue_schedule_to_start_timeout_millis: int max_heartbeat_throttle_interval_millis: int default_heartbeat_throttle_interval_millis: int - max_activities_per_second: Optional[float] - max_task_queue_activities_per_second: Optional[float] + max_activities_per_second: float | None + max_task_queue_activities_per_second: float | None graceful_shutdown_period_millis: int nondeterminism_as_workflow_fail: bool - nondeterminism_as_workflow_fail_for_types: Set[str] + nondeterminism_as_workflow_fail_for_types: set[str] nexus_task_poller_behavior: PollerBehavior plugins: Sequence[str] @@ -197,7 +193,7 @@ def create(client: temporalio.bridge.client.Client, config: WorkerConfig) -> Wor def for_replay( runtime: temporalio.bridge.runtime.Runtime, config: WorkerConfig, - ) -> Tuple[Worker, temporalio.bridge.temporal_sdk_bridge.HistoryPusher]: + ) -> tuple[Worker, temporalio.bridge.temporal_sdk_bridge.HistoryPusher]: """Create a bridge replay worker.""" [ replay_worker, @@ -290,7 +286,7 @@ async def finalize_shutdown(self) -> None: class _Visitor(VisitorFunctions): - def __init__(self, f: Callable[[Sequence[Payload]], Awaitable[List[Payload]]]): + def __init__(self, f: Callable[[Sequence[Payload]], Awaitable[list[Payload]]]): self._f = f async def visit_payload(self, payload: Payload) -> None: diff --git a/temporalio/client.py b/temporalio/client.py index def892365..db912e122 100644 --- a/temporalio/client.py +++ b/temporalio/client.py @@ -14,21 +14,24 @@ import warnings from abc import ABC, abstractmethod from asyncio import Future +from collections.abc import ( + AsyncIterator, + Awaitable, + Callable, + Iterable, + Mapping, + Sequence, +) from dataclasses import dataclass from datetime import datetime, timedelta, timezone from enum import Enum, IntEnum from typing import ( Any, - AsyncIterator, - Awaitable, - Callable, + Concatenate, Dict, FrozenSet, Generic, - Iterable, - Mapping, Optional, - Sequence, Text, Tuple, Type, @@ -41,7 +44,7 @@ import google.protobuf.json_format import google.protobuf.timestamp_pb2 from google.protobuf.internal.containers import MessageMap -from typing_extensions import Concatenate, Required, Self, TypedDict +from typing_extensions import Required, Self, TypedDict import temporalio.api.common.v1 import temporalio.api.enums.v1 @@ -118,21 +121,20 @@ async def connect( target_host: str, *, namespace: str = "default", - api_key: Optional[str] = None, + api_key: str | None = None, data_converter: temporalio.converter.DataConverter = temporalio.converter.DataConverter.default, plugins: Sequence[Plugin] = [], interceptors: Sequence[Interceptor] = [], - default_workflow_query_reject_condition: Optional[ - temporalio.common.QueryRejectCondition - ] = None, - tls: Union[bool, TLSConfig, None] = None, - retry_config: Optional[RetryConfig] = None, - keep_alive_config: Optional[KeepAliveConfig] = KeepAliveConfig.default, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - identity: Optional[str] = None, + default_workflow_query_reject_condition: None + | (temporalio.common.QueryRejectCondition) = None, + tls: bool | TLSConfig | None = None, + retry_config: RetryConfig | None = None, + keep_alive_config: KeepAliveConfig | None = KeepAliveConfig.default, + rpc_metadata: Mapping[str, str | bytes] = {}, + identity: str | None = None, lazy: bool = False, - runtime: Optional[temporalio.runtime.Runtime] = None, - http_connect_proxy_config: Optional[HttpConnectProxyConfig] = None, + runtime: temporalio.runtime.Runtime | None = None, + http_connect_proxy_config: HttpConnectProxyConfig | None = None, header_codec_behavior: HeaderCodecBehavior = HeaderCodecBehavior.NO_CODEC, ) -> Self: """Connect to a Temporal server. @@ -230,9 +232,8 @@ def __init__( data_converter: temporalio.converter.DataConverter = temporalio.converter.DataConverter.default, plugins: Sequence[Plugin] = [], interceptors: Sequence[Interceptor] = [], - default_workflow_query_reject_condition: Optional[ - temporalio.common.QueryRejectCondition - ] = None, + default_workflow_query_reject_condition: None + | (temporalio.common.QueryRejectCondition) = None, header_codec_behavior: HeaderCodecBehavior = HeaderCodecBehavior.NO_CODEC, ): """Create a Temporal client from a service client. @@ -313,7 +314,7 @@ def data_converter(self) -> temporalio.converter.DataConverter: return self._config["data_converter"] @property - def rpc_metadata(self) -> Mapping[str, Union[str, bytes]]: + def rpc_metadata(self) -> Mapping[str, str | bytes]: """Headers for every call made by this client. Do not use mutate this mapping. Rather, set this property with an @@ -322,7 +323,7 @@ def rpc_metadata(self) -> Mapping[str, Union[str, bytes]]: return self.service_client.config.rpc_metadata @rpc_metadata.setter - def rpc_metadata(self, value: Mapping[str, Union[str, bytes]]) -> None: + def rpc_metadata(self, value: Mapping[str, str | bytes]) -> None: """Update the headers for this client. Do not mutate this mapping after set. Rather, set an entirely new @@ -342,12 +343,12 @@ def rpc_metadata(self, value: Mapping[str, Union[str, bytes]]) -> None: self.service_client.config.rpc_metadata = value @property - def api_key(self) -> Optional[str]: + def api_key(self) -> str | None: """API key for every call made by this client.""" return self.service_client.config.api_key @api_key.setter - def api_key(self, value: Optional[str]) -> None: + def api_key(self, value: str | None) -> None: """Update the API key for this client. This is only set if RPCmetadata doesn't already have an "authorization" @@ -365,30 +366,28 @@ async def start_workflow( *, id: str, task_queue: str, - execution_timeout: Optional[timedelta] = None, - run_timeout: Optional[timedelta] = None, - task_timeout: Optional[timedelta] = None, + execution_timeout: timedelta | None = None, + run_timeout: timedelta | None = None, + task_timeout: timedelta | None = None, id_reuse_policy: temporalio.common.WorkflowIDReusePolicy = temporalio.common.WorkflowIDReusePolicy.ALLOW_DUPLICATE, id_conflict_policy: temporalio.common.WorkflowIDConflictPolicy = temporalio.common.WorkflowIDConflictPolicy.UNSPECIFIED, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cron_schedule: str = "", - memo: Optional[Mapping[str, Any]] = None, - search_attributes: Optional[ - Union[ - temporalio.common.TypedSearchAttributes, - temporalio.common.SearchAttributes, - ] - ] = None, - static_summary: Optional[str] = None, - static_details: Optional[str] = None, - start_delay: Optional[timedelta] = None, - start_signal: Optional[str] = None, + memo: Mapping[str, Any] | None = None, + search_attributes: None + | ( + temporalio.common.TypedSearchAttributes | temporalio.common.SearchAttributes + ) = None, + static_summary: str | None = None, + static_details: str | None = None, + start_delay: timedelta | None = None, + start_signal: str | None = None, start_signal_args: Sequence[Any] = [], - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, request_eager_start: bool = False, priority: temporalio.common.Priority = temporalio.common.Priority.default, - versioning_override: Optional[temporalio.common.VersioningOverride] = None, + versioning_override: temporalio.common.VersioningOverride | None = None, ) -> WorkflowHandle[SelfType, ReturnType]: ... # Overload for single-param workflow @@ -400,30 +399,28 @@ async def start_workflow( *, id: str, task_queue: str, - execution_timeout: Optional[timedelta] = None, - run_timeout: Optional[timedelta] = None, - task_timeout: Optional[timedelta] = None, + execution_timeout: timedelta | None = None, + run_timeout: timedelta | None = None, + task_timeout: timedelta | None = None, id_reuse_policy: temporalio.common.WorkflowIDReusePolicy = temporalio.common.WorkflowIDReusePolicy.ALLOW_DUPLICATE, id_conflict_policy: temporalio.common.WorkflowIDConflictPolicy = temporalio.common.WorkflowIDConflictPolicy.UNSPECIFIED, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cron_schedule: str = "", - memo: Optional[Mapping[str, Any]] = None, - search_attributes: Optional[ - Union[ - temporalio.common.TypedSearchAttributes, - temporalio.common.SearchAttributes, - ] - ] = None, - static_summary: Optional[str] = None, - static_details: Optional[str] = None, - start_delay: Optional[timedelta] = None, - start_signal: Optional[str] = None, + memo: Mapping[str, Any] | None = None, + search_attributes: None + | ( + temporalio.common.TypedSearchAttributes | temporalio.common.SearchAttributes + ) = None, + static_summary: str | None = None, + static_details: str | None = None, + start_delay: timedelta | None = None, + start_signal: str | None = None, start_signal_args: Sequence[Any] = [], - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, request_eager_start: bool = False, priority: temporalio.common.Priority = temporalio.common.Priority.default, - versioning_override: Optional[temporalio.common.VersioningOverride] = None, + versioning_override: temporalio.common.VersioningOverride | None = None, ) -> WorkflowHandle[SelfType, ReturnType]: ... # Overload for multi-param workflow @@ -437,30 +434,28 @@ async def start_workflow( args: Sequence[Any], id: str, task_queue: str, - execution_timeout: Optional[timedelta] = None, - run_timeout: Optional[timedelta] = None, - task_timeout: Optional[timedelta] = None, + execution_timeout: timedelta | None = None, + run_timeout: timedelta | None = None, + task_timeout: timedelta | None = None, id_reuse_policy: temporalio.common.WorkflowIDReusePolicy = temporalio.common.WorkflowIDReusePolicy.ALLOW_DUPLICATE, id_conflict_policy: temporalio.common.WorkflowIDConflictPolicy = temporalio.common.WorkflowIDConflictPolicy.UNSPECIFIED, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cron_schedule: str = "", - memo: Optional[Mapping[str, Any]] = None, - search_attributes: Optional[ - Union[ - temporalio.common.TypedSearchAttributes, - temporalio.common.SearchAttributes, - ] - ] = None, - static_summary: Optional[str] = None, - static_details: Optional[str] = None, - start_delay: Optional[timedelta] = None, - start_signal: Optional[str] = None, + memo: Mapping[str, Any] | None = None, + search_attributes: None + | ( + temporalio.common.TypedSearchAttributes | temporalio.common.SearchAttributes + ) = None, + static_summary: str | None = None, + static_details: str | None = None, + start_delay: timedelta | None = None, + start_signal: str | None = None, start_signal_args: Sequence[Any] = [], - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, request_eager_start: bool = False, priority: temporalio.common.Priority = temporalio.common.Priority.default, - versioning_override: Optional[temporalio.common.VersioningOverride] = None, + versioning_override: temporalio.common.VersioningOverride | None = None, ) -> WorkflowHandle[SelfType, ReturnType]: ... # Overload for string-name workflow @@ -473,66 +468,62 @@ async def start_workflow( args: Sequence[Any] = [], id: str, task_queue: str, - result_type: Optional[type] = None, - execution_timeout: Optional[timedelta] = None, - run_timeout: Optional[timedelta] = None, - task_timeout: Optional[timedelta] = None, + result_type: type | None = None, + execution_timeout: timedelta | None = None, + run_timeout: timedelta | None = None, + task_timeout: timedelta | None = None, id_reuse_policy: temporalio.common.WorkflowIDReusePolicy = temporalio.common.WorkflowIDReusePolicy.ALLOW_DUPLICATE, id_conflict_policy: temporalio.common.WorkflowIDConflictPolicy = temporalio.common.WorkflowIDConflictPolicy.UNSPECIFIED, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cron_schedule: str = "", - memo: Optional[Mapping[str, Any]] = None, - search_attributes: Optional[ - Union[ - temporalio.common.TypedSearchAttributes, - temporalio.common.SearchAttributes, - ] - ] = None, - static_summary: Optional[str] = None, - static_details: Optional[str] = None, - start_delay: Optional[timedelta] = None, - start_signal: Optional[str] = None, + memo: Mapping[str, Any] | None = None, + search_attributes: None + | ( + temporalio.common.TypedSearchAttributes | temporalio.common.SearchAttributes + ) = None, + static_summary: str | None = None, + static_details: str | None = None, + start_delay: timedelta | None = None, + start_signal: str | None = None, start_signal_args: Sequence[Any] = [], - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, request_eager_start: bool = False, priority: temporalio.common.Priority = temporalio.common.Priority.default, - versioning_override: Optional[temporalio.common.VersioningOverride] = None, + versioning_override: temporalio.common.VersioningOverride | None = None, ) -> WorkflowHandle[Any, Any]: ... async def start_workflow( self, - workflow: Union[str, Callable[..., Awaitable[Any]]], + workflow: str | Callable[..., Awaitable[Any]], arg: Any = temporalio.common._arg_unset, *, args: Sequence[Any] = [], id: str, task_queue: str, - result_type: Optional[type] = None, - execution_timeout: Optional[timedelta] = None, - run_timeout: Optional[timedelta] = None, - task_timeout: Optional[timedelta] = None, + result_type: type | None = None, + execution_timeout: timedelta | None = None, + run_timeout: timedelta | None = None, + task_timeout: timedelta | None = None, id_reuse_policy: temporalio.common.WorkflowIDReusePolicy = temporalio.common.WorkflowIDReusePolicy.ALLOW_DUPLICATE, id_conflict_policy: temporalio.common.WorkflowIDConflictPolicy = temporalio.common.WorkflowIDConflictPolicy.UNSPECIFIED, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cron_schedule: str = "", - memo: Optional[Mapping[str, Any]] = None, - search_attributes: Optional[ - Union[ - temporalio.common.TypedSearchAttributes, - temporalio.common.SearchAttributes, - ] - ] = None, - static_summary: Optional[str] = None, - static_details: Optional[str] = None, - start_delay: Optional[timedelta] = None, - start_signal: Optional[str] = None, + memo: Mapping[str, Any] | None = None, + search_attributes: None + | ( + temporalio.common.TypedSearchAttributes | temporalio.common.SearchAttributes + ) = None, + static_summary: str | None = None, + static_details: str | None = None, + start_delay: timedelta | None = None, + start_signal: str | None = None, start_signal_args: Sequence[Any] = [], - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, request_eager_start: bool = False, priority: temporalio.common.Priority = temporalio.common.Priority.default, - versioning_override: Optional[temporalio.common.VersioningOverride] = None, + versioning_override: temporalio.common.VersioningOverride | None = None, # The following options should not be considered part of the public API. They # are deliberately not exposed in overloads, and are not subject to any # backwards compatibility guarantees. @@ -540,7 +531,7 @@ async def start_workflow( workflow_event_links: Sequence[ temporalio.api.common.v1.Link.WorkflowEvent ] = [], - request_id: Optional[str] = None, + request_id: str | None = None, stack_level: int = 2, ) -> WorkflowHandle[Any, Any]: """Start a workflow and return its handle. @@ -646,30 +637,28 @@ async def execute_workflow( *, id: str, task_queue: str, - execution_timeout: Optional[timedelta] = None, - run_timeout: Optional[timedelta] = None, - task_timeout: Optional[timedelta] = None, + execution_timeout: timedelta | None = None, + run_timeout: timedelta | None = None, + task_timeout: timedelta | None = None, id_reuse_policy: temporalio.common.WorkflowIDReusePolicy = temporalio.common.WorkflowIDReusePolicy.ALLOW_DUPLICATE, id_conflict_policy: temporalio.common.WorkflowIDConflictPolicy = temporalio.common.WorkflowIDConflictPolicy.UNSPECIFIED, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cron_schedule: str = "", - memo: Optional[Mapping[str, Any]] = None, - search_attributes: Optional[ - Union[ - temporalio.common.TypedSearchAttributes, - temporalio.common.SearchAttributes, - ] - ] = None, - static_summary: Optional[str] = None, - static_details: Optional[str] = None, - start_delay: Optional[timedelta] = None, - start_signal: Optional[str] = None, + memo: Mapping[str, Any] | None = None, + search_attributes: None + | ( + temporalio.common.TypedSearchAttributes | temporalio.common.SearchAttributes + ) = None, + static_summary: str | None = None, + static_details: str | None = None, + start_delay: timedelta | None = None, + start_signal: str | None = None, start_signal_args: Sequence[Any] = [], - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, request_eager_start: bool = False, priority: temporalio.common.Priority = temporalio.common.Priority.default, - versioning_override: Optional[temporalio.common.VersioningOverride] = None, + versioning_override: temporalio.common.VersioningOverride | None = None, ) -> ReturnType: ... # Overload for single-param workflow @@ -681,30 +670,28 @@ async def execute_workflow( *, id: str, task_queue: str, - execution_timeout: Optional[timedelta] = None, - run_timeout: Optional[timedelta] = None, - task_timeout: Optional[timedelta] = None, + execution_timeout: timedelta | None = None, + run_timeout: timedelta | None = None, + task_timeout: timedelta | None = None, id_reuse_policy: temporalio.common.WorkflowIDReusePolicy = temporalio.common.WorkflowIDReusePolicy.ALLOW_DUPLICATE, id_conflict_policy: temporalio.common.WorkflowIDConflictPolicy = temporalio.common.WorkflowIDConflictPolicy.UNSPECIFIED, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cron_schedule: str = "", - memo: Optional[Mapping[str, Any]] = None, - search_attributes: Optional[ - Union[ - temporalio.common.TypedSearchAttributes, - temporalio.common.SearchAttributes, - ] - ] = None, - static_summary: Optional[str] = None, - static_details: Optional[str] = None, - start_delay: Optional[timedelta] = None, - start_signal: Optional[str] = None, + memo: Mapping[str, Any] | None = None, + search_attributes: None + | ( + temporalio.common.TypedSearchAttributes | temporalio.common.SearchAttributes + ) = None, + static_summary: str | None = None, + static_details: str | None = None, + start_delay: timedelta | None = None, + start_signal: str | None = None, start_signal_args: Sequence[Any] = [], - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, request_eager_start: bool = False, priority: temporalio.common.Priority = temporalio.common.Priority.default, - versioning_override: Optional[temporalio.common.VersioningOverride] = None, + versioning_override: temporalio.common.VersioningOverride | None = None, ) -> ReturnType: ... # Overload for multi-param workflow @@ -718,30 +705,28 @@ async def execute_workflow( args: Sequence[Any], id: str, task_queue: str, - execution_timeout: Optional[timedelta] = None, - run_timeout: Optional[timedelta] = None, - task_timeout: Optional[timedelta] = None, + execution_timeout: timedelta | None = None, + run_timeout: timedelta | None = None, + task_timeout: timedelta | None = None, id_reuse_policy: temporalio.common.WorkflowIDReusePolicy = temporalio.common.WorkflowIDReusePolicy.ALLOW_DUPLICATE, id_conflict_policy: temporalio.common.WorkflowIDConflictPolicy = temporalio.common.WorkflowIDConflictPolicy.UNSPECIFIED, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cron_schedule: str = "", - memo: Optional[Mapping[str, Any]] = None, - search_attributes: Optional[ - Union[ - temporalio.common.TypedSearchAttributes, - temporalio.common.SearchAttributes, - ] - ] = None, - static_summary: Optional[str] = None, - static_details: Optional[str] = None, - start_delay: Optional[timedelta] = None, - start_signal: Optional[str] = None, + memo: Mapping[str, Any] | None = None, + search_attributes: None + | ( + temporalio.common.TypedSearchAttributes | temporalio.common.SearchAttributes + ) = None, + static_summary: str | None = None, + static_details: str | None = None, + start_delay: timedelta | None = None, + start_signal: str | None = None, start_signal_args: Sequence[Any] = [], - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, request_eager_start: bool = False, priority: temporalio.common.Priority = temporalio.common.Priority.default, - versioning_override: Optional[temporalio.common.VersioningOverride] = None, + versioning_override: temporalio.common.VersioningOverride | None = None, ) -> ReturnType: ... # Overload for string-name workflow @@ -754,66 +739,62 @@ async def execute_workflow( args: Sequence[Any] = [], id: str, task_queue: str, - result_type: Optional[type] = None, - execution_timeout: Optional[timedelta] = None, - run_timeout: Optional[timedelta] = None, - task_timeout: Optional[timedelta] = None, + result_type: type | None = None, + execution_timeout: timedelta | None = None, + run_timeout: timedelta | None = None, + task_timeout: timedelta | None = None, id_reuse_policy: temporalio.common.WorkflowIDReusePolicy = temporalio.common.WorkflowIDReusePolicy.ALLOW_DUPLICATE, id_conflict_policy: temporalio.common.WorkflowIDConflictPolicy = temporalio.common.WorkflowIDConflictPolicy.UNSPECIFIED, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cron_schedule: str = "", - memo: Optional[Mapping[str, Any]] = None, - search_attributes: Optional[ - Union[ - temporalio.common.TypedSearchAttributes, - temporalio.common.SearchAttributes, - ] - ] = None, - static_summary: Optional[str] = None, - static_details: Optional[str] = None, - start_delay: Optional[timedelta] = None, - start_signal: Optional[str] = None, + memo: Mapping[str, Any] | None = None, + search_attributes: None + | ( + temporalio.common.TypedSearchAttributes | temporalio.common.SearchAttributes + ) = None, + static_summary: str | None = None, + static_details: str | None = None, + start_delay: timedelta | None = None, + start_signal: str | None = None, start_signal_args: Sequence[Any] = [], - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, request_eager_start: bool = False, priority: temporalio.common.Priority = temporalio.common.Priority.default, - versioning_override: Optional[temporalio.common.VersioningOverride] = None, + versioning_override: temporalio.common.VersioningOverride | None = None, ) -> Any: ... async def execute_workflow( self, - workflow: Union[str, Callable[..., Awaitable[Any]]], + workflow: str | Callable[..., Awaitable[Any]], arg: Any = temporalio.common._arg_unset, *, args: Sequence[Any] = [], id: str, task_queue: str, - result_type: Optional[type] = None, - execution_timeout: Optional[timedelta] = None, - run_timeout: Optional[timedelta] = None, - task_timeout: Optional[timedelta] = None, + result_type: type | None = None, + execution_timeout: timedelta | None = None, + run_timeout: timedelta | None = None, + task_timeout: timedelta | None = None, id_reuse_policy: temporalio.common.WorkflowIDReusePolicy = temporalio.common.WorkflowIDReusePolicy.ALLOW_DUPLICATE, id_conflict_policy: temporalio.common.WorkflowIDConflictPolicy = temporalio.common.WorkflowIDConflictPolicy.UNSPECIFIED, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cron_schedule: str = "", - memo: Optional[Mapping[str, Any]] = None, - search_attributes: Optional[ - Union[ - temporalio.common.TypedSearchAttributes, - temporalio.common.SearchAttributes, - ] - ] = None, - static_summary: Optional[str] = None, - static_details: Optional[str] = None, - start_delay: Optional[timedelta] = None, - start_signal: Optional[str] = None, + memo: Mapping[str, Any] | None = None, + search_attributes: None + | ( + temporalio.common.TypedSearchAttributes | temporalio.common.SearchAttributes + ) = None, + static_summary: str | None = None, + static_details: str | None = None, + start_delay: timedelta | None = None, + start_signal: str | None = None, start_signal_args: Sequence[Any] = [], - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, request_eager_start: bool = False, priority: temporalio.common.Priority = temporalio.common.Priority.default, - versioning_override: Optional[temporalio.common.VersioningOverride] = None, + versioning_override: temporalio.common.VersioningOverride | None = None, ) -> Any: """Start a workflow and wait for completion. @@ -857,9 +838,9 @@ def get_workflow_handle( self, workflow_id: str, *, - run_id: Optional[str] = None, - first_execution_run_id: Optional[str] = None, - result_type: Optional[Type] = None, + run_id: str | None = None, + first_execution_run_id: str | None = None, + result_type: type | None = None, ) -> WorkflowHandle[Any, Any]: """Get a workflow handle to an existing workflow by its ID. @@ -884,14 +865,14 @@ def get_workflow_handle( def get_workflow_handle_for( self, - workflow: Union[ - MethodAsyncNoParam[SelfType, ReturnType], - MethodAsyncSingleParam[SelfType, Any, ReturnType], - ], + workflow: ( + MethodAsyncNoParam[SelfType, ReturnType] + | MethodAsyncSingleParam[SelfType, Any, ReturnType] + ), workflow_id: str, *, - run_id: Optional[str] = None, - first_execution_run_id: Optional[str] = None, + run_id: str | None = None, + first_execution_run_id: str | None = None, ) -> WorkflowHandle[SelfType, ReturnType]: """Get a typed workflow handle to an existing workflow by its ID. @@ -922,9 +903,9 @@ async def execute_update_with_start_workflow( update: temporalio.workflow.UpdateMethodMultiParam[[SelfType], LocalReturnType], *, start_workflow_operation: WithStartWorkflowOperation[SelfType, Any], - id: Optional[str] = None, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + id: str | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> LocalReturnType: ... # Overload for single-param update @@ -937,9 +918,9 @@ async def execute_update_with_start_workflow( arg: ParamType, *, start_workflow_operation: WithStartWorkflowOperation[SelfType, Any], - id: Optional[str] = None, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + id: str | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> LocalReturnType: ... # Overload for multi-param update @@ -952,9 +933,9 @@ async def execute_update_with_start_workflow( *, args: MultiParamSpec.args, # type: ignore start_workflow_operation: WithStartWorkflowOperation[SelfType, Any], - id: Optional[str] = None, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + id: str | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> LocalReturnType: ... # Overload for string-name update @@ -966,23 +947,23 @@ async def execute_update_with_start_workflow( *, start_workflow_operation: WithStartWorkflowOperation[Any, Any], args: Sequence[Any] = [], - id: Optional[str] = None, - result_type: Optional[Type] = None, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + id: str | None = None, + result_type: type | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> Any: ... async def execute_update_with_start_workflow( self, - update: Union[str, Callable], + update: str | Callable, arg: Any = temporalio.common._arg_unset, *, start_workflow_operation: WithStartWorkflowOperation[Any, Any], args: Sequence[Any] = [], - id: Optional[str] = None, - result_type: Optional[Type] = None, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + id: str | None = None, + result_type: type | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> Any: """Send an update-with-start request and wait for the update to complete. @@ -1040,9 +1021,9 @@ async def start_update_with_start_workflow( *, start_workflow_operation: WithStartWorkflowOperation[SelfType, Any], wait_for_stage: WorkflowUpdateStage, - id: Optional[str] = None, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + id: str | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> WorkflowUpdateHandle[LocalReturnType]: ... # Overload for single-param start update @@ -1056,9 +1037,9 @@ async def start_update_with_start_workflow( *, start_workflow_operation: WithStartWorkflowOperation[SelfType, Any], wait_for_stage: WorkflowUpdateStage, - id: Optional[str] = None, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + id: str | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> WorkflowUpdateHandle[LocalReturnType]: ... # Overload for multi-param start update @@ -1072,9 +1053,9 @@ async def start_update_with_start_workflow( args: MultiParamSpec.args, # type: ignore start_workflow_operation: WithStartWorkflowOperation[SelfType, Any], wait_for_stage: WorkflowUpdateStage, - id: Optional[str] = None, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + id: str | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> WorkflowUpdateHandle[LocalReturnType]: ... # Overload for string-name start update @@ -1087,24 +1068,24 @@ async def start_update_with_start_workflow( start_workflow_operation: WithStartWorkflowOperation[Any, Any], wait_for_stage: WorkflowUpdateStage, args: Sequence[Any] = [], - id: Optional[str] = None, - result_type: Optional[Type] = None, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + id: str | None = None, + result_type: type | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> WorkflowUpdateHandle[Any]: ... async def start_update_with_start_workflow( self, - update: Union[str, Callable], + update: str | Callable, arg: Any = temporalio.common._arg_unset, *, start_workflow_operation: WithStartWorkflowOperation[Any, Any], wait_for_stage: WorkflowUpdateStage, args: Sequence[Any] = [], - id: Optional[str] = None, - result_type: Optional[Type] = None, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + id: str | None = None, + result_type: type | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> WorkflowUpdateHandle[Any]: """Send an update-with-start request and wait for it to be accepted. @@ -1161,16 +1142,16 @@ async def start_update_with_start_workflow( async def _start_update_with_start( self, - update: Union[str, Callable], + update: str | Callable, arg: Any = temporalio.common._arg_unset, *, wait_for_stage: WorkflowUpdateStage, args: Sequence[Any] = [], - id: Optional[str] = None, - result_type: Optional[Type] = None, + id: str | None = None, + result_type: type | None = None, start_workflow_operation: WithStartWorkflowOperation[SelfType, ReturnType], - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> WorkflowUpdateHandle[Any]: if wait_for_stage == WorkflowUpdateStage.ADMITTED: raise ValueError("ADMITTED wait stage not supported") @@ -1223,13 +1204,13 @@ def on_start_error( def list_workflows( self, - query: Optional[str] = None, + query: str | None = None, *, - limit: Optional[int] = None, + limit: int | None = None, page_size: int = 1000, - next_page_token: Optional[bytes] = None, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + next_page_token: bytes | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> WorkflowExecutionAsyncIterator: """List workflows. @@ -1268,9 +1249,9 @@ def list_workflows( async def count_workflows( self, - query: Optional[str] = None, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + query: str | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> WorkflowExecutionCount: """Count workflows. @@ -1292,7 +1273,7 @@ async def count_workflows( @overload def get_async_activity_handle( - self, *, workflow_id: str, run_id: Optional[str], activity_id: str + self, *, workflow_id: str, run_id: str | None, activity_id: str ) -> AsyncActivityHandle: pass @@ -1303,10 +1284,10 @@ def get_async_activity_handle(self, *, task_token: bytes) -> AsyncActivityHandle def get_async_activity_handle( self, *, - workflow_id: Optional[str] = None, - run_id: Optional[str] = None, - activity_id: Optional[str] = None, - task_token: Optional[bytes] = None, + workflow_id: str | None = None, + run_id: str | None = None, + activity_id: str | None = None, + task_token: bytes | None = None, ) -> AsyncActivityHandle: """Get an async activity handle. @@ -1349,17 +1330,15 @@ async def create_schedule( *, trigger_immediately: bool = False, backfill: Sequence[ScheduleBackfill] = [], - memo: Optional[Mapping[str, Any]] = None, - search_attributes: Optional[ - Union[ - temporalio.common.TypedSearchAttributes, - temporalio.common.SearchAttributes, - ] - ] = None, - static_summary: Optional[str] = None, - static_details: Optional[str] = None, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + memo: Mapping[str, Any] | None = None, + search_attributes: None + | ( + temporalio.common.TypedSearchAttributes | temporalio.common.SearchAttributes + ) = None, + static_summary: str | None = None, + static_details: str | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> ScheduleHandle: """Create a schedule and return its handle. @@ -1413,12 +1392,12 @@ def get_schedule_handle(self, id: str) -> ScheduleHandle: async def list_schedules( self, - query: Optional[str] = None, + query: str | None = None, *, page_size: int = 1000, - next_page_token: Optional[bytes] = None, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + next_page_token: bytes | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> ScheduleAsyncIterator: """List schedules. @@ -1457,8 +1436,8 @@ async def update_worker_build_id_compatibility( self, task_queue: str, operation: BuildIdOp, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> None: """Used to add new Build IDs or otherwise update the relative compatibility of Build Ids as defined on a specific task queue for the Worker Versioning feature. @@ -1487,9 +1466,9 @@ async def update_worker_build_id_compatibility( async def get_worker_build_id_compatibility( self, task_queue: str, - max_sets: Optional[int] = None, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + max_sets: int | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> WorkerBuildIdVersionSets: """Get the Build ID compatibility sets for a specific task queue. @@ -1519,9 +1498,9 @@ async def get_worker_task_reachability( self, build_ids: Sequence[str], task_queues: Sequence[str] = [], - reachability_type: Optional[TaskReachabilityType] = None, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + reachability_type: TaskReachabilityType | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> WorkerTaskReachability: """Determine if some Build IDs for certain Task Queues could have tasks dispatched to them. @@ -1565,7 +1544,7 @@ class ClientConfig(TypedDict, total=False): plugins: Required[Sequence[Plugin]] interceptors: Required[Sequence[Interceptor]] default_workflow_query_reject_condition: Required[ - Optional[temporalio.common.QueryRejectCondition] + temporalio.common.QueryRejectCondition | None ] header_codec_behavior: Required[HeaderCodecBehavior] @@ -1596,16 +1575,15 @@ def __init__( client: Client, id: str, *, - run_id: Optional[str] = None, - result_run_id: Optional[str] = None, - first_execution_run_id: Optional[str] = None, - result_type: Optional[Type] = None, - start_workflow_response: Optional[ - Union[ - temporalio.api.workflowservice.v1.StartWorkflowExecutionResponse, - temporalio.api.workflowservice.v1.SignalWithStartWorkflowExecutionResponse, - ] - ] = None, + run_id: str | None = None, + result_run_id: str | None = None, + first_execution_run_id: str | None = None, + result_type: type | None = None, + start_workflow_response: None + | ( + temporalio.api.workflowservice.v1.StartWorkflowExecutionResponse + | temporalio.api.workflowservice.v1.SignalWithStartWorkflowExecutionResponse + ) = None, ) -> None: """Create workflow handle.""" self._client = client @@ -1631,7 +1609,7 @@ def id(self) -> str: return self._id @property - def run_id(self) -> Optional[str]: + def run_id(self) -> str | None: """If present, run ID used to ensure that requested operations apply to this exact run. @@ -1644,7 +1622,7 @@ def run_id(self) -> Optional[str]: return self._run_id @property - def result_run_id(self) -> Optional[str]: + def result_run_id(self) -> str | None: """Run ID used for :py:meth:`result` calls if present to ensure result is for a workflow starting from this run. @@ -1659,7 +1637,7 @@ def result_run_id(self) -> Optional[str]: return self._result_run_id @property - def first_execution_run_id(self) -> Optional[str]: + def first_execution_run_id(self) -> str | None: """Run ID used to ensure requested operations apply to a workflow ID started with this run ID. @@ -1676,8 +1654,8 @@ async def result( self, *, follow_runs: bool = True, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> ReturnType: """Wait for result of the workflow. @@ -1807,8 +1785,8 @@ async def result( async def cancel( self, *, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> None: """Cancel the workflow. @@ -1843,8 +1821,8 @@ async def cancel( async def describe( self, *, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> WorkflowExecutionDescription: """Get workflow details. @@ -1882,8 +1860,8 @@ async def fetch_history( *, event_filter_type: WorkflowHistoryEventFilterType = WorkflowHistoryEventFilterType.ALL_EVENT, skip_archival: bool = False, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> WorkflowHistory: """Get workflow history. @@ -1906,13 +1884,13 @@ async def fetch_history( def fetch_history_events( self, *, - page_size: Optional[int] = None, - next_page_token: Optional[bytes] = None, + page_size: int | None = None, + next_page_token: bytes | None = None, wait_new_event: bool = False, event_filter_type: WorkflowHistoryEventFilterType = WorkflowHistoryEventFilterType.ALL_EVENT, skip_archival: bool = False, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> WorkflowHistoryEventAsyncIterator: """Get workflow history events as an async iterator. @@ -1946,15 +1924,15 @@ def fetch_history_events( def _fetch_history_events_for_run( self, - run_id: Optional[str], + run_id: str | None, *, - page_size: Optional[int] = None, - next_page_token: Optional[bytes] = None, + page_size: int | None = None, + next_page_token: bytes | None = None, wait_new_event: bool = False, event_filter_type: WorkflowHistoryEventFilterType = WorkflowHistoryEventFilterType.ALL_EVENT, skip_archival: bool = False, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> WorkflowHistoryEventAsyncIterator: return self._client._impl.fetch_workflow_history_events( FetchWorkflowHistoryEventsInput( @@ -1976,9 +1954,9 @@ async def query( self, query: MethodSyncOrAsyncNoParam[SelfType, LocalReturnType], *, - reject_condition: Optional[temporalio.common.QueryRejectCondition] = None, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + reject_condition: temporalio.common.QueryRejectCondition | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> LocalReturnType: ... # Overload for single-param query @@ -1988,9 +1966,9 @@ async def query( query: MethodSyncOrAsyncSingleParam[SelfType, ParamType, LocalReturnType], arg: ParamType, *, - reject_condition: Optional[temporalio.common.QueryRejectCondition] = None, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + reject_condition: temporalio.common.QueryRejectCondition | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> LocalReturnType: ... # Overload for multi-param query @@ -1999,13 +1977,13 @@ async def query( self, query: Callable[ Concatenate[SelfType, MultiParamSpec], - Union[Awaitable[LocalReturnType], LocalReturnType], + Awaitable[LocalReturnType] | LocalReturnType, ], *, args: Sequence[Any], - reject_condition: Optional[temporalio.common.QueryRejectCondition] = None, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + reject_condition: temporalio.common.QueryRejectCondition | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> LocalReturnType: ... # Overload for string-name query @@ -2016,22 +1994,22 @@ async def query( arg: Any = temporalio.common._arg_unset, *, args: Sequence[Any] = [], - result_type: Optional[Type] = None, - reject_condition: Optional[temporalio.common.QueryRejectCondition] = None, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + result_type: type | None = None, + reject_condition: temporalio.common.QueryRejectCondition | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> Any: ... async def query( self, - query: Union[str, Callable], + query: str | Callable, arg: Any = temporalio.common._arg_unset, *, args: Sequence[Any] = [], - result_type: Optional[Type] = None, - reject_condition: Optional[temporalio.common.QueryRejectCondition] = None, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + result_type: type | None = None, + reject_condition: temporalio.common.QueryRejectCondition | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> Any: """Query the workflow. @@ -2101,8 +2079,8 @@ async def signal( self, signal: MethodSyncOrAsyncNoParam[SelfType, None], *, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> None: ... # Overload for single-param signal @@ -2112,21 +2090,19 @@ async def signal( signal: MethodSyncOrAsyncSingleParam[SelfType, ParamType, None], arg: ParamType, *, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> None: ... # Overload for multi-param signal @overload async def signal( self, - signal: Callable[ - Concatenate[SelfType, MultiParamSpec], Union[Awaitable[None], None] - ], + signal: Callable[Concatenate[SelfType, MultiParamSpec], Awaitable[None] | None], *, args: Sequence[Any], - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> None: ... # Overload for string-name signal @@ -2137,18 +2113,18 @@ async def signal( arg: Any = temporalio.common._arg_unset, *, args: Sequence[Any] = [], - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> None: ... async def signal( self, - signal: Union[str, Callable], + signal: str | Callable, arg: Any = temporalio.common._arg_unset, *, args: Sequence[Any] = [], - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> None: """Send a signal to the workflow. @@ -2189,9 +2165,9 @@ async def signal( async def terminate( self, *args: Any, - reason: Optional[str] = None, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + reason: str | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> None: """Terminate the workflow. @@ -2233,9 +2209,9 @@ async def execute_update( self, update: temporalio.workflow.UpdateMethodMultiParam[[SelfType], LocalReturnType], *, - id: Optional[str] = None, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + id: str | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> LocalReturnType: ... # Overload for single-param update @@ -2247,9 +2223,9 @@ async def execute_update( ], arg: ParamType, *, - id: Optional[str] = None, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + id: str | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> LocalReturnType: ... # Overload for multi-param update @@ -2261,9 +2237,9 @@ async def execute_update( ], *, args: MultiParamSpec.args, # type: ignore - id: Optional[str] = None, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + id: str | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> LocalReturnType: ... # Overload for string-name update @@ -2274,22 +2250,22 @@ async def execute_update( arg: Any = temporalio.common._arg_unset, *, args: Sequence[Any] = [], - id: Optional[str] = None, - result_type: Optional[Type] = None, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + id: str | None = None, + result_type: type | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> Any: ... async def execute_update( self, - update: Union[str, Callable], + update: str | Callable, arg: Any = temporalio.common._arg_unset, *, args: Sequence[Any] = [], - id: Optional[str] = None, - result_type: Optional[Type] = None, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + id: str | None = None, + result_type: type | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> Any: """Send an update request to the workflow and wait for it to complete. @@ -2333,9 +2309,9 @@ async def start_update( update: temporalio.workflow.UpdateMethodMultiParam[[SelfType], LocalReturnType], *, wait_for_stage: WorkflowUpdateStage, - id: Optional[str] = None, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + id: str | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> WorkflowUpdateHandle[LocalReturnType]: ... # Overload for single-param start update @@ -2348,9 +2324,9 @@ async def start_update( arg: ParamType, *, wait_for_stage: WorkflowUpdateStage, - id: Optional[str] = None, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + id: str | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> WorkflowUpdateHandle[LocalReturnType]: ... # Overload for multi-param start update @@ -2363,9 +2339,9 @@ async def start_update( *, args: MultiParamSpec.args, # type: ignore wait_for_stage: WorkflowUpdateStage, - id: Optional[str] = None, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + id: str | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> WorkflowUpdateHandle[LocalReturnType]: ... # Overload for string-name start update @@ -2377,23 +2353,23 @@ async def start_update( *, wait_for_stage: WorkflowUpdateStage, args: Sequence[Any] = [], - id: Optional[str] = None, - result_type: Optional[Type] = None, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + id: str | None = None, + result_type: type | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> WorkflowUpdateHandle[Any]: ... async def start_update( self, - update: Union[str, Callable], + update: str | Callable, arg: Any = temporalio.common._arg_unset, *, wait_for_stage: WorkflowUpdateStage, args: Sequence[Any] = [], - id: Optional[str] = None, - result_type: Optional[Type] = None, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + id: str | None = None, + result_type: type | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> WorkflowUpdateHandle[Any]: """Send an update request to the workflow and return a handle to it. @@ -2433,15 +2409,15 @@ async def start_update( async def _start_update( self, - update: Union[str, Callable], + update: str | Callable, arg: Any = temporalio.common._arg_unset, *, wait_for_stage: WorkflowUpdateStage, args: Sequence[Any] = [], - id: Optional[str] = None, - result_type: Optional[Type] = None, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + id: str | None = None, + result_type: type | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> WorkflowUpdateHandle[Any]: if wait_for_stage == WorkflowUpdateStage.ADMITTED: raise ValueError("ADMITTED wait stage not supported") @@ -2470,8 +2446,8 @@ def get_update_handle( self, id: str, *, - workflow_run_id: Optional[str] = None, - result_type: Optional[Type] = None, + workflow_run_id: str | None = None, + result_type: type | None = None, ) -> WorkflowUpdateHandle[Any]: """Get a handle for an update. The handle can be used to wait on the update result. @@ -2501,7 +2477,7 @@ def get_update_handle_for( update: temporalio.workflow.UpdateMethodMultiParam[Any, LocalReturnType], id: str, *, - workflow_run_id: Optional[str] = None, + workflow_run_id: str | None = None, ) -> WorkflowUpdateHandle[LocalReturnType]: """Get a typed handle for an update. The handle can be used to wait on the update result. @@ -2538,26 +2514,24 @@ def __init__( id: str, task_queue: str, id_conflict_policy: temporalio.common.WorkflowIDConflictPolicy, - execution_timeout: Optional[timedelta] = None, - run_timeout: Optional[timedelta] = None, - task_timeout: Optional[timedelta] = None, + execution_timeout: timedelta | None = None, + run_timeout: timedelta | None = None, + task_timeout: timedelta | None = None, id_reuse_policy: temporalio.common.WorkflowIDReusePolicy = temporalio.common.WorkflowIDReusePolicy.ALLOW_DUPLICATE, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cron_schedule: str = "", - memo: Optional[Mapping[str, Any]] = None, - search_attributes: Optional[ - Union[ - temporalio.common.TypedSearchAttributes, - temporalio.common.SearchAttributes, - ] - ] = None, - static_summary: Optional[str] = None, - static_details: Optional[str] = None, - start_delay: Optional[timedelta] = None, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + memo: Mapping[str, Any] | None = None, + search_attributes: None + | ( + temporalio.common.TypedSearchAttributes | temporalio.common.SearchAttributes + ) = None, + static_summary: str | None = None, + static_details: str | None = None, + start_delay: timedelta | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, - versioning_override: Optional[temporalio.common.VersioningOverride] = None, + versioning_override: temporalio.common.VersioningOverride | None = None, ) -> None: ... # Overload for single-param workflow, with_start @@ -2570,26 +2544,24 @@ def __init__( id: str, task_queue: str, id_conflict_policy: temporalio.common.WorkflowIDConflictPolicy, - execution_timeout: Optional[timedelta] = None, - run_timeout: Optional[timedelta] = None, - task_timeout: Optional[timedelta] = None, + execution_timeout: timedelta | None = None, + run_timeout: timedelta | None = None, + task_timeout: timedelta | None = None, id_reuse_policy: temporalio.common.WorkflowIDReusePolicy = temporalio.common.WorkflowIDReusePolicy.ALLOW_DUPLICATE, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cron_schedule: str = "", - memo: Optional[Mapping[str, Any]] = None, - search_attributes: Optional[ - Union[ - temporalio.common.TypedSearchAttributes, - temporalio.common.SearchAttributes, - ] - ] = None, - static_summary: Optional[str] = None, - static_details: Optional[str] = None, - start_delay: Optional[timedelta] = None, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + memo: Mapping[str, Any] | None = None, + search_attributes: None + | ( + temporalio.common.TypedSearchAttributes | temporalio.common.SearchAttributes + ) = None, + static_summary: str | None = None, + static_details: str | None = None, + start_delay: timedelta | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, - versioning_override: Optional[temporalio.common.VersioningOverride] = None, + versioning_override: temporalio.common.VersioningOverride | None = None, ) -> None: ... # Overload for multi-param workflow, with_start @@ -2604,26 +2576,24 @@ def __init__( id: str, task_queue: str, id_conflict_policy: temporalio.common.WorkflowIDConflictPolicy, - execution_timeout: Optional[timedelta] = None, - run_timeout: Optional[timedelta] = None, - task_timeout: Optional[timedelta] = None, + execution_timeout: timedelta | None = None, + run_timeout: timedelta | None = None, + task_timeout: timedelta | None = None, id_reuse_policy: temporalio.common.WorkflowIDReusePolicy = temporalio.common.WorkflowIDReusePolicy.ALLOW_DUPLICATE, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cron_schedule: str = "", - memo: Optional[Mapping[str, Any]] = None, - search_attributes: Optional[ - Union[ - temporalio.common.TypedSearchAttributes, - temporalio.common.SearchAttributes, - ] - ] = None, - static_summary: Optional[str] = None, - static_details: Optional[str] = None, - start_delay: Optional[timedelta] = None, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + memo: Mapping[str, Any] | None = None, + search_attributes: None + | ( + temporalio.common.TypedSearchAttributes | temporalio.common.SearchAttributes + ) = None, + static_summary: str | None = None, + static_details: str | None = None, + start_delay: timedelta | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, - versioning_override: Optional[temporalio.common.VersioningOverride] = None, + versioning_override: temporalio.common.VersioningOverride | None = None, ) -> None: ... # Overload for string-name workflow, with_start @@ -2637,59 +2607,55 @@ def __init__( id: str, task_queue: str, id_conflict_policy: temporalio.common.WorkflowIDConflictPolicy, - result_type: Optional[Type] = None, - execution_timeout: Optional[timedelta] = None, - run_timeout: Optional[timedelta] = None, - task_timeout: Optional[timedelta] = None, + result_type: type | None = None, + execution_timeout: timedelta | None = None, + run_timeout: timedelta | None = None, + task_timeout: timedelta | None = None, id_reuse_policy: temporalio.common.WorkflowIDReusePolicy = temporalio.common.WorkflowIDReusePolicy.ALLOW_DUPLICATE, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cron_schedule: str = "", - memo: Optional[Mapping[str, Any]] = None, - search_attributes: Optional[ - Union[ - temporalio.common.TypedSearchAttributes, - temporalio.common.SearchAttributes, - ] - ] = None, - static_summary: Optional[str] = None, - static_details: Optional[str] = None, - start_delay: Optional[timedelta] = None, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + memo: Mapping[str, Any] | None = None, + search_attributes: None + | ( + temporalio.common.TypedSearchAttributes | temporalio.common.SearchAttributes + ) = None, + static_summary: str | None = None, + static_details: str | None = None, + start_delay: timedelta | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, - versioning_override: Optional[temporalio.common.VersioningOverride] = None, + versioning_override: temporalio.common.VersioningOverride | None = None, ) -> None: ... def __init__( self, - workflow: Union[str, Callable[..., Awaitable[Any]]], + workflow: str | Callable[..., Awaitable[Any]], arg: Any = temporalio.common._arg_unset, *, args: Sequence[Any] = [], id: str, task_queue: str, id_conflict_policy: temporalio.common.WorkflowIDConflictPolicy, - result_type: Optional[Type] = None, - execution_timeout: Optional[timedelta] = None, - run_timeout: Optional[timedelta] = None, - task_timeout: Optional[timedelta] = None, + result_type: type | None = None, + execution_timeout: timedelta | None = None, + run_timeout: timedelta | None = None, + task_timeout: timedelta | None = None, id_reuse_policy: temporalio.common.WorkflowIDReusePolicy = temporalio.common.WorkflowIDReusePolicy.ALLOW_DUPLICATE, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cron_schedule: str = "", - memo: Optional[Mapping[str, Any]] = None, - search_attributes: Optional[ - Union[ - temporalio.common.TypedSearchAttributes, - temporalio.common.SearchAttributes, - ] - ] = None, - static_summary: Optional[str] = None, - static_details: Optional[str] = None, - start_delay: Optional[timedelta] = None, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + memo: Mapping[str, Any] | None = None, + search_attributes: None + | ( + temporalio.common.TypedSearchAttributes | temporalio.common.SearchAttributes + ) = None, + static_summary: str | None = None, + static_details: str | None = None, + start_delay: timedelta | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, - versioning_override: Optional[temporalio.common.VersioningOverride] = None, + versioning_override: temporalio.common.VersioningOverride | None = None, stack_level: int = 2, ) -> None: """Create a WithStartWorkflowOperation. @@ -2743,7 +2709,7 @@ class AsyncActivityIDReference: """Reference to an async activity by its qualified ID.""" workflow_id: str - run_id: Optional[str] + run_id: str | None activity_id: str @@ -2753,8 +2719,8 @@ class AsyncActivityHandle(WithSerializationContext): def __init__( self, client: Client, - id_or_token: Union[AsyncActivityIDReference, bytes], - data_converter_override: Optional[DataConverter] = None, + id_or_token: AsyncActivityIDReference | bytes, + data_converter_override: DataConverter | None = None, ) -> None: """Create an async activity handle.""" self._client = client @@ -2764,8 +2730,8 @@ def __init__( async def heartbeat( self, *details: Any, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> None: """Record a heartbeat for the activity. @@ -2787,10 +2753,10 @@ async def heartbeat( async def complete( self, - result: Optional[Any] = temporalio.common._arg_unset, + result: Any | None = temporalio.common._arg_unset, *, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> None: """Complete the activity. @@ -2815,8 +2781,8 @@ async def fail( error: Exception, *, last_heartbeat_details: Sequence[Any] = [], - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> None: """Fail the activity. @@ -2841,8 +2807,8 @@ async def fail( async def report_cancellation( self, *details: Any, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> None: """Report the activity as cancelled. @@ -2890,10 +2856,10 @@ def with_context(self, context: SerializationContext) -> Self: class WorkflowExecution: """Info for a single workflow execution run.""" - close_time: Optional[datetime] + close_time: datetime | None """When the workflow was closed if closed.""" - execution_time: Optional[datetime] + execution_time: datetime | None """When this workflow run started or should start.""" history_length: int @@ -2905,16 +2871,16 @@ class WorkflowExecution: namespace: str """Namespace for the workflow.""" - parent_id: Optional[str] + parent_id: str | None """ID for the parent workflow if this was started as a child.""" - parent_run_id: Optional[str] + parent_run_id: str | None """Run ID for the parent workflow if this was started as a child.""" - root_id: Optional[str] + root_id: str | None """ID for the root workflow.""" - root_run_id: Optional[str] + root_run_id: str | None """Run ID for the root workflow.""" raw_info: temporalio.api.workflow.v1.WorkflowExecutionInfo @@ -2933,7 +2899,7 @@ class WorkflowExecution: start_time: datetime """When the workflow was created.""" - status: Optional[WorkflowExecutionStatus] + status: WorkflowExecutionStatus | None """Status for the workflow.""" task_queue: str @@ -3036,20 +3002,20 @@ async def memo_value( @overload async def memo_value( - self, key: str, *, type_hint: Type[ParamType] + self, key: str, *, type_hint: type[ParamType] ) -> ParamType: ... @overload async def memo_value( - self, key: str, default: AnyType, *, type_hint: Type[ParamType] - ) -> Union[AnyType, ParamType]: ... + self, key: str, default: AnyType, *, type_hint: type[ParamType] + ) -> AnyType | ParamType: ... async def memo_value( self, key: str, default: Any = temporalio.common._arg_unset, *, - type_hint: Optional[Type] = None, + type_hint: type | None = None, ) -> Any: """Memo value for the given key, optional default, and optional type hint. @@ -3085,11 +3051,11 @@ class WorkflowExecutionDescription(WorkflowExecution): raw_description: temporalio.api.workflowservice.v1.DescribeWorkflowExecutionResponse """Underlying protobuf description.""" - _static_summary: Optional[str] = None - _static_details: Optional[str] = None + _static_summary: str | None = None + _static_details: str | None = None _metadata_decoded: bool = False - async def static_summary(self) -> Optional[str]: + async def static_summary(self) -> str | None: """Gets the single-line fixed summary for this workflow execution that may appear in UI/CLI. This can be in single-line Temporal markdown format. """ @@ -3097,7 +3063,7 @@ async def static_summary(self) -> Optional[str]: await self._decode_metadata() return self._static_summary - async def static_details(self) -> Optional[str]: + async def static_details(self) -> str | None: """Gets the general fixed details for this workflow execution that may appear in UI/CLI. This can be in Temporal markdown format and can span multiple lines. """ @@ -3227,7 +3193,7 @@ def __init__( self._client = client self._input = input self._next_page_token = input.next_page_token - self._current_page: Optional[Sequence[WorkflowExecution]] = None + self._current_page: Sequence[WorkflowExecution] | None = None self._current_page_index = 0 self._limit = input.limit self._yielded = 0 @@ -3240,16 +3206,16 @@ def current_page_index(self) -> int: return self._current_page_index @property - def current_page(self) -> Optional[Sequence[WorkflowExecution]]: + def current_page(self) -> Sequence[WorkflowExecution] | None: """Current page, if it has been fetched yet.""" return self._current_page @property - def next_page_token(self) -> Optional[bytes]: + def next_page_token(self) -> bytes | None: """Token for the next page request if any.""" return self._next_page_token - async def fetch_next_page(self, *, page_size: Optional[int] = None) -> None: + async def fetch_next_page(self, *, page_size: int | None = None) -> None: """Fetch the next page if any. Args: @@ -3316,8 +3282,8 @@ async def map_histories( *, event_filter_type: WorkflowHistoryEventFilterType = WorkflowHistoryEventFilterType.ALL_EVENT, skip_archival: bool = False, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> AsyncIterator[WorkflowHistory]: """Create an async iterator consuming all workflows and calling :py:meth:`WorkflowHandle.fetch_history` on each one. @@ -3358,9 +3324,7 @@ def run_id(self) -> str: ].workflow_execution_started_event_attributes.original_execution_run_id @staticmethod - def from_json( - workflow_id: str, history: Union[str, Dict[str, Any]] - ) -> WorkflowHistory: + def from_json(workflow_id: str, history: str | dict[str, Any]) -> WorkflowHistory: """Construct a WorkflowHistory from an ID and a json dump of history. This is built to work both with Temporal UI/CLI JSON as well as @@ -3386,7 +3350,7 @@ def to_json(self) -> str: temporalio.api.history.v1.History(events=self.events) ) - def to_json_dict(self) -> Dict[str, Any]: + def to_json_dict(self) -> dict[str, Any]: """Convert this history to JSON-compatible dict. Note, this does not include the workflow ID. @@ -3417,9 +3381,9 @@ def __init__( self._client = client self._input = input self._next_page_token = input.next_page_token - self._current_page: Optional[ - Sequence[temporalio.api.history.v1.HistoryEvent] - ] = None + self._current_page: ( + None | (Sequence[temporalio.api.history.v1.HistoryEvent]) + ) = None self._current_page_index = 0 @property @@ -3432,16 +3396,16 @@ def current_page_index(self) -> int: @property def current_page( self, - ) -> Optional[Sequence[temporalio.api.history.v1.HistoryEvent]]: + ) -> Sequence[temporalio.api.history.v1.HistoryEvent] | None: """Current page, if it has been fetched yet.""" return self._current_page @property - def next_page_token(self) -> Optional[bytes]: + def next_page_token(self) -> bytes | None: """Token for the next page request if any.""" return self._next_page_token - async def fetch_next_page(self, *, page_size: Optional[int] = None) -> None: + async def fetch_next_page(self, *, page_size: int | None = None) -> None: """Fetch the next page if any. Args: @@ -3519,8 +3483,8 @@ def __init__(self, client: Client, id: str) -> None: async def backfill( self, *backfill: ScheduleBackfill, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> None: """Backfill the schedule by going through the specified time periods as if they passed right now. @@ -3545,8 +3509,8 @@ async def backfill( async def delete( self, *, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> None: """Delete this schedule. @@ -3566,8 +3530,8 @@ async def delete( async def describe( self, *, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> ScheduleDescription: """Fetch this schedule's description. @@ -3587,9 +3551,9 @@ async def describe( async def pause( self, *, - note: Optional[str] = None, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + note: str | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> None: """Pause the schedule and set a note. @@ -3611,9 +3575,9 @@ async def pause( async def trigger( self, *, - overlap: Optional[ScheduleOverlapPolicy] = None, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + overlap: ScheduleOverlapPolicy | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> None: """Trigger an action on this schedule to happen immediately. @@ -3635,9 +3599,9 @@ async def trigger( async def unpause( self, *, - note: Optional[str] = None, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + note: str | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> None: """Unpause the schedule and set a note. @@ -3659,30 +3623,30 @@ async def unpause( @overload async def update( self, - updater: Callable[[ScheduleUpdateInput], Optional[ScheduleUpdate]], + updater: Callable[[ScheduleUpdateInput], ScheduleUpdate | None], *, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> None: ... @overload async def update( self, - updater: Callable[[ScheduleUpdateInput], Awaitable[Optional[ScheduleUpdate]]], + updater: Callable[[ScheduleUpdateInput], Awaitable[ScheduleUpdate | None]], *, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> None: ... async def update( self, updater: Callable[ [ScheduleUpdateInput], - Union[Optional[ScheduleUpdate], Awaitable[Optional[ScheduleUpdate]]], + ScheduleUpdate | None | Awaitable[ScheduleUpdate | None], ], *, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> None: """Update a schedule using a callback to build the update from the description. @@ -3738,20 +3702,20 @@ class ScheduleSpec: skip: Sequence[ScheduleCalendarSpec] = dataclasses.field(default_factory=list) """Set of matching calendar times that will be skipped.""" - start_at: Optional[datetime] = None + start_at: datetime | None = None """Time before which any matching times will be skipped.""" - end_at: Optional[datetime] = None + end_at: datetime | None = None """Time after which any matching times will be skipped.""" - jitter: Optional[timedelta] = None + jitter: timedelta | None = None """Jitter to apply each action. An action's scheduled time will be incremented by a random value between 0 and this value if present (but not past the next schedule). """ - time_zone_name: Optional[str] = None + time_zone_name: str | None = None """IANA time zone name, for example ``US/Central``.""" @staticmethod @@ -3777,15 +3741,15 @@ def _from_proto(spec: temporalio.api.schedule.v1.ScheduleSpec) -> ScheduleSpec: ) def _to_proto(self) -> temporalio.api.schedule.v1.ScheduleSpec: - start_time: Optional[google.protobuf.timestamp_pb2.Timestamp] = None + start_time: google.protobuf.timestamp_pb2.Timestamp | None = None if self.start_at: start_time = google.protobuf.timestamp_pb2.Timestamp() start_time.FromDatetime(self.start_at) - end_time: Optional[google.protobuf.timestamp_pb2.Timestamp] = None + end_time: google.protobuf.timestamp_pb2.Timestamp | None = None if self.end_at: end_time = google.protobuf.timestamp_pb2.Timestamp() end_time.FromDatetime(self.end_at) - jitter: Optional[google.protobuf.duration_pb2.Duration] = None + jitter: google.protobuf.duration_pb2.Duration | None = None if self.jitter: jitter = google.protobuf.duration_pb2.Duration() jitter.FromTimedelta(self.jitter) @@ -3882,7 +3846,7 @@ class ScheduleCalendarSpec: """Day of week range to match, 0-6, 0 is Sunday. Default matches all days.""" - comment: Optional[str] = None + comment: str | None = None """Description of this schedule.""" @staticmethod @@ -3923,7 +3887,7 @@ class ScheduleIntervalSpec: every: timedelta """Period to repeat the interval.""" - offset: Optional[timedelta] = None + offset: timedelta | None = None """Fixed offset added to each interval period.""" @staticmethod @@ -3938,7 +3902,7 @@ def _from_proto( def _to_proto(self) -> temporalio.api.schedule.v1.IntervalSpec: interval = google.protobuf.duration_pb2.Duration() interval.FromTimedelta(self.every) - phase: Optional[google.protobuf.duration_pb2.Duration] = None + phase: google.protobuf.duration_pb2.Duration | None = None if self.offset: phase = google.protobuf.duration_pb2.Duration() phase.FromTimedelta(self.offset) @@ -3972,26 +3936,24 @@ class ScheduleActionStartWorkflow(ScheduleAction): """Schedule action to start a workflow.""" workflow: str - args: Union[Sequence[Any], Sequence[temporalio.api.common.v1.Payload]] + args: Sequence[Any] | Sequence[temporalio.api.common.v1.Payload] id: str task_queue: str - execution_timeout: Optional[timedelta] - run_timeout: Optional[timedelta] - task_timeout: Optional[timedelta] - retry_policy: Optional[temporalio.common.RetryPolicy] - memo: Optional[ - Union[Mapping[str, Any], Mapping[str, temporalio.api.common.v1.Payload]] - ] + execution_timeout: timedelta | None + run_timeout: timedelta | None + task_timeout: timedelta | None + retry_policy: temporalio.common.RetryPolicy | None + memo: None | (Mapping[str, Any] | Mapping[str, temporalio.api.common.v1.Payload]) typed_search_attributes: temporalio.common.TypedSearchAttributes untyped_search_attributes: temporalio.common.SearchAttributes """This is deprecated and is only present in case existing untyped attributes already exist for update. This should never be used when creating.""" - static_summary: Optional[Union[str, temporalio.api.common.v1.Payload]] - static_details: Optional[Union[str, temporalio.api.common.v1.Payload]] + static_summary: str | temporalio.api.common.v1.Payload | None + static_details: str | temporalio.api.common.v1.Payload | None priority: temporalio.common.Priority - headers: Optional[Mapping[str, temporalio.api.common.v1.Payload]] + headers: Mapping[str, temporalio.api.common.v1.Payload] | None """ Headers may still be encoded by the payload codec if present. """ @@ -4011,14 +3973,14 @@ def __init__( *, id: str, task_queue: str, - execution_timeout: Optional[timedelta] = None, - run_timeout: Optional[timedelta] = None, - task_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, - memo: Optional[Mapping[str, Any]] = None, + execution_timeout: timedelta | None = None, + run_timeout: timedelta | None = None, + task_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, + memo: Mapping[str, Any] | None = None, typed_search_attributes: temporalio.common.TypedSearchAttributes = temporalio.common.TypedSearchAttributes.empty, - static_summary: Optional[str] = None, - static_details: Optional[str] = None, + static_summary: str | None = None, + static_details: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> None: ... @@ -4031,14 +3993,14 @@ def __init__( *, id: str, task_queue: str, - execution_timeout: Optional[timedelta] = None, - run_timeout: Optional[timedelta] = None, - task_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, - memo: Optional[Mapping[str, Any]] = None, + execution_timeout: timedelta | None = None, + run_timeout: timedelta | None = None, + task_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, + memo: Mapping[str, Any] | None = None, typed_search_attributes: temporalio.common.TypedSearchAttributes = temporalio.common.TypedSearchAttributes.empty, - static_summary: Optional[str] = None, - static_details: Optional[str] = None, + static_summary: str | None = None, + static_details: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> None: ... @@ -4053,14 +4015,14 @@ def __init__( args: Sequence[Any], id: str, task_queue: str, - execution_timeout: Optional[timedelta] = None, - run_timeout: Optional[timedelta] = None, - task_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, - memo: Optional[Mapping[str, Any]] = None, + execution_timeout: timedelta | None = None, + run_timeout: timedelta | None = None, + task_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, + memo: Mapping[str, Any] | None = None, typed_search_attributes: temporalio.common.TypedSearchAttributes = temporalio.common.TypedSearchAttributes.empty, - static_summary: Optional[str] = None, - static_details: Optional[str] = None, + static_summary: str | None = None, + static_details: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> None: ... @@ -4074,14 +4036,14 @@ def __init__( args: Sequence[Any] = [], id: str, task_queue: str, - execution_timeout: Optional[timedelta] = None, - run_timeout: Optional[timedelta] = None, - task_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, - memo: Optional[Mapping[str, Any]] = None, + execution_timeout: timedelta | None = None, + run_timeout: timedelta | None = None, + task_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, + memo: Mapping[str, Any] | None = None, typed_search_attributes: temporalio.common.TypedSearchAttributes = temporalio.common.TypedSearchAttributes.empty, - static_summary: Optional[str] = None, - static_details: Optional[str] = None, + static_summary: str | None = None, + static_details: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> None: ... @@ -4096,23 +4058,23 @@ def __init__( def __init__( self, - workflow: Union[str, Callable[..., Awaitable[Any]]], + workflow: str | Callable[..., Awaitable[Any]], arg: Any = temporalio.common._arg_unset, *, args: Sequence[Any] = [], - id: Optional[str] = None, - task_queue: Optional[str] = None, - execution_timeout: Optional[timedelta] = None, - run_timeout: Optional[timedelta] = None, - task_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, - memo: Optional[Mapping[str, Any]] = None, + id: str | None = None, + task_queue: str | None = None, + execution_timeout: timedelta | None = None, + run_timeout: timedelta | None = None, + task_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, + memo: Mapping[str, Any] | None = None, typed_search_attributes: temporalio.common.TypedSearchAttributes = temporalio.common.TypedSearchAttributes.empty, untyped_search_attributes: temporalio.common.SearchAttributes = {}, - static_summary: Optional[str] = None, - static_details: Optional[str] = None, - headers: Optional[Mapping[str, temporalio.api.common.v1.Payload]] = None, - raw_info: Optional[temporalio.api.workflow.v1.NewWorkflowExecutionInfo] = None, + static_summary: str | None = None, + static_details: str | None = None, + headers: Mapping[str, temporalio.api.common.v1.Payload] | None = None, + raw_info: temporalio.api.workflow.v1.NewWorkflowExecutionInfo | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> None: """Create a start-workflow action. @@ -4214,23 +4176,23 @@ def __init__( async def _to_proto( self, client: Client ) -> temporalio.api.schedule.v1.ScheduleAction: - execution_timeout: Optional[google.protobuf.duration_pb2.Duration] = None + execution_timeout: google.protobuf.duration_pb2.Duration | None = None if self.execution_timeout: execution_timeout = google.protobuf.duration_pb2.Duration() execution_timeout.FromTimedelta(self.execution_timeout) - run_timeout: Optional[google.protobuf.duration_pb2.Duration] = None + run_timeout: google.protobuf.duration_pb2.Duration | None = None if self.run_timeout: run_timeout = google.protobuf.duration_pb2.Duration() run_timeout.FromTimedelta(self.run_timeout) - task_timeout: Optional[google.protobuf.duration_pb2.Duration] = None + task_timeout: google.protobuf.duration_pb2.Duration | None = None if self.task_timeout: task_timeout = google.protobuf.duration_pb2.Duration() task_timeout.FromTimedelta(self.task_timeout) - retry_policy: Optional[temporalio.api.common.v1.RetryPolicy] = None + retry_policy: temporalio.api.common.v1.RetryPolicy | None = None if self.retry_policy: retry_policy = temporalio.api.common.v1.RetryPolicy() self.retry_policy.apply_to_proto(retry_policy) - priority: Optional[temporalio.api.common.v1.Priority] = None + priority: temporalio.api.common.v1.Priority | None = None if self.priority: priority = self.priority._to_proto() data_converter = client.data_converter.with_context( @@ -4369,7 +4331,7 @@ class ScheduleBackfill: This is exclusive """ end_at: datetime - overlap: Optional[ScheduleOverlapPolicy] = None + overlap: ScheduleOverlapPolicy | None = None def _to_proto(self) -> temporalio.api.schedule.v1.BackfillRequest: start_time = google.protobuf.timestamp_pb2.Timestamp() @@ -4433,7 +4395,7 @@ def _to_proto(self) -> temporalio.api.schedule.v1.SchedulePolicies: class ScheduleState: """State of a schedule.""" - note: Optional[str] = None + note: str | None = None """Human readable message for the schedule. The system may overwrite this value on certain conditions like @@ -4584,20 +4546,20 @@ async def memo_value( @overload async def memo_value( - self, key: str, *, type_hint: Type[ParamType] + self, key: str, *, type_hint: type[ParamType] ) -> ParamType: ... @overload async def memo_value( - self, key: str, default: AnyType, *, type_hint: Type[ParamType] - ) -> Union[AnyType, ParamType]: ... + self, key: str, default: AnyType, *, type_hint: type[ParamType] + ) -> AnyType | ParamType: ... async def memo_value( self, key: str, default: Any = temporalio.common._arg_unset, *, - type_hint: Optional[Type] = None, + type_hint: type | None = None, ) -> Any: """Memo value for the given key, optional default, and optional type hint. @@ -4652,7 +4614,7 @@ class ScheduleInfo: created_at: datetime """When the schedule was created.""" - last_updated_at: Optional[datetime] + last_updated_at: datetime | None """When the schedule was last updated.""" @staticmethod @@ -4746,7 +4708,7 @@ class ScheduleUpdate: schedule: Schedule """Schedule to update.""" - search_attributes: Optional[temporalio.common.TypedSearchAttributes] = None + search_attributes: temporalio.common.TypedSearchAttributes | None = None """Search attributes to update.""" @@ -4757,14 +4719,14 @@ class ScheduleListDescription: id: str """ID of the schedule.""" - schedule: Optional[ScheduleListSchedule] + schedule: ScheduleListSchedule | None """Schedule details that can be mutated. This may not be present in older Temporal servers without advanced visibility. """ - info: Optional[ScheduleListInfo] + info: ScheduleListInfo | None """Information about the schedule. This may not be present in older Temporal servers without advanced @@ -4833,20 +4795,20 @@ async def memo_value( @overload async def memo_value( - self, key: str, *, type_hint: Type[ParamType] + self, key: str, *, type_hint: type[ParamType] ) -> ParamType: ... @overload async def memo_value( - self, key: str, default: AnyType, *, type_hint: Type[ParamType] - ) -> Union[AnyType, ParamType]: ... + self, key: str, default: AnyType, *, type_hint: type[ParamType] + ) -> AnyType | ParamType: ... async def memo_value( self, key: str, default: Any = temporalio.common._arg_unset, *, - type_hint: Optional[Type] = None, + type_hint: type | None = None, ) -> Any: """Memo value for the given key, optional default, and optional type hint. @@ -4953,7 +4915,7 @@ def _from_proto( class ScheduleListState: """State of a listed schedule.""" - note: Optional[str] + note: str | None """Human readable message for the schedule. The system may overwrite this value on certain conditions like @@ -4993,7 +4955,7 @@ def __init__( self._client = client self._input = input self._next_page_token = input.next_page_token - self._current_page: Optional[Sequence[ScheduleListDescription]] = None + self._current_page: Sequence[ScheduleListDescription] | None = None self._current_page_index = 0 @property @@ -5004,16 +4966,16 @@ def current_page_index(self) -> int: return self._current_page_index @property - def current_page(self) -> Optional[Sequence[ScheduleListDescription]]: + def current_page(self) -> Sequence[ScheduleListDescription] | None: """Current page, if it has been fetched yet.""" return self._current_page @property - def next_page_token(self) -> Optional[bytes]: + def next_page_token(self) -> bytes | None: """Token for the next page request if any.""" return self._next_page_token - async def fetch_next_page(self, *, page_size: Optional[int] = None) -> None: + async def fetch_next_page(self, *, page_size: int | None = None) -> None: """Fetch the next page if any. Args: @@ -5075,9 +5037,9 @@ def __init__( id: str, workflow_id: str, *, - workflow_run_id: Optional[str] = None, - result_type: Optional[Type] = None, - known_outcome: Optional[temporalio.api.update.v1.Outcome] = None, + workflow_run_id: str | None = None, + result_type: type | None = None, + known_outcome: temporalio.api.update.v1.Outcome | None = None, ): """Create a workflow update handle. @@ -5111,15 +5073,15 @@ def workflow_id(self) -> str: return self._workflow_id @property - def workflow_run_id(self) -> Optional[str]: + def workflow_run_id(self) -> str | None: """If specified, the specific run of the Workflow targeted by this Update.""" return self._workflow_run_id async def result( self, *, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> LocalReturnType: """Wait for and return the result of the update. The result may already be known in which case no network call is made. Otherwise the result will be polled for until it is returned. @@ -5162,8 +5124,8 @@ async def result( async def _poll_until_outcome( self, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> None: if self._known_outcome: return @@ -5256,13 +5218,13 @@ def new_execution_run_id(self) -> str: class WorkflowQueryRejectedError(temporalio.exceptions.TemporalError): """Error that occurs when a query was rejected.""" - def __init__(self, status: Optional[WorkflowExecutionStatus]) -> None: + def __init__(self, status: WorkflowExecutionStatus | None) -> None: """Create workflow query rejected error.""" super().__init__(f"Query rejected, status: {status}") self._status = status @property - def status(self) -> Optional[WorkflowExecutionStatus]: + def status(self) -> WorkflowExecutionStatus | None: """Get workflow execution status causing rejection.""" return self._status @@ -5317,7 +5279,7 @@ def __init__(self) -> None: class AsyncActivityCancelledError(temporalio.exceptions.TemporalError): """Error that occurs when async activity attempted heartbeat but was cancelled.""" - def __init__(self, details: Optional[ActivityCancellationDetails] = None) -> None: + def __init__(self, details: ActivityCancellationDetails | None = None) -> None: """Create async activity cancelled error.""" super().__init__("Activity cancelled") self.details = details @@ -5339,36 +5301,34 @@ class StartWorkflowInput: args: Sequence[Any] id: str task_queue: str - execution_timeout: Optional[timedelta] - run_timeout: Optional[timedelta] - task_timeout: Optional[timedelta] + execution_timeout: timedelta | None + run_timeout: timedelta | None + task_timeout: timedelta | None id_reuse_policy: temporalio.common.WorkflowIDReusePolicy id_conflict_policy: temporalio.common.WorkflowIDConflictPolicy - retry_policy: Optional[temporalio.common.RetryPolicy] + retry_policy: temporalio.common.RetryPolicy | None cron_schedule: str - memo: Optional[Mapping[str, Any]] - search_attributes: Optional[ - Union[ - temporalio.common.SearchAttributes, temporalio.common.TypedSearchAttributes - ] - ] - start_delay: Optional[timedelta] + memo: Mapping[str, Any] | None + search_attributes: None | ( + temporalio.common.SearchAttributes | temporalio.common.TypedSearchAttributes + ) + start_delay: timedelta | None headers: Mapping[str, temporalio.api.common.v1.Payload] - start_signal: Optional[str] + start_signal: str | None start_signal_args: Sequence[Any] - static_summary: Optional[str] - static_details: Optional[str] + static_summary: str | None + static_details: str | None # Type may be absent - ret_type: Optional[Type] - rpc_metadata: Mapping[str, Union[str, bytes]] - rpc_timeout: Optional[timedelta] + ret_type: type | None + rpc_metadata: Mapping[str, str | bytes] + rpc_timeout: timedelta | None request_eager_start: bool priority: temporalio.common.Priority # The following options are experimental and unstable. callbacks: Sequence[Callback] workflow_event_links: Sequence[temporalio.api.common.v1.Link.WorkflowEvent] - request_id: Optional[str] - versioning_override: Optional[temporalio.common.VersioningOverride] = None + request_id: str | None + versioning_override: temporalio.common.VersioningOverride | None = None @dataclass @@ -5376,10 +5336,10 @@ class CancelWorkflowInput: """Input for :py:meth:`OutboundInterceptor.cancel_workflow`.""" id: str - run_id: Optional[str] - first_execution_run_id: Optional[str] - rpc_metadata: Mapping[str, Union[str, bytes]] - rpc_timeout: Optional[timedelta] + run_id: str | None + first_execution_run_id: str | None + rpc_metadata: Mapping[str, str | bytes] + rpc_timeout: timedelta | None @dataclass @@ -5387,9 +5347,9 @@ class DescribeWorkflowInput: """Input for :py:meth:`OutboundInterceptor.describe_workflow`.""" id: str - run_id: Optional[str] - rpc_metadata: Mapping[str, Union[str, bytes]] - rpc_timeout: Optional[timedelta] + run_id: str | None + rpc_metadata: Mapping[str, str | bytes] + rpc_timeout: timedelta | None @dataclass @@ -5397,35 +5357,35 @@ class FetchWorkflowHistoryEventsInput: """Input for :py:meth:`OutboundInterceptor.fetch_workflow_history_events`.""" id: str - run_id: Optional[str] - page_size: Optional[int] - next_page_token: Optional[bytes] + run_id: str | None + page_size: int | None + next_page_token: bytes | None wait_new_event: bool event_filter_type: WorkflowHistoryEventFilterType skip_archival: bool - rpc_metadata: Mapping[str, Union[str, bytes]] - rpc_timeout: Optional[timedelta] + rpc_metadata: Mapping[str, str | bytes] + rpc_timeout: timedelta | None @dataclass class ListWorkflowsInput: """Input for :py:meth:`OutboundInterceptor.list_workflows`.""" - query: Optional[str] + query: str | None page_size: int - next_page_token: Optional[bytes] - rpc_metadata: Mapping[str, Union[str, bytes]] - rpc_timeout: Optional[timedelta] - limit: Optional[int] + next_page_token: bytes | None + rpc_metadata: Mapping[str, str | bytes] + rpc_timeout: timedelta | None + limit: int | None @dataclass class CountWorkflowsInput: """Input for :py:meth:`OutboundInterceptor.count_workflows`.""" - query: Optional[str] - rpc_metadata: Mapping[str, Union[str, bytes]] - rpc_timeout: Optional[timedelta] + query: str | None + rpc_metadata: Mapping[str, str | bytes] + rpc_timeout: timedelta | None @dataclass @@ -5433,15 +5393,15 @@ class QueryWorkflowInput: """Input for :py:meth:`OutboundInterceptor.query_workflow`.""" id: str - run_id: Optional[str] + run_id: str | None query: str args: Sequence[Any] - reject_condition: Optional[temporalio.common.QueryRejectCondition] + reject_condition: temporalio.common.QueryRejectCondition | None headers: Mapping[str, temporalio.api.common.v1.Payload] # Type may be absent - ret_type: Optional[Type] - rpc_metadata: Mapping[str, Union[str, bytes]] - rpc_timeout: Optional[timedelta] + ret_type: type | None + rpc_metadata: Mapping[str, str | bytes] + rpc_timeout: timedelta | None @dataclass @@ -5449,12 +5409,12 @@ class SignalWorkflowInput: """Input for :py:meth:`OutboundInterceptor.signal_workflow`.""" id: str - run_id: Optional[str] + run_id: str | None signal: str args: Sequence[Any] headers: Mapping[str, temporalio.api.common.v1.Payload] - rpc_metadata: Mapping[str, Union[str, bytes]] - rpc_timeout: Optional[timedelta] + rpc_metadata: Mapping[str, str | bytes] + rpc_timeout: timedelta | None @dataclass @@ -5462,12 +5422,12 @@ class TerminateWorkflowInput: """Input for :py:meth:`OutboundInterceptor.terminate_workflow`.""" id: str - run_id: Optional[str] - first_execution_run_id: Optional[str] + run_id: str | None + first_execution_run_id: str | None args: Sequence[Any] - reason: Optional[str] - rpc_metadata: Mapping[str, Union[str, bytes]] - rpc_timeout: Optional[timedelta] + reason: str | None + rpc_metadata: Mapping[str, str | bytes] + rpc_timeout: timedelta | None @dataclass @@ -5475,30 +5435,30 @@ class StartWorkflowUpdateInput: """Input for :py:meth:`OutboundInterceptor.start_workflow_update`.""" id: str - run_id: Optional[str] - first_execution_run_id: Optional[str] - update_id: Optional[str] + run_id: str | None + first_execution_run_id: str | None + update_id: str | None update: str args: Sequence[Any] wait_for_stage: WorkflowUpdateStage headers: Mapping[str, temporalio.api.common.v1.Payload] - ret_type: Optional[Type] - rpc_metadata: Mapping[str, Union[str, bytes]] - rpc_timeout: Optional[timedelta] + ret_type: type | None + rpc_metadata: Mapping[str, str | bytes] + rpc_timeout: timedelta | None @dataclass class UpdateWithStartUpdateWorkflowInput: """Update input for :py:meth:`OutboundInterceptor.start_update_with_start_workflow`.""" - update_id: Optional[str] + update_id: str | None update: str args: Sequence[Any] wait_for_stage: WorkflowUpdateStage headers: Mapping[str, temporalio.api.common.v1.Payload] - ret_type: Optional[Type] - rpc_metadata: Mapping[str, Union[str, bytes]] - rpc_timeout: Optional[timedelta] + ret_type: type | None + rpc_metadata: Mapping[str, str | bytes] + rpc_timeout: timedelta | None @dataclass @@ -5512,29 +5472,27 @@ class UpdateWithStartStartWorkflowInput: args: Sequence[Any] id: str task_queue: str - execution_timeout: Optional[timedelta] - run_timeout: Optional[timedelta] - task_timeout: Optional[timedelta] + execution_timeout: timedelta | None + run_timeout: timedelta | None + task_timeout: timedelta | None id_reuse_policy: temporalio.common.WorkflowIDReusePolicy id_conflict_policy: temporalio.common.WorkflowIDConflictPolicy - retry_policy: Optional[temporalio.common.RetryPolicy] + retry_policy: temporalio.common.RetryPolicy | None cron_schedule: str - memo: Optional[Mapping[str, Any]] - search_attributes: Optional[ - Union[ - temporalio.common.SearchAttributes, temporalio.common.TypedSearchAttributes - ] - ] - start_delay: Optional[timedelta] + memo: Mapping[str, Any] | None + search_attributes: None | ( + temporalio.common.SearchAttributes | temporalio.common.TypedSearchAttributes + ) + start_delay: timedelta | None headers: Mapping[str, temporalio.api.common.v1.Payload] - static_summary: Optional[str] - static_details: Optional[str] + static_summary: str | None + static_details: str | None # Type may be absent - ret_type: Optional[Type] - rpc_metadata: Mapping[str, Union[str, bytes]] - rpc_timeout: Optional[timedelta] + ret_type: type | None + rpc_metadata: Mapping[str, str | bytes] + rpc_timeout: timedelta | None priority: temporalio.common.Priority - versioning_override: Optional[temporalio.common.VersioningOverride] = None + versioning_override: temporalio.common.VersioningOverride | None = None @dataclass @@ -5553,45 +5511,45 @@ class StartWorkflowUpdateWithStartInput: class HeartbeatAsyncActivityInput: """Input for :py:meth:`OutboundInterceptor.heartbeat_async_activity`.""" - id_or_token: Union[AsyncActivityIDReference, bytes] + id_or_token: AsyncActivityIDReference | bytes details: Sequence[Any] - rpc_metadata: Mapping[str, Union[str, bytes]] - rpc_timeout: Optional[timedelta] - data_converter_override: Optional[DataConverter] = None + rpc_metadata: Mapping[str, str | bytes] + rpc_timeout: timedelta | None + data_converter_override: DataConverter | None = None @dataclass class CompleteAsyncActivityInput: """Input for :py:meth:`OutboundInterceptor.complete_async_activity`.""" - id_or_token: Union[AsyncActivityIDReference, bytes] - result: Optional[Any] - rpc_metadata: Mapping[str, Union[str, bytes]] - rpc_timeout: Optional[timedelta] - data_converter_override: Optional[DataConverter] = None + id_or_token: AsyncActivityIDReference | bytes + result: Any | None + rpc_metadata: Mapping[str, str | bytes] + rpc_timeout: timedelta | None + data_converter_override: DataConverter | None = None @dataclass class FailAsyncActivityInput: """Input for :py:meth:`OutboundInterceptor.fail_async_activity`.""" - id_or_token: Union[AsyncActivityIDReference, bytes] + id_or_token: AsyncActivityIDReference | bytes error: Exception last_heartbeat_details: Sequence[Any] - rpc_metadata: Mapping[str, Union[str, bytes]] - rpc_timeout: Optional[timedelta] - data_converter_override: Optional[DataConverter] = None + rpc_metadata: Mapping[str, str | bytes] + rpc_timeout: timedelta | None + data_converter_override: DataConverter | None = None @dataclass class ReportCancellationAsyncActivityInput: """Input for :py:meth:`OutboundInterceptor.report_cancellation_async_activity`.""" - id_or_token: Union[AsyncActivityIDReference, bytes] + id_or_token: AsyncActivityIDReference | bytes details: Sequence[Any] - rpc_metadata: Mapping[str, Union[str, bytes]] - rpc_timeout: Optional[timedelta] - data_converter_override: Optional[DataConverter] = None + rpc_metadata: Mapping[str, str | bytes] + rpc_timeout: timedelta | None + data_converter_override: DataConverter | None = None @dataclass @@ -5602,14 +5560,12 @@ class CreateScheduleInput: schedule: Schedule trigger_immediately: bool backfill: Sequence[ScheduleBackfill] - memo: Optional[Mapping[str, Any]] - search_attributes: Optional[ - Union[ - temporalio.common.SearchAttributes, temporalio.common.TypedSearchAttributes - ] - ] - rpc_metadata: Mapping[str, Union[str, bytes]] - rpc_timeout: Optional[timedelta] + memo: Mapping[str, Any] | None + search_attributes: None | ( + temporalio.common.SearchAttributes | temporalio.common.TypedSearchAttributes + ) + rpc_metadata: Mapping[str, str | bytes] + rpc_timeout: timedelta | None @dataclass @@ -5617,10 +5573,10 @@ class ListSchedulesInput: """Input for :py:meth:`OutboundInterceptor.list_schedules`.""" page_size: int - next_page_token: Optional[bytes] - rpc_metadata: Mapping[str, Union[str, bytes]] - rpc_timeout: Optional[timedelta] - query: Optional[str] = None + next_page_token: bytes | None + rpc_metadata: Mapping[str, str | bytes] + rpc_timeout: timedelta | None + query: str | None = None @dataclass @@ -5629,8 +5585,8 @@ class BackfillScheduleInput: id: str backfills: Sequence[ScheduleBackfill] - rpc_metadata: Mapping[str, Union[str, bytes]] - rpc_timeout: Optional[timedelta] + rpc_metadata: Mapping[str, str | bytes] + rpc_timeout: timedelta | None @dataclass @@ -5638,8 +5594,8 @@ class DeleteScheduleInput: """Input for :py:meth:`OutboundInterceptor.delete_schedule`.""" id: str - rpc_metadata: Mapping[str, Union[str, bytes]] - rpc_timeout: Optional[timedelta] + rpc_metadata: Mapping[str, str | bytes] + rpc_timeout: timedelta | None @dataclass @@ -5647,8 +5603,8 @@ class DescribeScheduleInput: """Input for :py:meth:`OutboundInterceptor.describe_schedule`.""" id: str - rpc_metadata: Mapping[str, Union[str, bytes]] - rpc_timeout: Optional[timedelta] + rpc_metadata: Mapping[str, str | bytes] + rpc_timeout: timedelta | None @dataclass @@ -5656,9 +5612,9 @@ class PauseScheduleInput: """Input for :py:meth:`OutboundInterceptor.pause_schedule`.""" id: str - note: Optional[str] - rpc_metadata: Mapping[str, Union[str, bytes]] - rpc_timeout: Optional[timedelta] + note: str | None + rpc_metadata: Mapping[str, str | bytes] + rpc_timeout: timedelta | None @dataclass @@ -5666,9 +5622,9 @@ class TriggerScheduleInput: """Input for :py:meth:`OutboundInterceptor.trigger_schedule`.""" id: str - overlap: Optional[ScheduleOverlapPolicy] - rpc_metadata: Mapping[str, Union[str, bytes]] - rpc_timeout: Optional[timedelta] + overlap: ScheduleOverlapPolicy | None + rpc_metadata: Mapping[str, str | bytes] + rpc_timeout: timedelta | None @dataclass @@ -5676,9 +5632,9 @@ class UnpauseScheduleInput: """Input for :py:meth:`OutboundInterceptor.unpause_schedule`.""" id: str - note: Optional[str] - rpc_metadata: Mapping[str, Union[str, bytes]] - rpc_timeout: Optional[timedelta] + note: str | None + rpc_metadata: Mapping[str, str | bytes] + rpc_timeout: timedelta | None @dataclass @@ -5688,10 +5644,10 @@ class UpdateScheduleInput: id: str updater: Callable[ [ScheduleUpdateInput], - Union[Optional[ScheduleUpdate], Awaitable[Optional[ScheduleUpdate]]], + ScheduleUpdate | None | Awaitable[ScheduleUpdate | None], ] - rpc_metadata: Mapping[str, Union[str, bytes]] - rpc_timeout: Optional[timedelta] + rpc_metadata: Mapping[str, str | bytes] + rpc_timeout: timedelta | None @dataclass @@ -5700,8 +5656,8 @@ class UpdateWorkerBuildIdCompatibilityInput: task_queue: str operation: BuildIdOp - rpc_metadata: Mapping[str, Union[str, bytes]] - rpc_timeout: Optional[timedelta] + rpc_metadata: Mapping[str, str | bytes] + rpc_timeout: timedelta | None @dataclass @@ -5709,9 +5665,9 @@ class GetWorkerBuildIdCompatibilityInput: """Input for :py:meth:`OutboundInterceptor.get_worker_build_id_compatibility`.""" task_queue: str - max_sets: Optional[int] - rpc_metadata: Mapping[str, Union[str, bytes]] - rpc_timeout: Optional[timedelta] + max_sets: int | None + rpc_metadata: Mapping[str, str | bytes] + rpc_timeout: timedelta | None @dataclass @@ -5720,9 +5676,9 @@ class GetWorkerTaskReachabilityInput: build_ids: Sequence[str] task_queues: Sequence[str] - reachability: Optional[TaskReachabilityType] - rpc_metadata: Mapping[str, Union[str, bytes]] - rpc_timeout: Optional[timedelta] + reachability: TaskReachabilityType | None + rpc_metadata: Mapping[str, str | bytes] + rpc_timeout: timedelta | None @dataclass @@ -5911,19 +5867,19 @@ def __init__(self, client: Client) -> None: # type: ignore async def start_workflow( self, input: StartWorkflowInput ) -> WorkflowHandle[Any, Any]: - req: Union[ - temporalio.api.workflowservice.v1.StartWorkflowExecutionRequest, - temporalio.api.workflowservice.v1.SignalWithStartWorkflowExecutionRequest, - ] + req: ( + temporalio.api.workflowservice.v1.StartWorkflowExecutionRequest + | temporalio.api.workflowservice.v1.SignalWithStartWorkflowExecutionRequest + ) if input.start_signal is not None: req = await self._build_signal_with_start_workflow_execution_request(input) else: req = await self._build_start_workflow_execution_request(input) - resp: Union[ - temporalio.api.workflowservice.v1.StartWorkflowExecutionResponse, - temporalio.api.workflowservice.v1.SignalWithStartWorkflowExecutionResponse, - ] + resp: ( + temporalio.api.workflowservice.v1.StartWorkflowExecutionResponse + | temporalio.api.workflowservice.v1.SignalWithStartWorkflowExecutionResponse + ) first_execution_run_id = None eagerly_started = False try: @@ -6032,11 +5988,11 @@ async def _build_update_with_start_start_workflow_execution_request( async def _populate_start_workflow_execution_request( self, - req: Union[ - temporalio.api.workflowservice.v1.StartWorkflowExecutionRequest, - temporalio.api.workflowservice.v1.SignalWithStartWorkflowExecutionRequest, - ], - input: Union[StartWorkflowInput, UpdateWithStartStartWorkflowInput], + req: ( + temporalio.api.workflowservice.v1.StartWorkflowExecutionRequest + | temporalio.api.workflowservice.v1.SignalWithStartWorkflowExecutionRequest + ), + input: StartWorkflowInput | UpdateWithStartStartWorkflowInput, ) -> None: data_converter = self._client.data_converter.with_context( WorkflowSerializationContext( @@ -6308,7 +6264,7 @@ async def start_workflow_update( async def _build_update_workflow_execution_request( self, - input: Union[StartWorkflowUpdateInput, UpdateWithStartUpdateWorkflowInput], + input: StartWorkflowUpdateInput | UpdateWithStartUpdateWorkflowInput, workflow_id: str, ) -> temporalio.api.workflowservice.v1.UpdateWorkflowExecutionRequest: data_converter = self._client.data_converter.with_context( @@ -6368,7 +6324,7 @@ def on_start( input._on_start(start_response) seen_start = True - err: Optional[BaseException] = None + err: BaseException | None = None try: return await self._start_workflow_update_with_start( @@ -6676,7 +6632,7 @@ async def create_schedule(self, input: CreateScheduleInput) -> ScheduleHandle: "Must set limited actions to true if there are remaining actions set" ) - initial_patch: Optional[temporalio.api.schedule.v1.SchedulePatch] = None + initial_patch: temporalio.api.schedule.v1.SchedulePatch | None = None if input.trigger_immediately or input.backfill: initial_patch = temporalio.api.schedule.v1.SchedulePatch( trigger_immediately=temporalio.api.schedule.v1.TriggerImmediatelyRequest( @@ -6919,8 +6875,8 @@ async def get_worker_task_reachability( async def _apply_headers( self, - source: Optional[Mapping[str, temporalio.api.common.v1.Payload]], - dest: MessageMap[Text, temporalio.api.common.v1.Payload], + source: Mapping[str, temporalio.api.common.v1.Payload] | None, + dest: MessageMap[str, temporalio.api.common.v1.Payload], ) -> None: await _apply_headers( source, @@ -6932,10 +6888,10 @@ async def _apply_headers( async def _apply_headers( - source: Optional[Mapping[str, temporalio.api.common.v1.Payload]], - dest: MessageMap[Text, temporalio.api.common.v1.Payload], + source: Mapping[str, temporalio.api.common.v1.Payload] | None, + dest: MessageMap[str, temporalio.api.common.v1.Payload], encode_headers: bool, - codec: Optional[temporalio.converter.PayloadCodec], + codec: temporalio.converter.PayloadCodec | None, ) -> None: if source is None: return @@ -6947,7 +6903,7 @@ async def _apply_headers( def _history_from_json( - history: Union[str, Dict[str, Any]], + history: str | dict[str, Any], ) -> temporalio.api.history.v1.History: if isinstance(history, str): history = json.loads(history) @@ -7021,7 +6977,7 @@ def _history_from_json( _pascal_case_match = re.compile("([A-Z]+)") -def _fix_history_failure(parent: Dict[str, Any], *attrs: str) -> None: +def _fix_history_failure(parent: dict[str, Any], *attrs: str) -> None: _fix_history_enum( "TIMEOUT_TYPE", parent, *attrs, "timeoutFailureInfo", "timeoutType" ) @@ -7047,7 +7003,7 @@ def _fix_history_failure(parent: Dict[str, Any], *attrs: str) -> None: _fix_history_failure(parent, "cause") -def _fix_history_enum(prefix: str, parent: Dict[str, Any], *attrs: str) -> None: +def _fix_history_enum(prefix: str, parent: dict[str, Any], *attrs: str) -> None: # If the attr is "*", we need to handle all dict children if attrs[0] == "*": for child in parent.values(): @@ -7275,7 +7231,7 @@ class BuildIdReachability: is an empty list, the Build ID is not reachable on that queue. """ - unretrieved_task_queues: FrozenSet[str] + unretrieved_task_queues: frozenset[str] """If any Task Queues could not be retrieved because the server limits the number that can be queried at once, they will be listed here. """ @@ -7355,17 +7311,17 @@ class CloudOperationsClient: @staticmethod async def connect( *, - api_key: Optional[str] = None, - version: Optional[str] = None, + api_key: str | None = None, + version: str | None = None, target_host: str = "saas-api.tmprl.cloud:443", - tls: Union[bool, TLSConfig] = True, - retry_config: Optional[RetryConfig] = None, - keep_alive_config: Optional[KeepAliveConfig] = KeepAliveConfig.default, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - identity: Optional[str] = None, + tls: bool | TLSConfig = True, + retry_config: RetryConfig | None = None, + keep_alive_config: KeepAliveConfig | None = KeepAliveConfig.default, + rpc_metadata: Mapping[str, str | bytes] = {}, + identity: str | None = None, lazy: bool = False, - runtime: Optional[temporalio.runtime.Runtime] = None, - http_connect_proxy_config: Optional[HttpConnectProxyConfig] = None, + runtime: temporalio.runtime.Runtime | None = None, + http_connect_proxy_config: HttpConnectProxyConfig | None = None, ) -> CloudOperationsClient: """Connect to a Temporal Cloud Operations API. @@ -7453,7 +7409,7 @@ def identity(self) -> str: return self._service_client.config.identity @property - def rpc_metadata(self) -> Mapping[str, Union[str, bytes]]: + def rpc_metadata(self) -> Mapping[str, str | bytes]: """Headers for every call made by this client. Do not use mutate this mapping. Rather, set this property with an @@ -7463,7 +7419,7 @@ def rpc_metadata(self) -> Mapping[str, Union[str, bytes]]: return self.service_client.config.rpc_metadata @rpc_metadata.setter - def rpc_metadata(self, value: Mapping[str, Union[str, bytes]]) -> None: + def rpc_metadata(self, value: Mapping[str, str | bytes]) -> None: """Update the headers for this client. Do not mutate this mapping after set. Rather, set an entirely new @@ -7475,12 +7431,12 @@ def rpc_metadata(self, value: Mapping[str, Union[str, bytes]]) -> None: self.service_client.update_rpc_metadata(value) @property - def api_key(self) -> Optional[str]: + def api_key(self) -> str | None: """API key for every call made by this client.""" return self.service_client.config.api_key @api_key.setter - def api_key(self, value: Optional[str]) -> None: + def api_key(self, value: str | None) -> None: """Update the API key for this client. This is only set if RPCmetadata doesn't already have an "authorization" @@ -7497,9 +7453,9 @@ def api_key(self, value: Optional[str]) -> None: async def _encode_user_metadata( converter: temporalio.converter.DataConverter, - summary: Optional[Union[str, temporalio.api.common.v1.Payload]], - details: Optional[Union[str, temporalio.api.common.v1.Payload]], -) -> Optional[temporalio.api.sdk.v1.UserMetadata]: + summary: str | temporalio.api.common.v1.Payload | None, + details: str | temporalio.api.common.v1.Payload | None, +) -> temporalio.api.sdk.v1.UserMetadata | None: if summary is None and details is None: return None enc_summary = None @@ -7519,8 +7475,8 @@ async def _encode_user_metadata( async def _decode_user_metadata( converter: temporalio.converter.DataConverter, - metadata: Optional[temporalio.api.sdk.v1.UserMetadata], -) -> Tuple[Optional[str], Optional[str]]: + metadata: temporalio.api.sdk.v1.UserMetadata | None, +) -> tuple[str | None, str | None]: """Returns (summary, details)""" if metadata is None: return None, None diff --git a/temporalio/common.py b/temporalio/common.py index 1975776cb..810f5851e 100644 --- a/temporalio/common.py +++ b/temporalio/common.py @@ -6,31 +6,29 @@ import types import warnings from abc import ABC, abstractmethod +from collections.abc import Callable, Collection, Iterator, Mapping, Sequence from dataclasses import dataclass from datetime import datetime, timedelta from enum import IntEnum from typing import ( Any, - Callable, ClassVar, - Collection, Generic, - Iterator, List, - Mapping, Optional, - Sequence, Text, Tuple, Type, + TypeAlias, TypeVar, Union, + get_origin, get_type_hints, overload, ) import google.protobuf.internal.containers -from typing_extensions import NamedTuple, Self, TypeAlias, get_origin +from typing_extensions import NamedTuple, Self import temporalio.api.common.v1 import temporalio.api.deployment.v1 @@ -51,7 +49,7 @@ class RetryPolicy: interval. Default 2.0. """ - maximum_interval: Optional[timedelta] = None + maximum_interval: timedelta | None = None """Maximum backoff interval between retries. Default 100x :py:attr:`initial_interval`. """ @@ -62,7 +60,7 @@ class RetryPolicy: If 0, the default, there is no maximum. """ - non_retryable_error_types: Optional[Sequence[str]] = None + non_retryable_error_types: Sequence[str] | None = None """List of error types that are not retryable.""" @staticmethod @@ -201,7 +199,7 @@ def __setstate__(self, state: object) -> None: # are not sending lists each time but maybe accidentally sending a string (which # is a sequence) SearchAttributeValues: TypeAlias = Union[ - List[str], List[int], List[float], List[bool], List[datetime] + list[str], list[int], list[float], list[bool], list[datetime] ] SearchAttributes: TypeAlias = Mapping[str, SearchAttributeValues] @@ -247,7 +245,7 @@ def indexed_value_type(self) -> SearchAttributeIndexedValueType: @property @abstractmethod - def value_type(self) -> Type[SearchAttributeValueType]: + def value_type(self) -> type[SearchAttributeValueType]: """Get the Python type of value for the key. This may contain generics which cannot be used in ``isinstance``. @@ -256,7 +254,7 @@ def value_type(self) -> Type[SearchAttributeValueType]: ... @property - def origin_value_type(self) -> Type: + def origin_value_type(self) -> type: """Get the Python type of value for the key without generics.""" return get_origin(self.value_type) or self.value_type @@ -340,9 +338,7 @@ def for_keyword_list(name: str) -> SearchAttributeKey[Sequence[str]]: ) @staticmethod - def _from_metadata_type( - name: str, metadata_type: str - ) -> Optional[SearchAttributeKey]: + def _from_metadata_type(name: str, metadata_type: str) -> SearchAttributeKey | None: if metadata_type == "Text": return SearchAttributeKey.for_text(name) elif metadata_type == "Keyword": @@ -362,7 +358,7 @@ def _from_metadata_type( @staticmethod def _guess_from_untyped_values( name: str, vals: SearchAttributeValues - ) -> Optional[SearchAttributeKey]: + ) -> SearchAttributeKey | None: if not vals: return None elif len(vals) > 1: @@ -386,7 +382,7 @@ class _SearchAttributeKey(SearchAttributeKey[SearchAttributeValueType]): _name: str _indexed_value_type: SearchAttributeIndexedValueType # No supported way in Python to derive this, so we're setting manually - _value_type: Type[SearchAttributeValueType] + _value_type: type[SearchAttributeValueType] @property def name(self) -> str: @@ -397,7 +393,7 @@ def indexed_value_type(self) -> SearchAttributeIndexedValueType: return self._indexed_value_type @property - def value_type(self) -> Type[SearchAttributeValueType]: + def value_type(self) -> type[SearchAttributeValueType]: return self._value_type @@ -419,7 +415,7 @@ def key(self) -> SearchAttributeKey[SearchAttributeValueType]: @property @abstractmethod - def value(self) -> Optional[SearchAttributeValueType]: + def value(self) -> SearchAttributeValueType | None: """Value that is being set or ``None`` if being unset.""" ... @@ -427,14 +423,14 @@ def value(self) -> Optional[SearchAttributeValueType]: @dataclass(frozen=True) class _SearchAttributeUpdate(SearchAttributeUpdate[SearchAttributeValueType]): _key: SearchAttributeKey[SearchAttributeValueType] - _value: Optional[SearchAttributeValueType] + _value: SearchAttributeValueType | None @property def key(self) -> SearchAttributeKey[SearchAttributeValueType]: return self._key @property - def value(self) -> Optional[SearchAttributeValueType]: + def value(self) -> SearchAttributeValueType | None: return self._value @@ -501,19 +497,19 @@ def __contains__(self, key: object) -> bool: @overload def get( self, key: SearchAttributeKey[SearchAttributeValueType] - ) -> Optional[SearchAttributeValueType]: ... + ) -> SearchAttributeValueType | None: ... @overload def get( self, key: SearchAttributeKey[SearchAttributeValueType], default: temporalio.types.AnyType, - ) -> Union[SearchAttributeValueType, temporalio.types.AnyType]: ... + ) -> SearchAttributeValueType | temporalio.types.AnyType: ... def get( self, key: SearchAttributeKey[SearchAttributeValueType], - default: Optional[Any] = None, + default: Any | None = None, ) -> Any: """Get an attribute value for a key (or default). This is similar to dict.get. @@ -549,7 +545,7 @@ def updated(self, *search_attributes: SearchAttributePair) -> TypedSearchAttribu def _warn_on_deprecated_search_attributes( - attributes: Optional[Union[SearchAttributes, Any]], + attributes: SearchAttributes | Any | None, stack_level: int = 2, ) -> None: if attributes and isinstance(attributes, Mapping): @@ -571,7 +567,7 @@ class MetricMeter(ABC): @abstractmethod def create_counter( - self, name: str, description: Optional[str] = None, unit: Optional[str] = None + self, name: str, description: str | None = None, unit: str | None = None ) -> MetricCounter: """Create a counter metric for adding values. @@ -587,7 +583,7 @@ def create_counter( @abstractmethod def create_histogram( - self, name: str, description: Optional[str] = None, unit: Optional[str] = None + self, name: str, description: str | None = None, unit: str | None = None ) -> MetricHistogram: """Create a histogram metric for recording values. @@ -603,7 +599,7 @@ def create_histogram( @abstractmethod def create_histogram_float( - self, name: str, description: Optional[str] = None, unit: Optional[str] = None + self, name: str, description: str | None = None, unit: str | None = None ) -> MetricHistogramFloat: """Create a histogram metric for recording values. @@ -619,7 +615,7 @@ def create_histogram_float( @abstractmethod def create_histogram_timedelta( - self, name: str, description: Optional[str] = None, unit: Optional[str] = None + self, name: str, description: str | None = None, unit: str | None = None ) -> MetricHistogramTimedelta: """Create a histogram metric for recording values. @@ -638,7 +634,7 @@ def create_histogram_timedelta( @abstractmethod def create_gauge( - self, name: str, description: Optional[str] = None, unit: Optional[str] = None + self, name: str, description: str | None = None, unit: str | None = None ) -> MetricGauge: """Create a gauge metric for setting values. @@ -654,7 +650,7 @@ def create_gauge( @abstractmethod def create_gauge_float( - self, name: str, description: Optional[str] = None, unit: Optional[str] = None + self, name: str, description: str | None = None, unit: str | None = None ) -> MetricGaugeFloat: """Create a gauge metric for setting values. @@ -699,13 +695,13 @@ def name(self) -> str: @property @abstractmethod - def description(self) -> Optional[str]: + def description(self) -> str | None: """Description for the metric if any.""" ... @property @abstractmethod - def unit(self) -> Optional[str]: + def unit(self) -> str | None: """Unit for the metric if any.""" ... @@ -734,7 +730,7 @@ class MetricCounter(MetricCommon): @abstractmethod def add( - self, value: int, additional_attributes: Optional[MetricAttributes] = None + self, value: int, additional_attributes: MetricAttributes | None = None ) -> None: """Add a value to the counter. @@ -755,7 +751,7 @@ class MetricHistogram(MetricCommon): @abstractmethod def record( - self, value: int, additional_attributes: Optional[MetricAttributes] = None + self, value: int, additional_attributes: MetricAttributes | None = None ) -> None: """Record a value on the histogram. @@ -776,7 +772,7 @@ class MetricHistogramFloat(MetricCommon): @abstractmethod def record( - self, value: float, additional_attributes: Optional[MetricAttributes] = None + self, value: float, additional_attributes: MetricAttributes | None = None ) -> None: """Record a value on the histogram. @@ -797,7 +793,7 @@ class MetricHistogramTimedelta(MetricCommon): @abstractmethod def record( - self, value: timedelta, additional_attributes: Optional[MetricAttributes] = None + self, value: timedelta, additional_attributes: MetricAttributes | None = None ) -> None: """Record a value on the histogram. @@ -820,7 +816,7 @@ class MetricGauge(MetricCommon): @abstractmethod def set( - self, value: int, additional_attributes: Optional[MetricAttributes] = None + self, value: int, additional_attributes: MetricAttributes | None = None ) -> None: """Set a value on the gauge. @@ -841,7 +837,7 @@ class MetricGaugeFloat(MetricCommon): @abstractmethod def set( - self, value: float, additional_attributes: Optional[MetricAttributes] = None + self, value: float, additional_attributes: MetricAttributes | None = None ) -> None: """Set a value on the gauge. @@ -859,32 +855,32 @@ def set( class _NoopMetricMeter(MetricMeter): def create_counter( - self, name: str, description: Optional[str] = None, unit: Optional[str] = None + self, name: str, description: str | None = None, unit: str | None = None ) -> MetricCounter: return _NoopMetricCounter(name, description, unit) def create_histogram( - self, name: str, description: Optional[str] = None, unit: Optional[str] = None + self, name: str, description: str | None = None, unit: str | None = None ) -> MetricHistogram: return _NoopMetricHistogram(name, description, unit) def create_histogram_float( - self, name: str, description: Optional[str] = None, unit: Optional[str] = None + self, name: str, description: str | None = None, unit: str | None = None ) -> MetricHistogramFloat: return _NoopMetricHistogramFloat(name, description, unit) def create_histogram_timedelta( - self, name: str, description: Optional[str] = None, unit: Optional[str] = None + self, name: str, description: str | None = None, unit: str | None = None ) -> MetricHistogramTimedelta: return _NoopMetricHistogramTimedelta(name, description, unit) def create_gauge( - self, name: str, description: Optional[str] = None, unit: Optional[str] = None + self, name: str, description: str | None = None, unit: str | None = None ) -> MetricGauge: return _NoopMetricGauge(name, description, unit) def create_gauge_float( - self, name: str, description: Optional[str] = None, unit: Optional[str] = None + self, name: str, description: str | None = None, unit: str | None = None ) -> MetricGaugeFloat: return _NoopMetricGaugeFloat(name, description, unit) @@ -895,9 +891,7 @@ def with_additional_attributes( class _NoopMetric(MetricCommon): - def __init__( - self, name: str, description: Optional[str], unit: Optional[str] - ) -> None: + def __init__(self, name: str, description: str | None, unit: str | None) -> None: self._name = name self._description = description self._unit = unit @@ -907,11 +901,11 @@ def name(self) -> str: return self._name @property - def description(self) -> Optional[str]: + def description(self) -> str | None: return self._description @property - def unit(self) -> Optional[str]: + def unit(self) -> str | None: return self._unit def with_additional_attributes( @@ -922,42 +916,42 @@ def with_additional_attributes( class _NoopMetricCounter(MetricCounter, _NoopMetric): def add( - self, value: int, additional_attributes: Optional[MetricAttributes] = None + self, value: int, additional_attributes: MetricAttributes | None = None ) -> None: pass class _NoopMetricHistogram(MetricHistogram, _NoopMetric): def record( - self, value: int, additional_attributes: Optional[MetricAttributes] = None + self, value: int, additional_attributes: MetricAttributes | None = None ) -> None: pass class _NoopMetricHistogramFloat(MetricHistogramFloat, _NoopMetric): def record( - self, value: float, additional_attributes: Optional[MetricAttributes] = None + self, value: float, additional_attributes: MetricAttributes | None = None ) -> None: pass class _NoopMetricHistogramTimedelta(MetricHistogramTimedelta, _NoopMetric): def record( - self, value: timedelta, additional_attributes: Optional[MetricAttributes] = None + self, value: timedelta, additional_attributes: MetricAttributes | None = None ) -> None: pass class _NoopMetricGauge(MetricGauge, _NoopMetric): def set( - self, value: int, additional_attributes: Optional[MetricAttributes] = None + self, value: int, additional_attributes: MetricAttributes | None = None ) -> None: pass class _NoopMetricGaugeFloat(MetricGaugeFloat, _NoopMetric): def set( - self, value: float, additional_attributes: Optional[MetricAttributes] = None + self, value: float, additional_attributes: MetricAttributes | None = None ) -> None: pass @@ -982,7 +976,7 @@ class Priority: 2. Then consider "fairness_key" and "fairness_weight" for fairness balancing. """ - priority_key: Optional[int] = None + priority_key: int | None = None """Priority key is a positive integer from 1 to n, where smaller integers correspond to higher priorities (tasks run sooner). In general, tasks in a queue should be processed in close to priority order, although small deviations are possible. @@ -994,7 +988,7 @@ class Priority: 3. """ - fairness_key: Optional[str] = None + fairness_key: str | None = None """A short string (max 64 bytes) that is used as a key for a fairness balancing mechanism. This can correspond to a tenant id or even fixed strings like "high", "low", etc. @@ -1005,7 +999,7 @@ class Priority: Default is an empty string. """ - fairness_weight: Optional[float] = None + fairness_weight: float | None = None """A float that represents the weight for task dispatch for the associated fairness key. Tasks for a fairness key are dispatched in proportion to their weight. @@ -1172,9 +1166,9 @@ def _arg_or_args(arg: Any, args: Sequence[Any]) -> Sequence[Any]: def _apply_headers( - source: Optional[Mapping[str, temporalio.api.common.v1.Payload]], + source: Mapping[str, temporalio.api.common.v1.Payload] | None, dest: google.protobuf.internal.containers.MessageMap[ - Text, temporalio.api.common.v1.Payload + str, temporalio.api.common.v1.Payload ], ) -> None: if source is None: @@ -1200,7 +1194,7 @@ def _apply_headers( def _type_hints_from_func( func: Callable, -) -> Tuple[Optional[List[Type]], Optional[Type]]: +) -> tuple[list[type] | None, type | None]: """Extracts the type hints from the function. Args: @@ -1236,7 +1230,7 @@ def _type_hints_from_func( hints = get_type_hints(func) ret_hint = hints.get("return") ret = ret_hint if ret_hint is not inspect.Signature.empty else None - args: List[Type] = [] + args: list[type] = [] for index, value in enumerate(sig.parameters.values()): # Ignore self on methods if ( diff --git a/temporalio/contrib/openai_agents/_heartbeat_decorator.py b/temporalio/contrib/openai_agents/_heartbeat_decorator.py index d25814a42..2fae11d7d 100644 --- a/temporalio/contrib/openai_agents/_heartbeat_decorator.py +++ b/temporalio/contrib/openai_agents/_heartbeat_decorator.py @@ -1,6 +1,7 @@ import asyncio +from collections.abc import Awaitable, Callable from functools import wraps -from typing import Any, Awaitable, Callable, TypeVar, cast +from typing import Any, TypeVar, cast from temporalio import activity diff --git a/temporalio/contrib/openai_agents/_invoke_model_activity.py b/temporalio/contrib/openai_agents/_invoke_model_activity.py index 330ad0e7a..f03458c32 100644 --- a/temporalio/contrib/openai_agents/_invoke_model_activity.py +++ b/temporalio/contrib/openai_agents/_invoke_model_activity.py @@ -89,9 +89,9 @@ class HostedMCPToolInput: class AgentOutputSchemaInput(AgentOutputSchemaBase): """Data conversion friendly representation of AgentOutputSchema.""" - output_type_name: Optional[str] + output_type_name: str | None is_wrapped: bool - output_schema: Optional[dict[str, Any]] + output_schema: dict[str, Any] | None strict_json_schema: bool def is_plain_text(self) -> bool: @@ -135,17 +135,17 @@ class ModelTracingInput(enum.IntEnum): class ActivityModelInput(TypedDict, total=False): """Input for the invoke_model_activity activity.""" - model_name: Optional[str] - system_instructions: Optional[str] - input: Required[Union[str, list[TResponseInputItem]]] + model_name: str | None + system_instructions: str | None + input: Required[str | list[TResponseInputItem]] model_settings: Required[ModelSettings] tools: list[ToolInput] - output_schema: Optional[AgentOutputSchemaInput] + output_schema: AgentOutputSchemaInput | None handoffs: list[HandoffInput] tracing: Required[ModelTracingInput] - previous_response_id: Optional[str] - conversation_id: Optional[str] - prompt: Optional[Any] + previous_response_id: str | None + conversation_id: str | None + prompt: Any | None class ModelActivity: @@ -153,7 +153,7 @@ class ModelActivity: Disabling retries in your model of choice is recommended to allow activity retries to define the retry model. """ - def __init__(self, model_provider: Optional[ModelProvider] = None): + def __init__(self, model_provider: ModelProvider | None = None): """Initialize the activity with a model provider.""" self._model_provider = model_provider or OpenAIProvider( openai_client=AsyncOpenAI(max_retries=0) diff --git a/temporalio/contrib/openai_agents/_mcp.py b/temporalio/contrib/openai_agents/_mcp.py index 07ae8d838..76d558b82 100644 --- a/temporalio/contrib/openai_agents/_mcp.py +++ b/temporalio/contrib/openai_agents/_mcp.py @@ -4,9 +4,10 @@ import functools import inspect import logging +from collections.abc import Callable, Sequence from contextlib import AbstractAsyncContextManager from datetime import timedelta -from typing import Any, Callable, Optional, Sequence, Union, cast +from typing import Any, Optional, Union, cast from agents import AgentBase, RunContextWrapper from agents.mcp import MCPServer @@ -33,35 +34,35 @@ @dataclasses.dataclass class _StatelessListToolsArguments: - factory_argument: Optional[Any] + factory_argument: Any | None @dataclasses.dataclass class _StatelessCallToolsArguments: tool_name: str - arguments: Optional[dict[str, Any]] - factory_argument: Optional[Any] + arguments: dict[str, Any] | None + factory_argument: Any | None @dataclasses.dataclass class _StatelessListPromptsArguments: - factory_argument: Optional[Any] + factory_argument: Any | None @dataclasses.dataclass class _StatelessGetPromptArguments: name: str - arguments: Optional[dict[str, Any]] - factory_argument: Optional[Any] + arguments: dict[str, Any] | None + factory_argument: Any | None class _StatelessMCPServerReference(MCPServer): def __init__( self, server: str, - config: Optional[ActivityConfig], + config: ActivityConfig | None, cache_tools_list: bool, - factory_argument: Optional[Any] = None, + factory_argument: Any | None = None, ): self._name = server + "-stateless" self._config = config or ActivityConfig( @@ -84,8 +85,8 @@ async def cleanup(self) -> None: async def list_tools( self, - run_context: Optional[RunContextWrapper[Any]] = None, - agent: Optional[AgentBase] = None, + run_context: RunContextWrapper[Any] | None = None, + agent: AgentBase | None = None, ) -> list[MCPTool]: if self._tools: return self._tools @@ -100,7 +101,7 @@ async def list_tools( return tools async def call_tool( - self, tool_name: str, arguments: Optional[dict[str, Any]] + self, tool_name: str, arguments: dict[str, Any] | None ) -> CallToolResult: return await workflow.execute_activity( self.name + "-call-tool-v2", @@ -118,7 +119,7 @@ async def list_prompts(self) -> ListPromptsResult: ) async def get_prompt( - self, name: str, arguments: Optional[dict[str, Any]] = None + self, name: str, arguments: dict[str, Any] | None = None ) -> GetPromptResult: return await workflow.execute_activity( self.name + "-get-prompt-v2", @@ -142,9 +143,7 @@ class StatelessMCPServerProvider: def __init__( self, name: str, - server_factory: Union[ - Callable[[], MCPServer], Callable[[Optional[Any]], MCPServer] - ], + server_factory: (Callable[[], MCPServer] | Callable[[Any | None], MCPServer]), ): """Initialize the stateless temporal MCP server. @@ -162,7 +161,7 @@ def __init__( self._name = name + "-stateless" super().__init__() - def _create_server(self, factory_argument: Optional[Any]) -> MCPServer: + def _create_server(self, factory_argument: Any | None) -> MCPServer: if self._server_accepts_arguments: return cast(Callable[[Optional[Any]], MCPServer], self._server_factory)( factory_argument @@ -178,7 +177,7 @@ def name(self) -> str: def _get_activities(self) -> Sequence[Callable]: @activity.defn(name=self.name + "-list-tools") async def list_tools( - args: Optional[_StatelessListToolsArguments] = None, + args: _StatelessListToolsArguments | None = None, ) -> list[MCPTool]: server = self._create_server(args.factory_argument if args else None) try: @@ -198,7 +197,7 @@ async def call_tool(args: _StatelessCallToolsArguments) -> CallToolResult: @activity.defn(name=self.name + "-list-prompts") async def list_prompts( - args: Optional[_StatelessListPromptsArguments] = None, + args: _StatelessListPromptsArguments | None = None, ) -> ListPromptsResult: server = self._create_server(args.factory_argument if args else None) try: @@ -219,7 +218,7 @@ async def get_prompt(args: _StatelessGetPromptArguments) -> GetPromptResult: @activity.defn(name=self.name + "-call-tool") async def call_tool_deprecated( tool_name: str, - arguments: Optional[dict[str, Any]], + arguments: dict[str, Any] | None, ) -> CallToolResult: return await call_tool( _StatelessCallToolsArguments(tool_name, arguments, None) @@ -228,7 +227,7 @@ async def call_tool_deprecated( @activity.defn(name=self.name + "-get-prompt") async def get_prompt_deprecated( name: str, - arguments: Optional[dict[str, Any]], + arguments: dict[str, Any] | None, ) -> GetPromptResult: return await get_prompt(_StatelessGetPromptArguments(name, arguments, None)) @@ -276,27 +275,27 @@ async def wrapper(*args, **kwargs): @dataclasses.dataclass class _StatefulCallToolsArguments: tool_name: str - arguments: Optional[dict[str, Any]] + arguments: dict[str, Any] | None @dataclasses.dataclass class _StatefulGetPromptArguments: name: str - arguments: Optional[dict[str, Any]] + arguments: dict[str, Any] | None @dataclasses.dataclass class _StatefulServerSessionArguments: - factory_argument: Optional[Any] + factory_argument: Any | None class _StatefulMCPServerReference(MCPServer, AbstractAsyncContextManager): def __init__( self, server: str, - config: Optional[ActivityConfig], - server_session_config: Optional[ActivityConfig], - factory_argument: Optional[Any], + config: ActivityConfig | None, + server_session_config: ActivityConfig | None, + factory_argument: Any | None, ): self._name = server + "-stateful" self._config = config or ActivityConfig( @@ -306,7 +305,7 @@ def __init__( self._server_session_config = server_session_config or ActivityConfig( start_to_close_timeout=timedelta(hours=1), ) - self._connect_handle: Optional[ActivityHandle] = None + self._connect_handle: ActivityHandle | None = None self._factory_argument = factory_argument super().__init__() @@ -343,8 +342,8 @@ async def __aexit__(self, exc_type, exc_value, traceback): @_handle_worker_failure async def list_tools( self, - run_context: Optional[RunContextWrapper[Any]] = None, - agent: Optional[AgentBase] = None, + run_context: RunContextWrapper[Any] | None = None, + agent: AgentBase | None = None, ) -> list[MCPTool]: if not self._connect_handle: raise ApplicationError( @@ -359,7 +358,7 @@ async def list_tools( @_handle_worker_failure async def call_tool( - self, tool_name: str, arguments: Optional[dict[str, Any]] + self, tool_name: str, arguments: dict[str, Any] | None ) -> CallToolResult: if not self._connect_handle: raise ApplicationError( @@ -387,7 +386,7 @@ async def list_prompts(self) -> ListPromptsResult: @_handle_worker_failure async def get_prompt( - self, name: str, arguments: Optional[dict[str, Any]] = None + self, name: str, arguments: dict[str, Any] | None = None ) -> GetPromptResult: if not self._connect_handle: raise ApplicationError( @@ -420,7 +419,7 @@ class StatefulMCPServerProvider: def __init__( self, name: str, - server_factory: Callable[[Optional[Any]], MCPServer], + server_factory: Callable[[Any | None], MCPServer], ): """Initialize the stateful temporal MCP server. @@ -431,7 +430,7 @@ def __init__( """ self._server_factory = server_factory self._name = name + "-stateful" - self._connect_handle: Optional[ActivityHandle] = None + self._connect_handle: ActivityHandle | None = None self._servers: dict[str, MCPServer] = {} super().__init__() @@ -450,7 +449,7 @@ async def list_tools() -> list[MCPTool]: @activity.defn(name=self.name + "-call-tool") async def call_tool_deprecated( - tool_name: str, arguments: Optional[dict[str, Any]] + tool_name: str, arguments: dict[str, Any] | None ) -> CallToolResult: return await self._servers[_server_id()].call_tool(tool_name, arguments) @@ -466,7 +465,7 @@ async def list_prompts() -> ListPromptsResult: @activity.defn(name=self.name + "-get-prompt") async def get_prompt_deprecated( - name: str, arguments: Optional[dict[str, Any]] + name: str, arguments: dict[str, Any] | None ) -> GetPromptResult: return await self._servers[_server_id()].get_prompt(name, arguments) @@ -484,7 +483,7 @@ async def heartbeat_every(delay: float, *details: Any) -> None: @activity.defn(name=self.name + "-server-session") async def connect( - args: Optional[_StatefulServerSessionArguments] = None, + args: _StatefulServerSessionArguments | None = None, ) -> None: heartbeat_task = asyncio.create_task(heartbeat_every(30)) diff --git a/temporalio/contrib/openai_agents/_model_parameters.py b/temporalio/contrib/openai_agents/_model_parameters.py index b4c4c8245..3cab91c27 100644 --- a/temporalio/contrib/openai_agents/_model_parameters.py +++ b/temporalio/contrib/openai_agents/_model_parameters.py @@ -1,9 +1,10 @@ """Parameters for configuring Temporal activity execution for model calls.""" from abc import ABC, abstractmethod +from collections.abc import Callable from dataclasses import dataclass from datetime import timedelta -from typing import Any, Callable, Optional, Union +from typing import Any, Optional, Union from agents import Agent, TResponseInputItem @@ -19,9 +20,9 @@ class ModelSummaryProvider(ABC): @abstractmethod def provide( self, - agent: Optional[Agent[Any]], - instructions: Optional[str], - input: Union[str, list[TResponseInputItem]], + agent: Agent[Any] | None, + instructions: str | None, + input: str | list[TResponseInputItem], ) -> str: """Given the provided information, produce a summary for the model invocation activity.""" pass @@ -36,36 +37,31 @@ class ModelActivityParameters: OpenAI Agents integration. """ - task_queue: Optional[str] = None + task_queue: str | None = None """Specific task queue to use for model activities.""" - schedule_to_close_timeout: Optional[timedelta] = None + schedule_to_close_timeout: timedelta | None = None """Maximum time from scheduling to completion.""" - schedule_to_start_timeout: Optional[timedelta] = None + schedule_to_start_timeout: timedelta | None = None """Maximum time from scheduling to starting.""" - start_to_close_timeout: Optional[timedelta] = timedelta(seconds=60) + start_to_close_timeout: timedelta | None = timedelta(seconds=60) """Maximum time for the activity to complete.""" - heartbeat_timeout: Optional[timedelta] = None + heartbeat_timeout: timedelta | None = None """Maximum time between heartbeats.""" - retry_policy: Optional[RetryPolicy] = None + retry_policy: RetryPolicy | None = None """Policy for retrying failed activities.""" cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL """How the activity handles cancellation.""" - versioning_intent: Optional[VersioningIntent] = None + versioning_intent: VersioningIntent | None = None """Versioning intent for the activity.""" - summary_override: Optional[ - Union[ - str, - ModelSummaryProvider, - ] - ] = None + summary_override: None | (str | ModelSummaryProvider) = None """Summary for the activity execution.""" priority: Priority = Priority.default diff --git a/temporalio/contrib/openai_agents/_openai_runner.py b/temporalio/contrib/openai_agents/_openai_runner.py index 0b120a2a6..a8065d207 100644 --- a/temporalio/contrib/openai_agents/_openai_runner.py +++ b/temporalio/contrib/openai_agents/_openai_runner.py @@ -27,7 +27,7 @@ def _convert_agent( model_params: ModelActivityParameters, agent: Agent[Any], - seen: Optional[dict[int, Agent]], + seen: dict[int, Agent] | None, ) -> Agent[Any]: if seen is None: seen = dict() @@ -46,7 +46,7 @@ def _convert_agent( name = _model_name(agent) - new_handoffs: list[Union[Agent, Handoff]] = [] + new_handoffs: list[Agent | Handoff] = [] for handoff in agent.handoffs: if isinstance(handoff, Agent): new_handoffs.append(_convert_agent(model_params, handoff, seen)) @@ -87,7 +87,7 @@ def __init__(self, model_params: ModelActivityParameters) -> None: async def run( self, starting_agent: Agent[TContext], - input: Union[str, list[TResponseInputItem]], + input: str | list[TResponseInputItem], **kwargs: Any, ) -> RunResult: """Run the agent in a Temporal workflow.""" @@ -174,7 +174,7 @@ async def run( def run_sync( self, starting_agent: Agent[TContext], - input: Union[str, list[TResponseInputItem]], + input: str | list[TResponseInputItem], **kwargs: Any, ) -> RunResult: """Run the agent synchronously (not supported in Temporal workflows).""" @@ -189,7 +189,7 @@ def run_sync( def run_streamed( self, starting_agent: Agent[TContext], - input: Union[str, list[TResponseInputItem]], + input: str | list[TResponseInputItem], **kwargs: Any, ) -> RunResultStreaming: """Run the agent with streaming responses (not supported in Temporal workflows).""" @@ -202,7 +202,7 @@ def run_streamed( raise RuntimeError("Temporal workflows do not support streaming.") -def _model_name(agent: Agent[Any]) -> Optional[str]: +def _model_name(agent: Agent[Any]) -> str | None: name = agent.model if name is not None and not isinstance(name, str): raise ValueError( diff --git a/temporalio/contrib/openai_agents/_temporal_model_stub.py b/temporalio/contrib/openai_agents/_temporal_model_stub.py index bd69af414..f84488541 100644 --- a/temporalio/contrib/openai_agents/_temporal_model_stub.py +++ b/temporalio/contrib/openai_agents/_temporal_model_stub.py @@ -8,7 +8,8 @@ logger = logging.getLogger(__name__) -from typing import Any, AsyncIterator, Union, cast +from collections.abc import AsyncIterator +from typing import Any, Union, cast from agents import ( Agent, @@ -48,10 +49,10 @@ class _TemporalModelStub(Model): def __init__( self, - model_name: Optional[str], + model_name: str | None, *, model_params: ModelActivityParameters, - agent: Optional[Agent[Any]], + agent: Agent[Any] | None, ) -> None: self.model_name = model_name self.model_params = model_params @@ -59,17 +60,17 @@ def __init__( async def get_response( self, - system_instructions: Optional[str], - input: Union[str, list[TResponseInputItem]], + system_instructions: str | None, + input: str | list[TResponseInputItem], model_settings: ModelSettings, tools: list[Tool], - output_schema: Optional[AgentOutputSchemaBase], + output_schema: AgentOutputSchemaBase | None, handoffs: list[Handoff], tracing: ModelTracing, *, - previous_response_id: Optional[str], - conversation_id: Optional[str], - prompt: Optional[ResponsePromptParam], + previous_response_id: str | None, + conversation_id: str | None, + prompt: ResponsePromptParam | None, ) -> ModelResponse: def make_tool_info(tool: Tool) -> ToolInput: if isinstance( @@ -183,22 +184,22 @@ def make_tool_info(tool: Tool) -> ToolInput: def stream_response( self, - system_instructions: Optional[str], - input: Union[str, list[TResponseInputItem]], + system_instructions: str | None, + input: str | list[TResponseInputItem], model_settings: ModelSettings, tools: list[Tool], - output_schema: Optional[AgentOutputSchemaBase], + output_schema: AgentOutputSchemaBase | None, handoffs: list[Handoff], tracing: ModelTracing, *, - previous_response_id: Optional[str], - conversation_id: Optional[str], + previous_response_id: str | None, + conversation_id: str | None, prompt: ResponsePromptParam | None, ) -> AsyncIterator[TResponseStreamEvent]: raise NotImplementedError("Temporal model doesn't support streams yet") -def _extract_summary(input: Union[str, list[TResponseInputItem]]) -> str: +def _extract_summary(input: str | list[TResponseInputItem]) -> str: ### Activity summary shown in the UI try: max_size = 100 diff --git a/temporalio/contrib/openai_agents/_temporal_openai_agents.py b/temporalio/contrib/openai_agents/_temporal_openai_agents.py index a54ca1912..41ae419f7 100644 --- a/temporalio/contrib/openai_agents/_temporal_openai_agents.py +++ b/temporalio/contrib/openai_agents/_temporal_openai_agents.py @@ -2,9 +2,10 @@ import dataclasses import typing +from collections.abc import AsyncIterator, Callable, Sequence from contextlib import asynccontextmanager, contextmanager from datetime import timedelta -from typing import AsyncIterator, Callable, Optional, Sequence, Union +from typing import Optional, Union from agents import ModelProvider, set_trace_provider from agents.run import get_default_agent_runner, set_default_agent_runner @@ -93,7 +94,7 @@ def __init__(self) -> None: super().__init__(ToJsonOptions(exclude_unset=True)) -def _data_converter(converter: Optional[DataConverter]) -> DataConverter: +def _data_converter(converter: DataConverter | None) -> DataConverter: if converter is None: return DataConverter(payload_converter_class=OpenAIPayloadConverter) elif converter.payload_converter_class is DefaultPayloadConverter: @@ -175,8 +176,8 @@ class OpenAIAgentsPlugin(SimplePlugin): def __init__( self, - model_params: Optional[ModelActivityParameters] = None, - model_provider: Optional[ModelProvider] = None, + model_params: ModelActivityParameters | None = None, + model_provider: ModelProvider | None = None, mcp_server_providers: Sequence[ Union["StatelessMCPServerProvider", "StatefulMCPServerProvider"] ] = (), @@ -215,7 +216,7 @@ def __init__( # Delay activity construction until they are actually needed def add_activities( - activities: Optional[Sequence[Callable]], + activities: Sequence[Callable] | None, ) -> Sequence[Callable]: if not register_activities: return activities or [] @@ -232,7 +233,7 @@ def add_activities( new_activities.extend(mcp_server._get_activities()) return list(activities or []) + new_activities - def workflow_runner(runner: Optional[WorkflowRunner]) -> WorkflowRunner: + def workflow_runner(runner: WorkflowRunner | None) -> WorkflowRunner: if not runner: raise ValueError("No WorkflowRunner provided to the OpenAI plugin.") diff --git a/temporalio/contrib/openai_agents/_temporal_trace_provider.py b/temporalio/contrib/openai_agents/_temporal_trace_provider.py index 46905f590..37fe33eca 100644 --- a/temporalio/contrib/openai_agents/_temporal_trace_provider.py +++ b/temporalio/contrib/openai_agents/_temporal_trace_provider.py @@ -27,10 +27,10 @@ def __init__( activity_id: str, activity_type: str, task_queue: str, - schedule_to_close_timeout: Optional[float] = None, - schedule_to_start_timeout: Optional[float] = None, - start_to_close_timeout: Optional[float] = None, - heartbeat_timeout: Optional[float] = None, + schedule_to_close_timeout: float | None = None, + schedule_to_start_timeout: float | None = None, + start_to_close_timeout: float | None = None, + heartbeat_timeout: float | None = None, ): """Initialize an ActivitySpanData instance.""" self.activity_id = activity_id diff --git a/temporalio/contrib/openai_agents/_trace_interceptor.py b/temporalio/contrib/openai_agents/_trace_interceptor.py index 20d489b65..ffa22cc16 100644 --- a/temporalio/contrib/openai_agents/_trace_interceptor.py +++ b/temporalio/contrib/openai_agents/_trace_interceptor.py @@ -4,8 +4,9 @@ import random import uuid +from collections.abc import Mapping from contextlib import contextmanager -from typing import Any, Mapping, Optional, Protocol, Type +from typing import Any, Optional, Protocol, Type from agents import CustomSpanData, custom_span, get_current_span, trace from agents.tracing import ( @@ -169,7 +170,7 @@ def intercept_activity( def workflow_interceptor_class( self, input: temporalio.worker.WorkflowInterceptorClassInput - ) -> Type[_ContextPropagationWorkflowInboundInterceptor]: + ) -> type[_ContextPropagationWorkflowInboundInterceptor]: """Returns the workflow interceptor class to propagate trace context. Args: @@ -401,7 +402,7 @@ def start_activity( self, input: temporalio.worker.StartActivityInput ) -> temporalio.workflow.ActivityHandle: trace = get_trace_provider().get_current_trace() - span: Optional[Span] = None + span: Span | None = None if trace: span = custom_span( name="temporal:startActivity", data={"activity": input.activity} @@ -418,7 +419,7 @@ async def start_child_workflow( self, input: temporalio.worker.StartChildWorkflowInput ) -> temporalio.workflow.ChildWorkflowHandle: trace = get_trace_provider().get_current_trace() - span: Optional[Span] = None + span: Span | None = None if trace: span = custom_span( name="temporal:startChildWorkflow", data={"workflow": input.workflow} @@ -434,7 +435,7 @@ def start_local_activity( self, input: temporalio.worker.StartLocalActivityInput ) -> temporalio.workflow.ActivityHandle: trace = get_trace_provider().get_current_trace() - span: Optional[Span] = None + span: Span | None = None if trace: span = custom_span( name="temporal:startLocalActivity", data={"activity": input.activity} diff --git a/temporalio/contrib/openai_agents/testing.py b/temporalio/contrib/openai_agents/testing.py index 9a2a2a9ed..4acab196a 100644 --- a/temporalio/contrib/openai_agents/testing.py +++ b/temporalio/contrib/openai_agents/testing.py @@ -1,6 +1,7 @@ """Testing utilities for OpenAI agents.""" -from typing import AsyncIterator, Callable, Optional, Sequence, Union +from collections.abc import AsyncIterator, Callable, Sequence +from typing import Optional, Union from agents import ( AgentOutputSchemaBase, @@ -125,7 +126,7 @@ def __init__(self, model: Model): """ self._model = model - def get_model(self, model_name: Union[str, None]) -> Model: + def get_model(self, model_name: str | None) -> Model: """Get a model from the model provider. .. warning:: @@ -153,11 +154,11 @@ def __init__(self, fn: Callable[[], ModelResponse]) -> None: async def get_response( self, - system_instructions: Union[str, None], - input: Union[str, list[TResponseInputItem]], + system_instructions: str | None, + input: str | list[TResponseInputItem], model_settings: ModelSettings, tools: list[Tool], - output_schema: Union[AgentOutputSchemaBase, None], + output_schema: AgentOutputSchemaBase | None, handoffs: list[Handoff], tracing: ModelTracing, **kwargs, @@ -167,11 +168,11 @@ async def get_response( def stream_response( self, - system_instructions: Optional[str], - input: Union[str, list[TResponseInputItem]], + system_instructions: str | None, + input: str | list[TResponseInputItem], model_settings: ModelSettings, tools: list[Tool], - output_schema: Optional[AgentOutputSchemaBase], + output_schema: AgentOutputSchemaBase | None, handoffs: list[Handoff], tracing: ModelTracing, **kwargs, @@ -218,11 +219,11 @@ class AgentEnvironment: def __init__( self, - model_params: Optional[ModelActivityParameters] = None, - model_provider: Optional[ModelProvider] = None, - model: Optional[Model] = None, + model_params: ModelActivityParameters | None = None, + model_provider: ModelProvider | None = None, + model: Model | None = None, mcp_server_providers: Sequence[ - Union[StatelessMCPServerProvider, StatefulMCPServerProvider] + StatelessMCPServerProvider | StatefulMCPServerProvider ] = (), register_activities: bool = True, ) -> None: @@ -253,7 +254,7 @@ def __init__( self._model_provider = TestModelProvider(model) self._mcp_server_providers = mcp_server_providers self._register_activities = register_activities - self._plugin: Optional[OpenAIAgentsPlugin] = None + self._plugin: OpenAIAgentsPlugin | None = None async def __aenter__(self) -> "AgentEnvironment": """Enter the async context manager.""" diff --git a/temporalio/contrib/openai_agents/workflow.py b/temporalio/contrib/openai_agents/workflow.py index 1023531a1..e4738e274 100644 --- a/temporalio/contrib/openai_agents/workflow.py +++ b/temporalio/contrib/openai_agents/workflow.py @@ -4,9 +4,10 @@ import inspect import json import typing +from collections.abc import Callable from contextlib import AbstractAsyncContextManager from datetime import timedelta -from typing import Any, Callable, Optional, Type +from typing import Any, Optional, Type import nexusrpc from agents import ( @@ -35,16 +36,16 @@ def activity_as_tool( fn: Callable, *, - task_queue: Optional[str] = None, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - heartbeat_timeout: Optional[timedelta] = None, - retry_policy: Optional[RetryPolicy] = None, + task_queue: str | None = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + heartbeat_timeout: timedelta | None = None, + retry_policy: RetryPolicy | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - versioning_intent: Optional[VersioningIntent] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + versioning_intent: VersioningIntent | None = None, + summary: str | None = None, priority: Priority = Priority.default, strict_json_schema: bool = True, ) -> Tool: @@ -161,9 +162,9 @@ async def run_activity(ctx: RunContextWrapper[Any], input: str) -> Any: def nexus_operation_as_tool( operation: nexusrpc.Operation[Any, Any], *, - service: Type[Any], + service: type[Any], endpoint: str, - schedule_to_close_timeout: Optional[timedelta] = None, + schedule_to_close_timeout: timedelta | None = None, strict_json_schema: bool = True, ) -> Tool: """Convert a Nexus operation into an OpenAI agent tool. @@ -248,9 +249,9 @@ async def run_operation(ctx: RunContextWrapper[Any], input: str) -> Any: def stateless_mcp_server( name: str, - config: Optional[ActivityConfig] = None, + config: ActivityConfig | None = None, cache_tools_list: bool = False, - factory_argument: Optional[Any] = None, + factory_argument: Any | None = None, ) -> "MCPServer": """A stateless MCP server implementation for Temporal workflows. @@ -283,9 +284,9 @@ def stateless_mcp_server( def stateful_mcp_server( name: str, - config: Optional[ActivityConfig] = None, - server_session_config: Optional[ActivityConfig] = None, - factory_argument: Optional[Any] = None, + config: ActivityConfig | None = None, + server_session_config: ActivityConfig | None = None, + factory_argument: Any | None = None, ) -> AbstractAsyncContextManager["MCPServer"]: """A stateful MCP server implementation for Temporal workflows. diff --git a/temporalio/contrib/opentelemetry.py b/temporalio/contrib/opentelemetry.py index 7dfd920ef..b1a0d6a06 100644 --- a/temporalio/contrib/opentelemetry.py +++ b/temporalio/contrib/opentelemetry.py @@ -2,18 +2,16 @@ from __future__ import annotations +from collections.abc import Callable, Iterator, Mapping, Sequence from contextlib import contextmanager from dataclasses import dataclass from typing import ( Any, - Callable, Dict, - Iterator, - Mapping, NoReturn, Optional, - Sequence, Type, + TypeAlias, cast, ) @@ -27,7 +25,7 @@ import opentelemetry.util.types from opentelemetry.context import Context from opentelemetry.trace import Status, StatusCode -from typing_extensions import Protocol, TypeAlias, TypedDict +from typing_extensions import Protocol, TypedDict import temporalio.activity import temporalio.api.common.v1 @@ -54,7 +52,7 @@ ) """Default text map propagator used by :py:class:`TracingInterceptor`.""" -_CarrierDict: TypeAlias = Dict[str, opentelemetry.propagators.textmap.CarrierValT] +_CarrierDict: TypeAlias = dict[str, opentelemetry.propagators.textmap.CarrierValT] class TracingInterceptor(temporalio.client.Interceptor, temporalio.worker.Interceptor): @@ -76,7 +74,7 @@ class should return the workflow interceptor subclass from def __init__( # type: ignore[reportMissingSuperCall] self, - tracer: Optional[opentelemetry.trace.Tracer] = None, + tracer: opentelemetry.trace.Tracer | None = None, *, always_create_workflow_spans: bool = False, ) -> None: @@ -123,7 +121,7 @@ def intercept_activity( def workflow_interceptor_class( self, input: temporalio.worker.WorkflowInterceptorClassInput - ) -> Type[TracingWorkflowInboundInterceptor]: + ) -> type[TracingWorkflowInboundInterceptor]: """Implementation of :py:meth:`temporalio.worker.Interceptor.workflow_interceptor_class`. """ @@ -149,7 +147,7 @@ def _context_to_headers( def _context_from_headers( self, headers: Mapping[str, temporalio.api.common.v1.Payload] - ) -> Optional[opentelemetry.context.context.Context]: + ) -> opentelemetry.context.context.Context | None: if self.header_key not in headers: return None header_payload = headers.get(self.header_key) @@ -168,9 +166,9 @@ def _start_as_current_span( name: str, *, attributes: opentelemetry.util.types.Attributes, - input: Optional[_InputWithHeaders] = None, + input: _InputWithHeaders | None = None, kind: opentelemetry.trace.SpanKind, - context: Optional[Context] = None, + context: Context | None = None, ) -> Iterator[None]: token = opentelemetry.context.attach(context) if context else None try: @@ -203,7 +201,7 @@ def _start_as_current_span( def _completed_workflow_span( self, params: _CompletedWorkflowSpanParams - ) -> Optional[_CarrierDict]: + ) -> _CarrierDict | None: # Carrier to context, start span, set span as current on context, # context back to carrier @@ -215,7 +213,7 @@ def _completed_workflow_span( # Extract the context context = self.text_map_propagator.extract(params.context) # Create link if there is a span present - links: Optional[Sequence[opentelemetry.trace.Link]] = [] + links: Sequence[opentelemetry.trace.Link] | None = [] if params.link_context: link_span = opentelemetry.trace.get_current_span( self.text_map_propagator.extract(params.link_context) @@ -353,7 +351,7 @@ class _InputWithHeaders(Protocol): class _WorkflowExternFunctions(TypedDict): __temporal_opentelemetry_completed_span: Callable[ - [_CompletedWorkflowSpanParams], Optional[_CarrierDict] + [_CompletedWorkflowSpanParams], _CarrierDict | None ] @@ -363,8 +361,8 @@ class _CompletedWorkflowSpanParams: name: str attributes: opentelemetry.util.types.Attributes time_ns: int - link_context: Optional[_CarrierDict] - exception: Optional[Exception] + link_context: _CarrierDict | None + exception: Exception | None kind: opentelemetry.trace.SpanKind parent_missing: bool @@ -382,7 +380,7 @@ class TracingWorkflowInboundInterceptor(temporalio.worker.WorkflowInboundInterce """ @staticmethod - def _from_context() -> Optional[TracingWorkflowInboundInterceptor]: + def _from_context() -> TracingWorkflowInboundInterceptor | None: ret = opentelemetry.context.get_value(_interceptor_context_key) if ret and isinstance(ret, TracingWorkflowInboundInterceptor): return ret @@ -401,7 +399,7 @@ def __init__(self, next: temporalio.worker.WorkflowInboundInterceptor) -> None: # TODO(cretz): Should I be using the configured one for this workflow? self.payload_converter = temporalio.converter.PayloadConverter.default # This is the context for the overall workflow, lazily created - self._workflow_context_carrier: Optional[_CarrierDict] = None + self._workflow_context_carrier: _CarrierDict | None = None def init(self, outbound: temporalio.worker.WorkflowOutboundInterceptor) -> None: """Implementation of @@ -430,7 +428,7 @@ async def handle_signal(self, input: temporalio.worker.HandleSignalInput) -> Non # Create a span in the current context for the signal and link any # header given link_context_header = input.headers.get(self.header_key) - link_context_carrier: Optional[_CarrierDict] = None + link_context_carrier: _CarrierDict | None = None if link_context_header: link_context_carrier = self.payload_converter.from_payloads( [link_context_header] @@ -452,7 +450,7 @@ async def handle_query(self, input: temporalio.worker.HandleQueryInput) -> Any: # span. context_header = input.headers.get(self.header_key) context: opentelemetry.context.Context - link_context_carrier: Optional[_CarrierDict] = None + link_context_carrier: _CarrierDict | None = None if context_header: context_carrier = self.payload_converter.from_payloads([context_header])[0] context = self.text_map_propagator.extract(context_carrier) @@ -491,7 +489,7 @@ def handle_update_validator( :py:meth:`temporalio.worker.WorkflowInboundInterceptor.handle_update_validator`. """ link_context_header = input.headers.get(self.header_key) - link_context_carrier: Optional[_CarrierDict] = None + link_context_carrier: _CarrierDict | None = None if link_context_header: link_context_carrier = self.payload_converter.from_payloads( [link_context_header] @@ -511,7 +509,7 @@ async def handle_update_handler( :py:meth:`temporalio.worker.WorkflowInboundInterceptor.handle_update_handler`. """ link_context_header = input.headers.get(self.header_key) - link_context_carrier: Optional[_CarrierDict] = None + link_context_carrier: _CarrierDict | None = None if link_context_header: link_context_carrier = self.payload_converter.from_payloads( [link_context_header] @@ -524,7 +522,7 @@ async def handle_update_handler( ) return await super().handle_update_handler(input) - def _load_workflow_context_carrier(self) -> Optional[_CarrierDict]: + def _load_workflow_context_carrier(self) -> _CarrierDict | None: if self._workflow_context_carrier: return self._workflow_context_carrier context_header = temporalio.workflow.info().headers.get(self.header_key) @@ -551,7 +549,7 @@ def _top_level_workflow_context( # Need to know whether completed and whether there was a fail-workflow # exception success = False - exception: Optional[Exception] = None + exception: Exception | None = None # Run under this context token = opentelemetry.context.attach(context) @@ -602,11 +600,11 @@ def _completed_span( self, span_name: str, *, - link_context_carrier: Optional[_CarrierDict] = None, - add_to_outbound: Optional[_InputWithHeaders] = None, + link_context_carrier: _CarrierDict | None = None, + add_to_outbound: _InputWithHeaders | None = None, new_span_even_on_replay: bool = False, additional_attributes: opentelemetry.util.types.Attributes = None, - exception: Optional[Exception] = None, + exception: Exception | None = None, kind: opentelemetry.trace.SpanKind = opentelemetry.trace.SpanKind.INTERNAL, ) -> None: # If we are replaying and they don't want a span on replay, no span @@ -618,7 +616,7 @@ def _completed_span( self.text_map_propagator.inject(new_context_carrier) # Invoke info = temporalio.workflow.info() - attributes: Dict[str, opentelemetry.util.types.AttributeValue] = { + attributes: dict[str, opentelemetry.util.types.AttributeValue] = { "temporalWorkflowID": info.workflow_id, "temporalRunID": info.run_id, } @@ -740,7 +738,7 @@ def completed_span( name: str, *, attributes: opentelemetry.util.types.Attributes = None, - exception: Optional[Exception] = None, + exception: Exception | None = None, ) -> None: """Create and end an OpenTelemetry span. diff --git a/temporalio/contrib/pydantic.py b/temporalio/contrib/pydantic.py index 97f1b6ac3..5de19f180 100644 --- a/temporalio/contrib/pydantic.py +++ b/temporalio/contrib/pydantic.py @@ -53,7 +53,7 @@ class PydanticJSONPlainPayloadConverter(EncodingPayloadConverter): See https://docs.pydantic.dev/latest/api/standard_library_types/ """ - def __init__(self, to_json_options: Optional[ToJsonOptions] = None): + def __init__(self, to_json_options: ToJsonOptions | None = None): """Create a new payload converter.""" self._schema_serializer = SchemaSerializer(any_schema()) self._to_json_options = to_json_options @@ -63,7 +63,7 @@ def encoding(self) -> str: """See base class.""" return "json/plain" - def to_payload(self, value: Any) -> Optional[temporalio.api.common.v1.Payload]: + def to_payload(self, value: Any) -> temporalio.api.common.v1.Payload | None: """See base class. Uses ``pydantic_core.to_json`` to serialize ``value`` to JSON. @@ -85,7 +85,7 @@ def to_payload(self, value: Any) -> Optional[temporalio.api.common.v1.Payload]: def from_payload( self, payload: temporalio.api.common.v1.Payload, - type_hint: Optional[Type] = None, + type_hint: type | None = None, ) -> Any: """See base class. @@ -106,7 +106,7 @@ class PydanticPayloadConverter(CompositePayloadConverter): :py:class:`PydanticJSONPlainPayloadConverter`. """ - def __init__(self, to_json_options: Optional[ToJsonOptions] = None) -> None: + def __init__(self, to_json_options: ToJsonOptions | None = None) -> None: """Initialize object""" json_payload_converter = PydanticJSONPlainPayloadConverter(to_json_options) super().__init__( diff --git a/temporalio/converter.py b/temporalio/converter.py index 92a5d72e2..8af1e1dc6 100644 --- a/temporalio/converter.py +++ b/temporalio/converter.py @@ -13,6 +13,7 @@ import uuid import warnings from abc import ABC, abstractmethod +from collections.abc import Awaitable, Callable, Mapping, Sequence from dataclasses import dataclass from datetime import datetime from enum import IntEnum @@ -20,16 +21,12 @@ from logging import getLogger from typing import ( Any, - Awaitable, - Callable, ClassVar, Dict, List, Literal, - Mapping, NewType, Optional, - Sequence, Tuple, Type, TypeVar, @@ -61,8 +58,7 @@ if sys.version_info >= (3, 11): from enum import StrEnum -if sys.version_info >= (3, 10): - from types import UnionType +from types import UnionType logger = getLogger(__name__) @@ -176,7 +172,7 @@ class PayloadConverter(ABC): @abstractmethod def to_payloads( self, values: Sequence[Any] - ) -> List[temporalio.api.common.v1.Payload]: + ) -> list[temporalio.api.common.v1.Payload]: """Encode values into payloads. Implementers are expected to just return the payload for @@ -199,8 +195,8 @@ def to_payloads( def from_payloads( self, payloads: Sequence[temporalio.api.common.v1.Payload], - type_hints: Optional[List[Type]] = None, - ) -> List[Any]: + type_hints: list[type] | None = None, + ) -> list[Any]: """Decode payloads into values. Implementers are expected to treat a type hint of @@ -231,8 +227,8 @@ def to_payloads_wrapper( return temporalio.api.common.v1.Payloads(payloads=self.to_payloads(values)) def from_payloads_wrapper( - self, payloads: Optional[temporalio.api.common.v1.Payloads] - ) -> List[Any]: + self, payloads: temporalio.api.common.v1.Payloads | None + ) -> list[Any]: """:py:meth:`from_payloads` for the :py:class:`temporalio.api.common.v1.Payloads` wrapper. """ @@ -261,13 +257,13 @@ def from_payload(self, payload: temporalio.api.common.v1.Payload) -> Any: ... def from_payload( self, payload: temporalio.api.common.v1.Payload, - type_hint: Type[temporalio.types.AnyType], + type_hint: type[temporalio.types.AnyType], ) -> temporalio.types.AnyType: ... def from_payload( self, payload: temporalio.api.common.v1.Payload, - type_hint: Optional[Type] = None, + type_hint: type | None = None, ) -> Any: """Convert a single payload to a value. @@ -294,7 +290,7 @@ def encoding(self) -> str: raise NotImplementedError @abstractmethod - def to_payload(self, value: Any) -> Optional[temporalio.api.common.v1.Payload]: + def to_payload(self, value: Any) -> temporalio.api.common.v1.Payload | None: """Encode a single value to a payload or None. Args: @@ -314,7 +310,7 @@ def to_payload(self, value: Any) -> Optional[temporalio.api.common.v1.Payload]: def from_payload( self, payload: temporalio.api.common.v1.Payload, - type_hint: Optional[Type] = None, + type_hint: type | None = None, ) -> Any: """Decode a single payload to a Python value or raise exception. @@ -359,7 +355,7 @@ def _set_converters(self, *converters: EncodingPayloadConverter) -> None: def to_payloads( self, values: Sequence[Any] - ) -> List[temporalio.api.common.v1.Payload]: + ) -> list[temporalio.api.common.v1.Payload]: """Encode values trying each converter. See base class. Always returns the same number of payloads as values. @@ -390,8 +386,8 @@ def to_payloads( def from_payloads( self, payloads: Sequence[temporalio.api.common.v1.Payload], - type_hints: Optional[List[Type]] = None, - ) -> List[Any]: + type_hints: list[type] | None = None, + ) -> list[Any]: """Decode values trying each converter. See base class. Always returns the same number of values as payloads. @@ -433,7 +429,7 @@ def with_context(self, context: SerializationContext) -> Self: def get_converters_with_context( self, context: SerializationContext - ) -> Optional[list[EncodingPayloadConverter]]: + ) -> list[EncodingPayloadConverter] | None: """Return converter instances with context set. If no converter uses context, return None. @@ -466,7 +462,7 @@ class DefaultPayloadConverter(CompositePayloadConverter): :py:attr:`PayloadConverter.default`. """ - default_encoding_payload_converters: Tuple[EncodingPayloadConverter, ...] + default_encoding_payload_converters: tuple[EncodingPayloadConverter, ...] """Default set of encoding payload converters the default payload converter uses. """ @@ -484,7 +480,7 @@ def encoding(self) -> str: """See base class.""" return "binary/null" - def to_payload(self, value: Any) -> Optional[temporalio.api.common.v1.Payload]: + def to_payload(self, value: Any) -> temporalio.api.common.v1.Payload | None: """See base class.""" if value is None: return temporalio.api.common.v1.Payload( @@ -495,7 +491,7 @@ def to_payload(self, value: Any) -> Optional[temporalio.api.common.v1.Payload]: def from_payload( self, payload: temporalio.api.common.v1.Payload, - type_hint: Optional[Type] = None, + type_hint: type | None = None, ) -> Any: """See base class.""" if len(payload.data) > 0: @@ -511,7 +507,7 @@ def encoding(self) -> str: """See base class.""" return "binary/plain" - def to_payload(self, value: Any) -> Optional[temporalio.api.common.v1.Payload]: + def to_payload(self, value: Any) -> temporalio.api.common.v1.Payload | None: """See base class.""" if isinstance(value, bytes): return temporalio.api.common.v1.Payload( @@ -522,7 +518,7 @@ def to_payload(self, value: Any) -> Optional[temporalio.api.common.v1.Payload]: def from_payload( self, payload: temporalio.api.common.v1.Payload, - type_hint: Optional[Type] = None, + type_hint: type | None = None, ) -> Any: """See base class.""" return payload.data @@ -549,7 +545,7 @@ def encoding(self) -> str: """See base class.""" return "json/protobuf" - def to_payload(self, value: Any) -> Optional[temporalio.api.common.v1.Payload]: + def to_payload(self, value: Any) -> temporalio.api.common.v1.Payload | None: """See base class.""" if ( isinstance(value, google.protobuf.message.Message) @@ -574,7 +570,7 @@ def to_payload(self, value: Any) -> Optional[temporalio.api.common.v1.Payload]: def from_payload( self, payload: temporalio.api.common.v1.Payload, - type_hint: Optional[Type] = None, + type_hint: type | None = None, ) -> Any: """See base class.""" message_type = payload.metadata.get("messageType", b"").decode() @@ -599,7 +595,7 @@ def encoding(self) -> str: """See base class.""" return "binary/protobuf" - def to_payload(self, value: Any) -> Optional[temporalio.api.common.v1.Payload]: + def to_payload(self, value: Any) -> temporalio.api.common.v1.Payload | None: """See base class.""" if ( isinstance(value, google.protobuf.message.Message) @@ -617,7 +613,7 @@ def to_payload(self, value: Any) -> Optional[temporalio.api.common.v1.Payload]: def from_payload( self, payload: temporalio.api.common.v1.Payload, - type_hint: Optional[Type] = None, + type_hint: type | None = None, ) -> Any: """See base class.""" message_type = payload.metadata.get("messageType", b"").decode() @@ -676,15 +672,15 @@ class JSONPlainPayloadConverter(EncodingPayloadConverter): type hint. """ - _encoder: Optional[Type[json.JSONEncoder]] - _decoder: Optional[Type[json.JSONDecoder]] + _encoder: type[json.JSONEncoder] | None + _decoder: type[json.JSONDecoder] | None _encoding: str def __init__( self, *, - encoder: Optional[Type[json.JSONEncoder]] = AdvancedJSONEncoder, - decoder: Optional[Type[json.JSONDecoder]] = None, + encoder: type[json.JSONEncoder] | None = AdvancedJSONEncoder, + decoder: type[json.JSONDecoder] | None = None, encoding: str = "json/plain", custom_type_converters: Sequence[JSONTypeConverter] = [], ) -> None: @@ -708,7 +704,7 @@ def encoding(self) -> str: """See base class.""" return self._encoding - def to_payload(self, value: Any) -> Optional[temporalio.api.common.v1.Payload]: + def to_payload(self, value: Any) -> temporalio.api.common.v1.Payload | None: """See base class.""" # Check for Pydantic v1 if hasattr(value, "parse_obj"): @@ -727,7 +723,7 @@ def to_payload(self, value: Any) -> Optional[temporalio.api.common.v1.Payload]: def from_payload( self, payload: temporalio.api.common.v1.Payload, - type_hint: Optional[Type] = None, + type_hint: type | None = None, ) -> Any: """See base class.""" try: @@ -754,8 +750,8 @@ class JSONTypeConverter(ABC): @abstractmethod def to_typed_value( - self, hint: Type, value: Any - ) -> Union[Optional[Any], _JSONTypeConverterUnhandled]: + self, hint: type, value: Any + ) -> Any | None | _JSONTypeConverterUnhandled: """Convert the given value to a type based on the given hint. Args: @@ -779,7 +775,7 @@ class PayloadCodec(ABC): @abstractmethod async def encode( self, payloads: Sequence[temporalio.api.common.v1.Payload] - ) -> List[temporalio.api.common.v1.Payload]: + ) -> list[temporalio.api.common.v1.Payload]: """Encode the given payloads. Args: @@ -795,7 +791,7 @@ async def encode( @abstractmethod async def decode( self, payloads: Sequence[temporalio.api.common.v1.Payload] - ) -> List[temporalio.api.common.v1.Payload]: + ) -> list[temporalio.api.common.v1.Payload]: """Decode the given payloads. Args: @@ -1113,7 +1109,7 @@ def from_failure( new_failure.CopyFrom(failure) failure = new_failure try: - encoded_attributes: Dict[str, Any] = payload_converter.from_payloads( + encoded_attributes: dict[str, Any] = payload_converter.from_payloads( [failure.encoded_attributes] )[0] if isinstance(encoded_attributes, dict): @@ -1126,7 +1122,7 @@ def from_failure( except: pass - err: Union[temporalio.exceptions.FailureError, nexusrpc.HandlerError] + err: temporalio.exceptions.FailureError | nexusrpc.HandlerError if failure.HasField("application_failure_info"): app_info = failure.application_failure_info err = temporalio.exceptions.ApplicationError( @@ -1257,13 +1253,13 @@ class DataConverter(WithSerializationContext): :py:class:`PayloadCodec` which encodes bytes. """ - payload_converter_class: Type[PayloadConverter] = DefaultPayloadConverter + payload_converter_class: type[PayloadConverter] = DefaultPayloadConverter """Class to instantiate for payload conversion.""" - payload_codec: Optional[PayloadCodec] = None + payload_codec: PayloadCodec | None = None """Optional codec for encoding payload bytes.""" - failure_converter_class: Type[FailureConverter] = DefaultFailureConverter + failure_converter_class: type[FailureConverter] = DefaultFailureConverter """Class to instantiate for failure conversion.""" payload_converter: PayloadConverter = dataclasses.field(init=False) @@ -1281,7 +1277,7 @@ def __post_init__(self) -> None: # noqa: D105 async def encode( self, values: Sequence[Any] - ) -> List[temporalio.api.common.v1.Payload]: + ) -> list[temporalio.api.common.v1.Payload]: """Encode values into payloads. First converts values to payloads then encodes payloads using codec. @@ -1302,8 +1298,8 @@ async def encode( async def decode( self, payloads: Sequence[temporalio.api.common.v1.Payload], - type_hints: Optional[List[Type]] = None, - ) -> List[Any]: + type_hints: list[type] | None = None, + ) -> list[Any]: """Decode payloads into values. First decodes payloads using codec then converts payloads to values. @@ -1328,9 +1324,9 @@ async def encode_wrapper( async def decode_wrapper( self, - payloads: Optional[temporalio.api.common.v1.Payloads], - type_hints: Optional[List[Type]] = None, - ) -> List[Any]: + payloads: temporalio.api.common.v1.Payloads | None, + type_hints: list[type] | None = None, + ) -> list[Any]: """:py:meth:`decode` for the :py:class:`temporalio.api.common.v1.Payloads` wrapper. """ @@ -1406,9 +1402,9 @@ def default() -> DataConverter: def encode_search_attributes( - attributes: Union[ - temporalio.common.SearchAttributes, temporalio.common.TypedSearchAttributes - ], + attributes: ( + temporalio.common.SearchAttributes | temporalio.common.TypedSearchAttributes + ), api: temporalio.api.common.v1.SearchAttributes, ) -> None: """Convert search attributes into an API message. @@ -1434,7 +1430,7 @@ def encode_typed_search_attribute_value( key: temporalio.common.SearchAttributeKey[ temporalio.common.SearchAttributeValueType ], - value: Optional[temporalio.common.SearchAttributeValue], + value: temporalio.common.SearchAttributeValue | None, ) -> temporalio.api.common.v1.Payload: """Convert typed search attribute value into a payload. @@ -1482,7 +1478,7 @@ def encode_search_attribute_values( if not isinstance(vals, list): raise TypeError("Search attribute values must be lists") # Confirm all types are the same - val_type: Optional[Type] = None + val_type: type | None = None # Convert dates to strings safe_vals = [] for v in vals: @@ -1507,8 +1503,8 @@ def encode_search_attribute_values( def _encode_maybe_typed_search_attributes( - non_typed_attributes: Optional[temporalio.common.SearchAttributes], - typed_attributes: Optional[temporalio.common.TypedSearchAttributes], + non_typed_attributes: temporalio.common.SearchAttributes | None, + typed_attributes: temporalio.common.TypedSearchAttributes | None, api: temporalio.api.common.v1.SearchAttributes, ) -> None: if non_typed_attributes: @@ -1575,7 +1571,7 @@ def decode_typed_search_attributes( Typed search attribute collection (new object every time). """ conv = default().payload_converter - pairs: List[temporalio.common.SearchAttributePair] = [] + pairs: list[temporalio.common.SearchAttributePair] = [] for k, v in api.indexed_fields.items(): # We want the "type" metadata, but if it is not present or an unknown # type, we will just ignore @@ -1621,7 +1617,7 @@ def _decode_search_attribute_value( def value_to_type( - hint: Type, + hint: type, value: Any, custom_converters: Sequence[JSONTypeConverter] = [], ) -> Any: @@ -1694,7 +1690,7 @@ def value_to_type( # Load origin for other checks origin = getattr(hint, "__origin__", hint) - type_args: Tuple = getattr(hint, "__args__", ()) + type_args: tuple = getattr(hint, "__args__", ()) # Literal if origin is Literal or origin is typing_extensions.Literal: @@ -1703,8 +1699,7 @@ def value_to_type( return value is_union = origin is Union - if sys.version_info >= (3, 10): - is_union = is_union or isinstance(origin, UnionType) + is_union = is_union or isinstance(origin, UnionType) # Union if is_union: @@ -1723,7 +1718,7 @@ def value_to_type( ret_dict = {} # If there are required or optional keys that means we are a TypedDict # and therefore can extract per-key types - per_key_types: Optional[Dict[str, Type]] = None + per_key_types: dict[str, type] | None = None if getattr(origin, "__required_keys__", None) or getattr( origin, "__optional_keys__", None ): diff --git a/temporalio/envconfig.py b/temporalio/envconfig.py index 6f016dc75..797d40d35 100644 --- a/temporalio/envconfig.py +++ b/temporalio/envconfig.py @@ -6,11 +6,12 @@ from __future__ import annotations +from collections.abc import Mapping from dataclasses import dataclass, field from pathlib import Path -from typing import Any, Dict, Literal, Mapping, Optional, Union, cast +from typing import Any, Dict, Literal, Optional, TypeAlias, Union, cast -from typing_extensions import Self, TypeAlias, TypedDict +from typing_extensions import Self, TypedDict import temporalio.service from temporalio.bridge.temporal_sdk_bridge import envconfig as _bridge_envconfig @@ -24,7 +25,7 @@ class ClientConfigTLSDict(TypedDict, total=False): """Dictionary representation of TLS config for TOML.""" - disabled: Optional[bool] + disabled: bool | None server_name: str server_ca_cert: Mapping[str, str] client_cert: Mapping[str, str] @@ -41,7 +42,7 @@ class ClientConfigProfileDict(TypedDict, total=False): grpc_meta: Mapping[str, str] -def _from_dict_to_source(d: Optional[Mapping[str, Any]]) -> Optional[DataSource]: +def _from_dict_to_source(d: Mapping[str, Any] | None) -> DataSource | None: if not d: return None if "data" in d: @@ -52,8 +53,8 @@ def _from_dict_to_source(d: Optional[Mapping[str, Any]]) -> Optional[DataSource] def _source_to_dict( - source: Optional[DataSource], -) -> Optional[Mapping[str, str]]: + source: DataSource | None, +) -> Mapping[str, str] | None: if isinstance(source, Path): return {"path": str(source)} if isinstance(source, str): @@ -64,10 +65,10 @@ def _source_to_dict( def _source_to_path_and_data( - source: Optional[DataSource], -) -> tuple[Optional[str], Optional[bytes]]: - path: Optional[str] = None - data: Optional[bytes] = None + source: DataSource | None, +) -> tuple[str | None, bytes | None]: + path: str | None = None + data: bytes | None = None if isinstance(source, Path): path = str(source) elif isinstance(source, str): @@ -82,7 +83,7 @@ def _source_to_path_and_data( return path, data -def _read_source(source: Optional[DataSource]) -> Optional[bytes]: +def _read_source(source: DataSource | None) -> bytes | None: if source is None: return None if isinstance(source, Path): @@ -105,15 +106,15 @@ class ClientConfigTLS: Experimental API. """ - disabled: Optional[bool] = None + disabled: bool | None = None """If True, TLS is explicitly disabled. If False, TLS is explicitly enabled. If None, TLS behavior was not configured.""" - server_name: Optional[str] = None + server_name: str | None = None """SNI override.""" - server_root_ca_cert: Optional[DataSource] = None + server_root_ca_cert: DataSource | None = None """Server CA certificate source.""" - client_cert: Optional[DataSource] = None + client_cert: DataSource | None = None """Client certificate source.""" - client_private_key: Optional[DataSource] = None + client_private_key: DataSource | None = None """Client key source.""" def to_dict(self) -> ClientConfigTLSDict: @@ -126,7 +127,7 @@ def to_dict(self) -> ClientConfigTLSDict: def set_source( key: Literal["server_ca_cert", "client_cert", "client_key"], - source: Optional[DataSource], + source: DataSource | None, ): if source is not None and (val := _source_to_dict(source)): d[key] = val @@ -136,7 +137,7 @@ def set_source( set_source("client_key", self.client_private_key) return d - def to_connect_tls_config(self) -> Union[bool, temporalio.service.TLSConfig]: + def to_connect_tls_config(self) -> bool | temporalio.service.TLSConfig: """Create a `temporalio.service.TLSConfig` from this profile.""" if self.disabled is True: return False @@ -149,7 +150,7 @@ def to_connect_tls_config(self) -> Union[bool, temporalio.service.TLSConfig]: ) @classmethod - def from_dict(cls, d: Optional[ClientConfigTLSDict]) -> Optional[Self]: + def from_dict(cls, d: ClientConfigTLSDict | None) -> Self | None: """Create a ClientConfigTLS from a dictionary.""" if not d: return None @@ -175,7 +176,7 @@ class ClientConnectConfig(TypedDict, total=False): target_host: str namespace: str api_key: str - tls: Union[bool, temporalio.service.TLSConfig] + tls: bool | temporalio.service.TLSConfig rpc_metadata: Mapping[str, str] @@ -191,13 +192,13 @@ class ClientConfigProfile: Experimental API. """ - address: Optional[str] = None + address: str | None = None """Client address.""" - namespace: Optional[str] = None + namespace: str | None = None """Client namespace.""" - api_key: Optional[str] = None + api_key: str | None = None """Client API key.""" - tls: Optional[ClientConfigTLS] = None + tls: ClientConfigTLS | None = None """TLS configuration.""" grpc_meta: Mapping[str, str] = field(default_factory=dict) """gRPC metadata.""" @@ -231,7 +232,7 @@ def to_dict(self) -> ClientConfigProfileDict: def to_client_connect_config(self) -> ClientConnectConfig: """Create a `ClientConnectConfig` from this profile.""" # Only include non-None values - config: Dict[str, Any] = {} + config: dict[str, Any] = {} if self.address: config["target_host"] = self.address if self.namespace is not None: @@ -251,13 +252,13 @@ def to_client_connect_config(self) -> ClientConnectConfig: @staticmethod def load( - profile: Optional[str] = None, + profile: str | None = None, *, - config_source: Optional[DataSource] = None, + config_source: DataSource | None = None, disable_file: bool = False, disable_env: bool = False, config_file_strict: bool = False, - override_env_vars: Optional[Mapping[str, str]] = None, + override_env_vars: Mapping[str, str] | None = None, ) -> ClientConfigProfile: """Load a single client profile from given sources, applying env overrides. @@ -336,9 +337,9 @@ def from_dict( @staticmethod def load( *, - config_source: Optional[DataSource] = None, + config_source: DataSource | None = None, config_file_strict: bool = False, - override_env_vars: Optional[Mapping[str, str]] = None, + override_env_vars: Mapping[str, str] | None = None, ) -> ClientConfig: """Load all client profiles from given sources. @@ -372,13 +373,13 @@ def load( @staticmethod def load_client_connect_config( - profile: Optional[str] = None, + profile: str | None = None, *, - config_file: Optional[str] = None, + config_file: str | None = None, disable_file: bool = False, disable_env: bool = False, config_file_strict: bool = False, - override_env_vars: Optional[Mapping[str, str]] = None, + override_env_vars: Mapping[str, str] | None = None, ) -> ClientConnectConfig: """Load a single client profile and convert to connect config. @@ -406,7 +407,7 @@ def load_client_connect_config( TypedDict of keyword arguments for :py:meth:`temporalio.client.Client.connect`. """ - config_source: Optional[DataSource] = None + config_source: DataSource | None = None if config_file and not disable_file: config_source = Path(config_file) diff --git a/temporalio/exceptions.py b/temporalio/exceptions.py index 74afb7ea7..61c04166d 100644 --- a/temporalio/exceptions.py +++ b/temporalio/exceptions.py @@ -1,9 +1,10 @@ """Common Temporal exceptions.""" import asyncio +from collections.abc import Sequence from datetime import timedelta from enum import IntEnum -from typing import Any, Optional, Sequence, Tuple +from typing import Any, Optional, Tuple import temporalio.api.common.v1 import temporalio.api.enums.v1 @@ -14,7 +15,7 @@ class TemporalError(Exception): """Base for all Temporal exceptions.""" @property - def cause(self) -> Optional[BaseException]: + def cause(self) -> BaseException | None: """Cause of the exception. This is the same as ``Exception.__cause__``. @@ -29,8 +30,8 @@ def __init__( self, message: str, *, - failure: Optional[temporalio.api.failure.v1.Failure] = None, - exc_args: Optional[Tuple] = None, + failure: temporalio.api.failure.v1.Failure | None = None, + exc_args: tuple | None = None, ) -> None: """Initialize a failure error.""" if exc_args is None: @@ -45,7 +46,7 @@ def message(self) -> str: return self._message @property - def failure(self) -> Optional[temporalio.api.failure.v1.Failure]: + def failure(self) -> temporalio.api.failure.v1.Failure | None: """Underlying protobuf failure object.""" return self._failure @@ -61,7 +62,7 @@ class WorkflowAlreadyStartedError(FailureError): """ def __init__( - self, workflow_id: str, workflow_type: str, *, run_id: Optional[str] = None + self, workflow_id: str, workflow_type: str, *, run_id: str | None = None ) -> None: """Initialize a workflow already started error.""" super().__init__("Workflow execution already started") @@ -90,9 +91,9 @@ def __init__( self, message: str, *details: Any, - type: Optional[str] = None, + type: str | None = None, non_retryable: bool = False, - next_retry_delay: Optional[timedelta] = None, + next_retry_delay: timedelta | None = None, category: ApplicationErrorCategory = ApplicationErrorCategory.UNSPECIFIED, ) -> None: """Initialize an application error.""" @@ -113,7 +114,7 @@ def details(self) -> Sequence[Any]: return self._details @property - def type(self) -> Optional[str]: + def type(self) -> str | None: """General error type.""" return self._type @@ -128,7 +129,7 @@ def non_retryable(self) -> bool: return self._non_retryable @property - def next_retry_delay(self) -> Optional[timedelta]: + def next_retry_delay(self) -> timedelta | None: """Delay before the next activity retry attempt. User activity code may set this when raising ApplicationError to specify @@ -192,7 +193,7 @@ def __init__( self, message: str, *, - type: Optional[TimeoutType], + type: TimeoutType | None, last_heartbeat_details: Sequence[Any], ) -> None: """Initialize a timeout error.""" @@ -201,7 +202,7 @@ def __init__( self._last_heartbeat_details = last_heartbeat_details @property - def type(self) -> Optional[TimeoutType]: + def type(self) -> TimeoutType | None: """Type of timeout error.""" return self._type @@ -259,7 +260,7 @@ def __init__( identity: str, activity_type: str, activity_id: str, - retry_state: Optional[RetryState], + retry_state: RetryState | None, ) -> None: """Initialize an activity error.""" super().__init__(message) @@ -296,7 +297,7 @@ def activity_id(self) -> str: return self._activity_id @property - def retry_state(self) -> Optional[RetryState]: + def retry_state(self) -> RetryState | None: """Retry state for this error.""" return self._retry_state @@ -314,7 +315,7 @@ def __init__( workflow_type: str, initiated_event_id: int, started_event_id: int, - retry_state: Optional[RetryState], + retry_state: RetryState | None, ) -> None: """Initialize a child workflow error.""" super().__init__(message) @@ -357,7 +358,7 @@ def started_event_id(self) -> int: return self._started_event_id @property - def retry_state(self) -> Optional[RetryState]: + def retry_state(self) -> RetryState | None: """Retry state for this error.""" return self._retry_state diff --git a/temporalio/nexus/_decorators.py b/temporalio/nexus/_decorators.py index 3c97482ff..dfdecc89c 100644 --- a/temporalio/nexus/_decorators.py +++ b/temporalio/nexus/_decorators.py @@ -1,8 +1,7 @@ from __future__ import annotations +from collections.abc import Awaitable, Callable from typing import ( - Awaitable, - Callable, Optional, TypeVar, Union, @@ -43,7 +42,7 @@ def workflow_run_operation( @overload def workflow_run_operation( *, - name: Optional[str] = None, + name: str | None = None, ) -> Callable[ [ Callable[ @@ -59,20 +58,21 @@ def workflow_run_operation( def workflow_run_operation( - start: Optional[ + start: None + | ( Callable[ [ServiceHandlerT, WorkflowRunOperationContext, InputT], Awaitable[WorkflowHandle[OutputT]], ] - ] = None, + ) = None, *, - name: Optional[str] = None, -) -> Union[ + name: str | None = None, +) -> ( Callable[ [ServiceHandlerT, WorkflowRunOperationContext, InputT], Awaitable[WorkflowHandle[OutputT]], - ], - Callable[ + ] + | Callable[ [ Callable[ [ServiceHandlerT, WorkflowRunOperationContext, InputT], @@ -83,8 +83,8 @@ def workflow_run_operation( [ServiceHandlerT, WorkflowRunOperationContext, InputT], Awaitable[WorkflowHandle[OutputT]], ], - ], -]: + ] +): """Decorator marking a method as the start method for a workflow-backed operation.""" def decorator( diff --git a/temporalio/nexus/_link_conversion.py b/temporalio/nexus/_link_conversion.py index 1445b2a0d..b2a219f96 100644 --- a/temporalio/nexus/_link_conversion.py +++ b/temporalio/nexus/_link_conversion.py @@ -86,7 +86,7 @@ def workflow_event_to_nexus_link( def nexus_link_to_workflow_event( link: nexusrpc.Link, -) -> Optional[temporalio.api.common.v1.Link.WorkflowEvent]: +) -> temporalio.api.common.v1.Link.WorkflowEvent | None: """Convert a nexus link into a WorkflowEvent link This is used when propagating links from a Nexus start operation request to a diff --git a/temporalio/nexus/_operation_context.py b/temporalio/nexus/_operation_context.py index 098bba8a1..79e35c95c 100644 --- a/temporalio/nexus/_operation_context.py +++ b/temporalio/nexus/_operation_context.py @@ -2,7 +2,14 @@ import dataclasses import logging -from collections.abc import Awaitable, Mapping, MutableMapping, Sequence +from collections.abc import ( + Awaitable, + Callable, + Generator, + Mapping, + MutableMapping, + Sequence, +) from contextlib import contextmanager from contextvars import ContextVar from dataclasses import dataclass @@ -10,15 +17,13 @@ from typing import ( TYPE_CHECKING, Any, - Callable, - Generator, + Concatenate, Optional, Union, overload, ) from nexusrpc.handler import CancelOperationContext, StartOperationContext -from typing_extensions import Concatenate import temporalio.api.common.v1 import temporalio.api.workflowservice.v1 @@ -88,7 +93,7 @@ def client() -> temporalio.client.Client: def _temporal_context() -> ( - Union[_TemporalStartOperationContext, _TemporalCancelOperationContext] + _TemporalStartOperationContext | _TemporalCancelOperationContext ): ctx = _try_temporal_context() if ctx is None: @@ -97,7 +102,7 @@ def _temporal_context() -> ( def _try_temporal_context() -> ( - Optional[Union[_TemporalStartOperationContext, _TemporalCancelOperationContext]] + _TemporalStartOperationContext | _TemporalCancelOperationContext | None ): start_ctx = _temporal_start_operation_context.get(None) cancel_ctx = _temporal_cancel_operation_context.get(None) @@ -107,7 +112,7 @@ def _try_temporal_context() -> ( @contextmanager -def _nexus_backing_workflow_start_context() -> Generator[None, None, None]: +def _nexus_backing_workflow_start_context() -> Generator[None]: token = _temporal_nexus_backing_workflow_start_context.set(True) try: yield @@ -225,31 +230,29 @@ async def start_workflow( workflow: MethodAsyncNoParam[SelfType, ReturnType], *, id: str, - task_queue: Optional[str] = None, - execution_timeout: Optional[timedelta] = None, - run_timeout: Optional[timedelta] = None, - task_timeout: Optional[timedelta] = None, + task_queue: str | None = None, + execution_timeout: timedelta | None = None, + run_timeout: timedelta | None = None, + task_timeout: timedelta | None = None, id_reuse_policy: temporalio.common.WorkflowIDReusePolicy = temporalio.common.WorkflowIDReusePolicy.ALLOW_DUPLICATE, id_conflict_policy: temporalio.common.WorkflowIDConflictPolicy = temporalio.common.WorkflowIDConflictPolicy.UNSPECIFIED, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cron_schedule: str = "", - memo: Optional[Mapping[str, Any]] = None, - search_attributes: Optional[ - Union[ - temporalio.common.TypedSearchAttributes, - temporalio.common.SearchAttributes, - ] - ] = None, - static_summary: Optional[str] = None, - static_details: Optional[str] = None, - start_delay: Optional[timedelta] = None, - start_signal: Optional[str] = None, + memo: Mapping[str, Any] | None = None, + search_attributes: None + | ( + temporalio.common.TypedSearchAttributes | temporalio.common.SearchAttributes + ) = None, + static_summary: str | None = None, + static_details: str | None = None, + start_delay: timedelta | None = None, + start_signal: str | None = None, start_signal_args: Sequence[Any] = [], - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, request_eager_start: bool = False, priority: temporalio.common.Priority = temporalio.common.Priority.default, - versioning_override: Optional[temporalio.common.VersioningOverride] = None, + versioning_override: temporalio.common.VersioningOverride | None = None, ) -> WorkflowHandle[ReturnType]: ... # Overload for single-param workflow @@ -260,31 +263,29 @@ async def start_workflow( arg: ParamType, *, id: str, - task_queue: Optional[str] = None, - execution_timeout: Optional[timedelta] = None, - run_timeout: Optional[timedelta] = None, - task_timeout: Optional[timedelta] = None, + task_queue: str | None = None, + execution_timeout: timedelta | None = None, + run_timeout: timedelta | None = None, + task_timeout: timedelta | None = None, id_reuse_policy: temporalio.common.WorkflowIDReusePolicy = temporalio.common.WorkflowIDReusePolicy.ALLOW_DUPLICATE, id_conflict_policy: temporalio.common.WorkflowIDConflictPolicy = temporalio.common.WorkflowIDConflictPolicy.UNSPECIFIED, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cron_schedule: str = "", - memo: Optional[Mapping[str, Any]] = None, - search_attributes: Optional[ - Union[ - temporalio.common.TypedSearchAttributes, - temporalio.common.SearchAttributes, - ] - ] = None, - static_summary: Optional[str] = None, - static_details: Optional[str] = None, - start_delay: Optional[timedelta] = None, - start_signal: Optional[str] = None, + memo: Mapping[str, Any] | None = None, + search_attributes: None + | ( + temporalio.common.TypedSearchAttributes | temporalio.common.SearchAttributes + ) = None, + static_summary: str | None = None, + static_details: str | None = None, + start_delay: timedelta | None = None, + start_signal: str | None = None, start_signal_args: Sequence[Any] = [], - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, request_eager_start: bool = False, priority: temporalio.common.Priority = temporalio.common.Priority.default, - versioning_override: Optional[temporalio.common.VersioningOverride] = None, + versioning_override: temporalio.common.VersioningOverride | None = None, ) -> WorkflowHandle[ReturnType]: ... # Overload for multi-param workflow @@ -297,31 +298,29 @@ async def start_workflow( *, args: Sequence[Any], id: str, - task_queue: Optional[str] = None, - execution_timeout: Optional[timedelta] = None, - run_timeout: Optional[timedelta] = None, - task_timeout: Optional[timedelta] = None, + task_queue: str | None = None, + execution_timeout: timedelta | None = None, + run_timeout: timedelta | None = None, + task_timeout: timedelta | None = None, id_reuse_policy: temporalio.common.WorkflowIDReusePolicy = temporalio.common.WorkflowIDReusePolicy.ALLOW_DUPLICATE, id_conflict_policy: temporalio.common.WorkflowIDConflictPolicy = temporalio.common.WorkflowIDConflictPolicy.UNSPECIFIED, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cron_schedule: str = "", - memo: Optional[Mapping[str, Any]] = None, - search_attributes: Optional[ - Union[ - temporalio.common.TypedSearchAttributes, - temporalio.common.SearchAttributes, - ] - ] = None, - static_summary: Optional[str] = None, - static_details: Optional[str] = None, - start_delay: Optional[timedelta] = None, - start_signal: Optional[str] = None, + memo: Mapping[str, Any] | None = None, + search_attributes: None + | ( + temporalio.common.TypedSearchAttributes | temporalio.common.SearchAttributes + ) = None, + static_summary: str | None = None, + static_details: str | None = None, + start_delay: timedelta | None = None, + start_signal: str | None = None, start_signal_args: Sequence[Any] = [], - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, request_eager_start: bool = False, priority: temporalio.common.Priority = temporalio.common.Priority.default, - versioning_override: Optional[temporalio.common.VersioningOverride] = None, + versioning_override: temporalio.common.VersioningOverride | None = None, ) -> WorkflowHandle[ReturnType]: ... # Overload for string-name workflow @@ -333,67 +332,63 @@ async def start_workflow( *, args: Sequence[Any] = [], id: str, - task_queue: Optional[str] = None, - result_type: Optional[type[ReturnType]] = None, - execution_timeout: Optional[timedelta] = None, - run_timeout: Optional[timedelta] = None, - task_timeout: Optional[timedelta] = None, + task_queue: str | None = None, + result_type: type[ReturnType] | None = None, + execution_timeout: timedelta | None = None, + run_timeout: timedelta | None = None, + task_timeout: timedelta | None = None, id_reuse_policy: temporalio.common.WorkflowIDReusePolicy = temporalio.common.WorkflowIDReusePolicy.ALLOW_DUPLICATE, id_conflict_policy: temporalio.common.WorkflowIDConflictPolicy = temporalio.common.WorkflowIDConflictPolicy.UNSPECIFIED, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cron_schedule: str = "", - memo: Optional[Mapping[str, Any]] = None, - search_attributes: Optional[ - Union[ - temporalio.common.TypedSearchAttributes, - temporalio.common.SearchAttributes, - ] - ] = None, - static_summary: Optional[str] = None, - static_details: Optional[str] = None, - start_delay: Optional[timedelta] = None, - start_signal: Optional[str] = None, + memo: Mapping[str, Any] | None = None, + search_attributes: None + | ( + temporalio.common.TypedSearchAttributes | temporalio.common.SearchAttributes + ) = None, + static_summary: str | None = None, + static_details: str | None = None, + start_delay: timedelta | None = None, + start_signal: str | None = None, start_signal_args: Sequence[Any] = [], - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, request_eager_start: bool = False, priority: temporalio.common.Priority = temporalio.common.Priority.default, - versioning_override: Optional[temporalio.common.VersioningOverride] = None, + versioning_override: temporalio.common.VersioningOverride | None = None, ) -> WorkflowHandle[ReturnType]: ... async def start_workflow( self, - workflow: Union[str, Callable[..., Awaitable[ReturnType]]], + workflow: str | Callable[..., Awaitable[ReturnType]], arg: Any = temporalio.common._arg_unset, *, args: Sequence[Any] = [], id: str, - task_queue: Optional[str] = None, - result_type: Optional[type] = None, - execution_timeout: Optional[timedelta] = None, - run_timeout: Optional[timedelta] = None, - task_timeout: Optional[timedelta] = None, + task_queue: str | None = None, + result_type: type | None = None, + execution_timeout: timedelta | None = None, + run_timeout: timedelta | None = None, + task_timeout: timedelta | None = None, id_reuse_policy: temporalio.common.WorkflowIDReusePolicy = temporalio.common.WorkflowIDReusePolicy.ALLOW_DUPLICATE, id_conflict_policy: temporalio.common.WorkflowIDConflictPolicy = temporalio.common.WorkflowIDConflictPolicy.UNSPECIFIED, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cron_schedule: str = "", - memo: Optional[Mapping[str, Any]] = None, - search_attributes: Optional[ - Union[ - temporalio.common.TypedSearchAttributes, - temporalio.common.SearchAttributes, - ] - ] = None, - static_summary: Optional[str] = None, - static_details: Optional[str] = None, - start_delay: Optional[timedelta] = None, - start_signal: Optional[str] = None, + memo: Mapping[str, Any] | None = None, + search_attributes: None + | ( + temporalio.common.TypedSearchAttributes | temporalio.common.SearchAttributes + ) = None, + static_summary: str | None = None, + static_details: str | None = None, + start_delay: timedelta | None = None, + start_signal: str | None = None, start_signal_args: Sequence[Any] = [], - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, request_eager_start: bool = False, priority: temporalio.common.Priority = temporalio.common.Priority.default, - versioning_override: Optional[temporalio.common.VersioningOverride] = None, + versioning_override: temporalio.common.VersioningOverride | None = None, ) -> WorkflowHandle[ReturnType]: """Start a workflow that will deliver the result of the Nexus operation. @@ -508,7 +503,7 @@ def set(self) -> None: class LoggerAdapter(logging.LoggerAdapter): """Logger adapter that adds Nexus operation context information.""" - def __init__(self, logger: logging.Logger, extra: Optional[Mapping[str, Any]]): + def __init__(self, logger: logging.Logger, extra: Mapping[str, Any] | None): """Initialize the logger adapter.""" super().__init__(logger, extra or {}) diff --git a/temporalio/nexus/_operation_handlers.py b/temporalio/nexus/_operation_handlers.py index aa5351353..6f6480d21 100644 --- a/temporalio/nexus/_operation_handlers.py +++ b/temporalio/nexus/_operation_handlers.py @@ -1,9 +1,8 @@ from __future__ import annotations +from collections.abc import Awaitable, Callable from typing import ( Any, - Awaitable, - Callable, ) from nexusrpc import ( diff --git a/temporalio/nexus/_token.py b/temporalio/nexus/_token.py index 999e33767..a19d26d05 100644 --- a/temporalio/nexus/_token.py +++ b/temporalio/nexus/_token.py @@ -30,12 +30,12 @@ class WorkflowHandle(Generic[OutputT]): workflow_id: str # Version of the token. Treated as v1 if missing. This field is not included in the # serialized token; it's only used to reject newer token versions on load. - version: Optional[int] = None + version: int | None = None def _to_client_workflow_handle( self, client: temporalio.client.Client, - result_type: Optional[type[OutputT]] = None, + result_type: type[OutputT] | None = None, ) -> temporalio.client.WorkflowHandle[Any, OutputT]: """Create a :py:class:`temporalio.client.WorkflowHandle` from the token.""" if client.namespace != self.namespace: diff --git a/temporalio/nexus/_util.py b/temporalio/nexus/_util.py index de5bf94b2..843aa50d3 100644 --- a/temporalio/nexus/_util.py +++ b/temporalio/nexus/_util.py @@ -4,10 +4,9 @@ import inspect import typing import warnings +from collections.abc import Awaitable, Callable from typing import ( Any, - Awaitable, - Callable, Optional, Type, TypeVar, @@ -34,8 +33,8 @@ def get_workflow_run_start_method_input_and_output_type_annotations( Awaitable[WorkflowHandle[OutputT]], ], ) -> tuple[ - Optional[Type[InputT]], - Optional[Type[OutputT]], + type[InputT] | None, + type[OutputT] | None, ]: """Return operation input and output types. @@ -73,8 +72,8 @@ def _get_start_method_input_and_output_type_annotations( Awaitable[WorkflowHandle[OutputT]], ], ) -> tuple[ - Optional[Type[InputT]], - Optional[Type[OutputT]], + type[InputT] | None, + type[OutputT] | None, ]: try: type_annotations = typing.get_type_hints(start) @@ -122,8 +121,8 @@ def get_callable_name(fn: Callable[..., Any]) -> str: def get_operation_factory( obj: Any, ) -> tuple[ - Optional[Callable[[Any], Any]], - Optional[nexusrpc.Operation[Any, Any]], + Callable[[Any], Any] | None, + nexusrpc.Operation[Any, Any] | None, ]: """Return the :py:class:`Operation` for the object along with the factory function. diff --git a/temporalio/plugin.py b/temporalio/plugin.py index 04435c7e8..9202bc1f3 100644 --- a/temporalio/plugin.py +++ b/temporalio/plugin.py @@ -4,14 +4,11 @@ and worker behavior in the Temporal SDK through configurable parameters. """ +from collections.abc import AsyncIterator, Awaitable, Callable, Sequence from contextlib import AbstractAsyncContextManager, asynccontextmanager from typing import ( Any, - AsyncIterator, - Awaitable, - Callable, Optional, - Sequence, Type, TypeVar, Union, @@ -52,15 +49,15 @@ def __init__( ] = None, activities: PluginParameter[Sequence[Callable]] = None, nexus_service_handlers: PluginParameter[Sequence[Any]] = None, - workflows: PluginParameter[Sequence[Type]] = None, + workflows: PluginParameter[Sequence[type]] = None, workflow_runner: PluginParameter[WorkflowRunner] = None, worker_interceptors: PluginParameter[ Sequence[temporalio.worker.Interceptor] ] = None, workflow_failure_exception_types: PluginParameter[ - Sequence[Type[BaseException]] + Sequence[type[BaseException]] ] = None, - run_context: Optional[Callable[[], AbstractAsyncContextManager[None]]] = None, + run_context: Callable[[], AbstractAsyncContextManager[None]] | None = None, ) -> None: """Create a simple plugin with configurable parameters. Each of the parameters will be applied to any component for which they are applicable. All arguments are optional, and all but run_context can also @@ -233,9 +230,7 @@ async def run_replayer( yield results -def _resolve_parameter( - existing: Optional[T], parameter: PluginParameter[T] -) -> Optional[T]: +def _resolve_parameter(existing: T | None, parameter: PluginParameter[T]) -> T | None: if parameter is None: return existing elif callable(parameter): @@ -245,8 +240,8 @@ def _resolve_parameter( def _resolve_append_parameter( - existing: Optional[Sequence[T]], parameter: PluginParameter[Sequence[T]] -) -> Optional[Sequence[T]]: + existing: Sequence[T] | None, parameter: PluginParameter[Sequence[T]] +) -> Sequence[T] | None: if parameter is None: return existing elif callable(parameter): diff --git a/temporalio/runtime.py b/temporalio/runtime.py index c3546c900..acd9f17df 100644 --- a/temporalio/runtime.py +++ b/temporalio/runtime.py @@ -4,16 +4,15 @@ import logging import time +from collections.abc import Mapping, Sequence from dataclasses import dataclass, field from datetime import timedelta from enum import Enum from typing import ( ClassVar, Generic, - Mapping, NewType, Optional, - Sequence, TypeVar, Union, ) @@ -121,7 +120,7 @@ def __init__( self, *, telemetry: TelemetryConfig, - worker_heartbeat_interval: Optional[timedelta] = timedelta(seconds=60), + worker_heartbeat_interval: timedelta | None = timedelta(seconds=60), ) -> None: """Create a runtime with the provided configuration. @@ -198,10 +197,10 @@ def formatted(self) -> str: class LoggingConfig: """Configuration for runtime logging.""" - filter: Union[TelemetryFilter, str] + filter: TelemetryFilter | str """Filter for logging. Can use :py:class:`TelemetryFilter` or raw string.""" - forwarding: Optional[LogForwardingConfig] = None + forwarding: LogForwardingConfig | None = None """If present, Core logger messages will be forwarded to a Python logger. See the :py:class:`LogForwardingConfig` docs for more info. """ @@ -323,8 +322,8 @@ class OpenTelemetryConfig: """Configuration for OpenTelemetry collector.""" url: str - headers: Optional[Mapping[str, str]] = None - metric_periodicity: Optional[timedelta] = None + headers: Mapping[str, str] | None = None + metric_periodicity: timedelta | None = None metric_temporality: OpenTelemetryMetricTemporality = ( OpenTelemetryMetricTemporality.CUMULATIVE ) @@ -356,7 +355,7 @@ class PrometheusConfig: counters_total_suffix: bool = False unit_suffix: bool = False durations_as_seconds: bool = False - histogram_bucket_overrides: Optional[Mapping[str, Sequence[float]]] = None + histogram_bucket_overrides: Mapping[str, Sequence[float]] | None = None def _to_bridge_config(self) -> temporalio.bridge.runtime.PrometheusConfig: return temporalio.bridge.runtime.PrometheusConfig( @@ -406,7 +405,7 @@ def __init__( duration_format: Which duration format to use. """ self._buffer_size = buffer_size - self._runtime: Optional[Runtime] = None + self._runtime: Runtime | None = None self._durations_as_seconds = ( duration_format == MetricBufferDurationFormat.SECONDS ) @@ -432,10 +431,10 @@ def retrieve_updates(self) -> Sequence[BufferedMetricUpdate]: class TelemetryConfig: """Configuration for Core telemetry.""" - logging: Optional[LoggingConfig] = LoggingConfig.default + logging: LoggingConfig | None = LoggingConfig.default """Logging configuration.""" - metrics: Optional[Union[OpenTelemetryConfig, PrometheusConfig, MetricBuffer]] = None + metrics: OpenTelemetryConfig | PrometheusConfig | MetricBuffer | None = None """Metrics configuration or buffer.""" global_tags: Mapping[str, str] = field(default_factory=dict) @@ -444,7 +443,7 @@ class TelemetryConfig: attach_service_name: bool = True """Whether to put the service_name on every metric.""" - metric_prefix: Optional[str] = None + metric_prefix: str | None = None """Prefix to put on every Temporal metric. If unset, defaults to ``temporal_``.""" @@ -498,12 +497,12 @@ def name(self) -> str: ... @property - def description(self) -> Optional[str]: + def description(self) -> str | None: """Get the description of the metric if any.""" ... @property - def unit(self) -> Optional[str]: + def unit(self) -> str | None: """Get the unit of the metric if any.""" ... @@ -533,7 +532,7 @@ def metric(self) -> BufferedMetric: ... @property - def value(self) -> Union[int, float]: + def value(self) -> int | float: """Value for the update. For counters this is a delta, for gauges and histograms this is just the @@ -566,7 +565,7 @@ def __init__( self._core_attrs = core_attrs def create_counter( - self, name: str, description: Optional[str] = None, unit: Optional[str] = None + self, name: str, description: str | None = None, unit: str | None = None ) -> temporalio.common.MetricCounter: return _MetricCounter( name, @@ -579,7 +578,7 @@ def create_counter( ) def create_histogram( - self, name: str, description: Optional[str] = None, unit: Optional[str] = None + self, name: str, description: str | None = None, unit: str | None = None ) -> temporalio.common.MetricHistogram: return _MetricHistogram( name, @@ -592,7 +591,7 @@ def create_histogram( ) def create_histogram_float( - self, name: str, description: Optional[str] = None, unit: Optional[str] = None + self, name: str, description: str | None = None, unit: str | None = None ) -> temporalio.common.MetricHistogramFloat: return _MetricHistogramFloat( name, @@ -605,7 +604,7 @@ def create_histogram_float( ) def create_histogram_timedelta( - self, name: str, description: Optional[str] = None, unit: Optional[str] = None + self, name: str, description: str | None = None, unit: str | None = None ) -> temporalio.common.MetricHistogramTimedelta: return _MetricHistogramTimedelta( name, @@ -618,7 +617,7 @@ def create_histogram_timedelta( ) def create_gauge( - self, name: str, description: Optional[str] = None, unit: Optional[str] = None + self, name: str, description: str | None = None, unit: str | None = None ) -> temporalio.common.MetricGauge: return _MetricGauge( name, @@ -631,7 +630,7 @@ def create_gauge( ) def create_gauge_float( - self, name: str, description: Optional[str] = None, unit: Optional[str] = None + self, name: str, description: str | None = None, unit: str | None = None ) -> temporalio.common.MetricGaugeFloat: return _MetricGaugeFloat( name, @@ -659,8 +658,8 @@ class _MetricCommon(temporalio.common.MetricCommon, Generic[_CoreMetricType]): def __init__( self, name: str, - description: Optional[str], - unit: Optional[str], + description: str | None, + unit: str | None, core_metric: _CoreMetricType, core_attrs: temporalio.bridge.metric.MetricAttributes, ) -> None: @@ -675,11 +674,11 @@ def name(self) -> str: return self._name @property - def description(self) -> Optional[str]: + def description(self) -> str | None: return self._description @property - def unit(self) -> Optional[str]: + def unit(self) -> str | None: return self._unit def with_additional_attributes( @@ -701,7 +700,7 @@ class _MetricCounter( def add( self, value: int, - additional_attributes: Optional[temporalio.common.MetricAttributes] = None, + additional_attributes: temporalio.common.MetricAttributes | None = None, ) -> None: if value < 0: raise ValueError("Metric value cannot be negative") @@ -718,7 +717,7 @@ class _MetricHistogram( def record( self, value: int, - additional_attributes: Optional[temporalio.common.MetricAttributes] = None, + additional_attributes: temporalio.common.MetricAttributes | None = None, ) -> None: if value < 0: raise ValueError("Metric value cannot be negative") @@ -735,7 +734,7 @@ class _MetricHistogramFloat( def record( self, value: float, - additional_attributes: Optional[temporalio.common.MetricAttributes] = None, + additional_attributes: temporalio.common.MetricAttributes | None = None, ) -> None: if value < 0: raise ValueError("Metric value cannot be negative") @@ -752,7 +751,7 @@ class _MetricHistogramTimedelta( def record( self, value: timedelta, - additional_attributes: Optional[temporalio.common.MetricAttributes] = None, + additional_attributes: temporalio.common.MetricAttributes | None = None, ) -> None: if value.days < 0: raise ValueError("Metric value cannot be negative") @@ -773,7 +772,7 @@ class _MetricGauge( def set( self, value: int, - additional_attributes: Optional[temporalio.common.MetricAttributes] = None, + additional_attributes: temporalio.common.MetricAttributes | None = None, ) -> None: if value < 0: raise ValueError("Metric value cannot be negative") @@ -790,7 +789,7 @@ class _MetricGaugeFloat( def set( self, value: float, - additional_attributes: Optional[temporalio.common.MetricAttributes] = None, + additional_attributes: temporalio.common.MetricAttributes | None = None, ) -> None: if value < 0: raise ValueError("Metric value cannot be negative") diff --git a/temporalio/service.py b/temporalio/service.py index 349bce763..bde62e429 100644 --- a/temporalio/service.py +++ b/temporalio/service.py @@ -8,10 +8,11 @@ import socket import warnings from abc import ABC, abstractmethod +from collections.abc import Mapping from dataclasses import dataclass, field from datetime import timedelta from enum import IntEnum -from typing import ClassVar, Mapping, Optional, Tuple, Type, TypeVar, Union +from typing import ClassVar, Optional, Tuple, Type, TypeVar, Union import google.protobuf.message @@ -37,18 +38,18 @@ class TLSConfig: """TLS configuration for connecting to Temporal server.""" - server_root_ca_cert: Optional[bytes] = None + server_root_ca_cert: bytes | None = None """Root CA to validate the server certificate against.""" - domain: Optional[str] = None + domain: str | None = None """TLS domain.""" - client_cert: Optional[bytes] = None + client_cert: bytes | None = None """Client certificate for mTLS. This must be combined with :py:attr:`client_private_key`.""" - client_private_key: Optional[bytes] = None + client_private_key: bytes | None = None """Client private key for mTLS. This must be combined with :py:attr:`client_cert`.""" @@ -74,7 +75,7 @@ class RetryConfig: """Backoff multiplier.""" max_interval_millis: int = 5000 """Maximum backoff interval.""" - max_elapsed_time_millis: Optional[int] = 10000 + max_elapsed_time_millis: int | None = 10000 """Maximum total time.""" max_retries: int = 10 """Maximum number of retries.""" @@ -118,7 +119,7 @@ class HttpConnectProxyConfig: target_host: str """Target host:port for the HTTP CONNECT proxy.""" - basic_auth: Optional[Tuple[str, str]] = None + basic_auth: tuple[str, str] | None = None """Basic auth for the HTTP CONNECT proxy if any as a user/pass tuple.""" def _to_bridge_config( @@ -135,15 +136,15 @@ class ConnectConfig: """Config for connecting to the server.""" target_host: str - api_key: Optional[str] = None - tls: Union[bool, TLSConfig, None] = None - retry_config: Optional[RetryConfig] = None - keep_alive_config: Optional[KeepAliveConfig] = KeepAliveConfig.default - rpc_metadata: Mapping[str, Union[str, bytes]] = field(default_factory=dict) + api_key: str | None = None + tls: bool | TLSConfig | None = None + retry_config: RetryConfig | None = None + keep_alive_config: KeepAliveConfig | None = KeepAliveConfig.default + rpc_metadata: Mapping[str, str | bytes] = field(default_factory=dict) identity: str = "" lazy: bool = False - runtime: Optional[temporalio.runtime.Runtime] = None - http_connect_proxy_config: Optional[HttpConnectProxyConfig] = None + runtime: temporalio.runtime.Runtime | None = None + http_connect_proxy_config: HttpConnectProxyConfig | None = None def __post_init__(self) -> None: """Set extra defaults on unset properties.""" @@ -155,7 +156,7 @@ def _to_bridge_config(self) -> temporalio.bridge.client.ClientConfig: # past so we'll leave it for only one more version with a warning. # Otherwise we'll prepend the scheme. target_url: str - tls_config: Optional[temporalio.bridge.client.ClientTlsConfig] + tls_config: temporalio.bridge.client.ClientTlsConfig | None if "://" in self.target_host: warnings.warn( "Target host as URL with scheme no longer supported. This will be an error in future versions." @@ -227,8 +228,8 @@ async def check_health( *, service: str = "temporal.api.workflowservice.v1.WorkflowService", retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> bool: """Check whether the WorkflowService is up. @@ -260,12 +261,12 @@ def worker_service_client(self) -> _BridgeServiceClient: raise NotImplementedError @abstractmethod - def update_rpc_metadata(self, metadata: Mapping[str, Union[str, bytes]]) -> None: + def update_rpc_metadata(self, metadata: Mapping[str, str | bytes]) -> None: """Update service client's RPC metadata.""" raise NotImplementedError @abstractmethod - def update_api_key(self, api_key: Optional[str]) -> None: + def update_api_key(self, api_key: str | None) -> None: """Update service client's API key.""" raise NotImplementedError @@ -274,12 +275,12 @@ async def _rpc_call( self, rpc: str, req: google.protobuf.message.Message, - resp_type: Type[ServiceResponse], + resp_type: type[ServiceResponse], *, service: str, retry: bool, - metadata: Mapping[str, Union[str, bytes]], - timeout: Optional[timedelta], + metadata: Mapping[str, str | bytes], + timeout: timedelta | None, ) -> ServiceResponse: raise NotImplementedError @@ -316,7 +317,7 @@ async def connect(config: ConnectConfig) -> _BridgeServiceClient: def __init__(self, config: ConnectConfig) -> None: super().__init__(config) self._bridge_config = config._to_bridge_config() - self._bridge_client: Optional[temporalio.bridge.client.Client] = None + self._bridge_client: temporalio.bridge.client.Client | None = None self._bridge_client_connect_lock = asyncio.Lock() async def _connected_client(self) -> temporalio.bridge.client.Client: @@ -334,7 +335,7 @@ def worker_service_client(self) -> _BridgeServiceClient: """Underlying service client.""" return self - def update_rpc_metadata(self, metadata: Mapping[str, Union[str, bytes]]) -> None: + def update_rpc_metadata(self, metadata: Mapping[str, str | bytes]) -> None: """Update Core client metadata.""" # Mutate the bridge config and then only mutate the running client # metadata if already connected @@ -342,7 +343,7 @@ def update_rpc_metadata(self, metadata: Mapping[str, Union[str, bytes]]) -> None if self._bridge_client: self._bridge_client.update_metadata(metadata) - def update_api_key(self, api_key: Optional[str]) -> None: + def update_api_key(self, api_key: str | None) -> None: """Update Core client API key.""" # Mutate the bridge config and then only mutate the running client # metadata if already connected @@ -354,12 +355,12 @@ async def _rpc_call( self, rpc: str, req: google.protobuf.message.Message, - resp_type: Type[ServiceResponse], + resp_type: type[ServiceResponse], *, service: str, retry: bool, - metadata: Mapping[str, Union[str, bytes]], - timeout: Optional[timedelta], + metadata: Mapping[str, str | bytes], + timeout: timedelta | None, ) -> ServiceResponse: global LOG_PROTOS if LOG_PROTOS: @@ -417,7 +418,7 @@ def __init__( self._message = message self._status = status self._raw_grpc_status = raw_grpc_status - self._grpc_status: Optional[temporalio.api.common.v1.GrpcStatus] = None + self._grpc_status: temporalio.api.common.v1.GrpcStatus | None = None @property def message(self) -> str: diff --git a/temporalio/testing/_activity.py b/temporalio/testing/_activity.py index 532299530..99150381c 100644 --- a/temporalio/testing/_activity.py +++ b/temporalio/testing/_activity.py @@ -5,9 +5,10 @@ import asyncio import inspect import threading +from collections.abc import Callable from contextlib import contextmanager from datetime import datetime, timedelta, timezone -from typing import Any, Callable, Optional, Set, TypeVar +from typing import Any, Optional, Set, TypeVar from typing_extensions import ParamSpec @@ -65,7 +66,7 @@ class ActivityEnvironment: take effect. Default is noop. """ - def __init__(self, client: Optional[Client] = None) -> None: + def __init__(self, client: Client | None = None) -> None: """Create an ActivityEnvironment for running activity code.""" self.info = _default_info self.on_heartbeat: Callable[..., None] = lambda *args: None @@ -75,7 +76,7 @@ def __init__(self, client: Optional[Client] = None) -> None: self.metric_meter = temporalio.common.MetricMeter.noop self._cancelled = False self._worker_shutdown = False - self._activities: Set[_Activity] = set() + self._activities: set[_Activity] = set() self._client = client self._cancellation_details = ( temporalio.activity._ActivityCancellationDetailsHolder() @@ -139,16 +140,16 @@ def __init__( self, env: ActivityEnvironment, fn: Callable, - client: Optional[Client], + client: Client | None, ) -> None: self.env = env self.fn = fn self.is_async = inspect.iscoroutinefunction(fn) or inspect.iscoroutinefunction( fn.__call__ # type: ignore ) - self.cancel_thread_raiser: Optional[ + self.cancel_thread_raiser: None | ( temporalio.worker._activity._ThreadExceptionRaiser - ] = None + ) = None if not self.is_async: # If there is a definition and they disable thread raising, don't # set @@ -179,7 +180,7 @@ def __init__( client=client if self.is_async else None, cancellation_details=env._cancellation_details, ) - self.task: Optional[asyncio.Task] = None + self.task: asyncio.Task | None = None def run(self, *args, **kwargs) -> Any: if self.cancel_thread_raiser: diff --git a/temporalio/testing/_workflow.py b/temporalio/testing/_workflow.py index 8e054e56b..e651876e9 100644 --- a/temporalio/testing/_workflow.py +++ b/temporalio/testing/_workflow.py @@ -4,16 +4,13 @@ import asyncio import logging +from collections.abc import AsyncIterator, Iterator, Mapping, Sequence from contextlib import asynccontextmanager, contextmanager from datetime import datetime, timedelta, timezone from typing import ( Any, - AsyncIterator, - Iterator, List, - Mapping, Optional, - Sequence, Type, Union, cast, @@ -80,26 +77,25 @@ async def start_local( data_converter: temporalio.converter.DataConverter = temporalio.converter.DataConverter.default, interceptors: Sequence[temporalio.client.Interceptor] = [], plugins: Sequence[temporalio.client.Plugin] = [], - default_workflow_query_reject_condition: Optional[ - temporalio.common.QueryRejectCondition - ] = None, - retry_config: Optional[temporalio.client.RetryConfig] = None, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - identity: Optional[str] = None, + default_workflow_query_reject_condition: None + | (temporalio.common.QueryRejectCondition) = None, + retry_config: temporalio.client.RetryConfig | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + identity: str | None = None, tls: bool | temporalio.client.TLSConfig = False, ip: str = "127.0.0.1", - port: Optional[int] = None, - download_dest_dir: Optional[str] = None, + port: int | None = None, + download_dest_dir: str | None = None, ui: bool = False, - runtime: Optional[temporalio.runtime.Runtime] = None, + runtime: temporalio.runtime.Runtime | None = None, search_attributes: Sequence[temporalio.common.SearchAttributeKey] = (), - dev_server_existing_path: Optional[str] = None, - dev_server_database_filename: Optional[str] = None, + dev_server_existing_path: str | None = None, + dev_server_database_filename: str | None = None, dev_server_log_format: str = "pretty", - dev_server_log_level: Optional[str] = "warn", + dev_server_log_level: str | None = "warn", dev_server_download_version: str = "default", dev_server_extra_args: Sequence[str] = [], - dev_server_download_ttl: Optional[timedelta] = None, + dev_server_download_ttl: timedelta | None = None, ) -> WorkflowEnvironment: """Start a full Temporal server locally, downloading if necessary. @@ -241,19 +237,18 @@ async def start_time_skipping( data_converter: temporalio.converter.DataConverter = temporalio.converter.DataConverter.default, interceptors: Sequence[temporalio.client.Interceptor] = [], plugins: Sequence[temporalio.client.Plugin] = [], - default_workflow_query_reject_condition: Optional[ - temporalio.common.QueryRejectCondition - ] = None, - retry_config: Optional[temporalio.client.RetryConfig] = None, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - identity: Optional[str] = None, - port: Optional[int] = None, - download_dest_dir: Optional[str] = None, - runtime: Optional[temporalio.runtime.Runtime] = None, - test_server_existing_path: Optional[str] = None, + default_workflow_query_reject_condition: None + | (temporalio.common.QueryRejectCondition) = None, + retry_config: temporalio.client.RetryConfig | None = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + identity: str | None = None, + port: int | None = None, + download_dest_dir: str | None = None, + runtime: temporalio.runtime.Runtime | None = None, + test_server_existing_path: str | None = None, test_server_download_version: str = "default", test_server_extra_args: Sequence[str] = [], - test_server_download_ttl: Optional[timedelta] = None, + test_server_download_ttl: timedelta | None = None, ) -> WorkflowEnvironment: """Start a time skipping workflow environment. @@ -380,7 +375,7 @@ async def shutdown(self) -> None: """Shut down this environment.""" pass - async def sleep(self, duration: Union[timedelta, float]) -> None: + async def sleep(self, duration: timedelta | float) -> None: """Sleep in this environment. This awaits a regular :py:func:`asyncio.sleep` in regular environments, @@ -432,7 +427,7 @@ def __init__( # Add assertion interceptor to client and if time skipping is supported, # add time skipping interceptor self._supports_time_skipping = server.has_test_service - interceptors: List[temporalio.client.Interceptor] = [ + interceptors: list[temporalio.client.Interceptor] = [ _AssertionErrorInterceptor() ] if self._supports_time_skipping: @@ -444,7 +439,7 @@ def __init__( async def shutdown(self) -> None: await self._server.shutdown() - async def sleep(self, duration: Union[timedelta, float]) -> None: + async def sleep(self, duration: timedelta | float) -> None: # Use regular sleep if no time skipping if not self._supports_time_skipping: return await super().sleep(duration) @@ -510,7 +505,7 @@ class _AssertionErrorInterceptor( ): def workflow_interceptor_class( self, input: temporalio.worker.WorkflowInterceptorClassInput - ) -> Optional[Type[temporalio.worker.WorkflowInboundInterceptor]]: + ) -> type[temporalio.worker.WorkflowInboundInterceptor] | None: return _AssertionErrorWorkflowInboundInterceptor @@ -575,8 +570,8 @@ async def result( self, *, follow_runs: bool = True, - rpc_metadata: Mapping[str, Union[str, bytes]] = {}, - rpc_timeout: Optional[timedelta] = None, + rpc_metadata: Mapping[str, str | bytes] = {}, + rpc_timeout: timedelta | None = None, ) -> Any: async with self.env.time_skipping_unlocked(): return await super().result( diff --git a/temporalio/types.py b/temporalio/types.py index 331c9596e..c8d7824e3 100644 --- a/temporalio/types.py +++ b/temporalio/types.py @@ -1,11 +1,12 @@ """Advanced types.""" -from typing import Any, Awaitable, Callable, Type, TypeVar, Union +from collections.abc import Awaitable, Callable +from typing import Any, Type, TypeVar, Union from typing_extensions import ParamSpec, Protocol AnyType = TypeVar("AnyType") -ClassType = TypeVar("ClassType", bound=Type) +ClassType = TypeVar("ClassType", bound=type) SelfType = TypeVar("SelfType") ParamType = TypeVar("ParamType") ReturnType = TypeVar("ReturnType", covariant=True) @@ -105,7 +106,7 @@ class MethodSyncOrAsyncNoParam(Protocol[ProtocolSelfType, ProtocolReturnType]): def __call__( self, __self: ProtocolSelfType - ) -> Union[ProtocolReturnType, Awaitable[ProtocolReturnType]]: + ) -> ProtocolReturnType | Awaitable[ProtocolReturnType]: """Generic callable type callback.""" ... @@ -117,7 +118,7 @@ class MethodSyncOrAsyncSingleParam( def __call__( self, __self: ProtocolSelfType, __param: ProtocolParamType, / - ) -> Union[ProtocolReturnType, Awaitable[ProtocolReturnType]]: + ) -> ProtocolReturnType | Awaitable[ProtocolReturnType]: """Generic callable type callback.""" ... diff --git a/temporalio/worker/_activity.py b/temporalio/worker/_activity.py index 44bfb6910..f74ee7872 100644 --- a/temporalio/worker/_activity.py +++ b/temporalio/worker/_activity.py @@ -14,13 +14,12 @@ import threading import warnings from abc import ABC, abstractmethod -from collections.abc import Iterator, Sequence +from collections.abc import Callable, Iterator, Sequence from contextlib import contextmanager from dataclasses import dataclass, field from datetime import datetime, timedelta, timezone from typing import ( Any, - Callable, NoReturn, Optional, Union, @@ -54,8 +53,8 @@ def __init__( bridge_worker: Callable[[], temporalio.bridge.worker.Worker], task_queue: str, activities: Sequence[Callable], - activity_executor: Optional[concurrent.futures.Executor], - shared_state_manager: Optional[SharedStateManager], + activity_executor: concurrent.futures.Executor | None, + shared_state_manager: SharedStateManager | None, data_converter: temporalio.converter.DataConverter, interceptors: Sequence[Interceptor], metric_meter: temporalio.common.MetricMeter, @@ -73,15 +72,13 @@ def __init__( self._encode_headers = encode_headers self._fail_worker_exception_queue: asyncio.Queue[Exception] = asyncio.Queue() # Lazily created on first activity - self._worker_shutdown_event: Optional[temporalio.activity._CompositeEvent] = ( - None - ) + self._worker_shutdown_event: temporalio.activity._CompositeEvent | None = None self._seen_sync_activity = False self._client = client # Validate and build activity dict self._activities: dict[str, temporalio.activity._Definition] = {} - self._dynamic_activity: Optional[temporalio.activity._Definition] = None + self._dynamic_activity: temporalio.activity._Definition | None = None for activity in activities: # Get definition defn = temporalio.activity._Definition.must_from_callable(activity) @@ -246,7 +243,7 @@ async def _heartbeat_async( task_token: bytes, ) -> None: # Drain the queue, only taking the last value to actually heartbeat - details: Optional[Sequence[Any]] = None + details: Sequence[Any] | None = None while not activity.pending_heartbeats.empty(): details = activity.pending_heartbeats.get_nowait() if details is None: @@ -646,15 +643,15 @@ def assert_activity_valid(self, activity) -> None: class _RunningActivity: pending_heartbeats: asyncio.Queue[Sequence[Any]] # Most of these optional values are set before use - info: Optional[temporalio.activity.Info] = None - task: Optional[asyncio.Task] = None - cancelled_event: Optional[temporalio.activity._CompositeEvent] = None - last_heartbeat_task: Optional[asyncio.Task] = None - cancel_thread_raiser: Optional[_ThreadExceptionRaiser] = None + info: temporalio.activity.Info | None = None + task: asyncio.Task | None = None + cancelled_event: temporalio.activity._CompositeEvent | None = None + last_heartbeat_task: asyncio.Task | None = None + cancel_thread_raiser: _ThreadExceptionRaiser | None = None sync: bool = False done: bool = False cancelled_by_request: bool = False - cancelled_due_to_heartbeat_error: Optional[Exception] = None + cancelled_due_to_heartbeat_error: Exception | None = None cancellation_details: temporalio.activity._ActivityCancellationDetailsHolder = ( field(default_factory=temporalio.activity._ActivityCancellationDetailsHolder) ) @@ -663,7 +660,7 @@ def cancel( self, *, cancelled_by_request: bool = False, - cancelled_due_to_heartbeat_error: Optional[Exception] = None, + cancelled_due_to_heartbeat_error: Exception | None = None, ) -> None: self.cancelled_by_request = cancelled_by_request self.cancelled_due_to_heartbeat_error = cancelled_due_to_heartbeat_error @@ -684,8 +681,8 @@ def cancel( class _ThreadExceptionRaiser: def __init__(self) -> None: self._lock = threading.Lock() - self._thread_id: Optional[int] = None - self._pending_exception: Optional[type[Exception]] = None + self._thread_id: int | None = None + self._pending_exception: type[Exception] | None = None self._shield_depth = 0 def set_thread_id(self, thread_id: int) -> None: @@ -771,8 +768,8 @@ async def heartbeat_with_context(*details: Any) -> None: # For heartbeats, we use the existing heartbeat callable for thread # pool executors or a multiprocessing queue for others - heartbeat: Union[Callable[..., None], SharedHeartbeatSender] = ctx.heartbeat - shared_manager: Optional[SharedStateManager] = None + heartbeat: Callable[..., None] | SharedHeartbeatSender = ctx.heartbeat + shared_manager: SharedStateManager | None = None if not isinstance(input.executor, concurrent.futures.ThreadPoolExecutor): # Should always be present in worker, pre-checked on init shared_manager = self._worker._shared_state_manager @@ -842,16 +839,16 @@ def heartbeat(self, *details: Any) -> None: # This has to be defined at the top-level to be picklable for process executors def _execute_sync_activity( info: temporalio.activity.Info, - heartbeat: Union[Callable[..., None], SharedHeartbeatSender], + heartbeat: Callable[..., None] | SharedHeartbeatSender, # This is only set for threaded activities - cancel_thread_raiser: Optional[_ThreadExceptionRaiser], + cancel_thread_raiser: _ThreadExceptionRaiser | None, cancelled_event: threading.Event, worker_shutdown_event: threading.Event, - payload_converter_class_or_instance: Union[ - type[temporalio.converter.PayloadConverter], - temporalio.converter.PayloadConverter, - ], - runtime_metric_meter: Optional[temporalio.common.MetricMeter], + payload_converter_class_or_instance: ( + type[temporalio.converter.PayloadConverter] + | temporalio.converter.PayloadConverter + ), + runtime_metric_meter: temporalio.common.MetricMeter | None, cancellation_details: temporalio.activity._ActivityCancellationDetailsHolder, fn: Callable[..., Any], *args: Any, @@ -900,7 +897,7 @@ class SharedStateManager(ABC): @staticmethod def create_from_multiprocessing( mgr: multiprocessing.managers.SyncManager, - queue_poller_executor: Optional[concurrent.futures.Executor] = None, + queue_poller_executor: concurrent.futures.Executor | None = None, ) -> SharedStateManager: """Create a shared state manager from a multiprocessing manager. @@ -1056,7 +1053,7 @@ def _proto_to_datetime( def _proto_to_non_zero_timedelta( dur: google.protobuf.duration_pb2.Duration, -) -> Optional[timedelta]: +) -> timedelta | None: if dur.nanos == 0 and dur.seconds == 0: return None return dur.ToTimedelta() diff --git a/temporalio/worker/_command_aware_visitor.py b/temporalio/worker/_command_aware_visitor.py index 450445999..2301f6ed6 100644 --- a/temporalio/worker/_command_aware_visitor.py +++ b/temporalio/worker/_command_aware_visitor.py @@ -1,9 +1,10 @@ """Visitor that sets command context during payload traversal.""" import contextvars +from collections.abc import Iterator from contextlib import contextmanager from dataclasses import dataclass -from typing import Iterator, Optional +from typing import Optional from temporalio.api.enums.v1.command_type_pb2 import CommandType from temporalio.bridge._visitor import PayloadVisitor, VisitorFunctions @@ -33,7 +34,7 @@ class CommandInfo: command_seq: int -current_command_info: contextvars.ContextVar[Optional[CommandInfo]] = ( +current_command_info: contextvars.ContextVar[CommandInfo | None] = ( contextvars.ContextVar("current_command_info", default=None) ) diff --git a/temporalio/worker/_interceptor.py b/temporalio/worker/_interceptor.py index a60ebb1d5..c8d84e861 100644 --- a/temporalio/worker/_interceptor.py +++ b/temporalio/worker/_interceptor.py @@ -3,17 +3,15 @@ from __future__ import annotations import concurrent.futures -from collections.abc import Callable, Mapping, MutableMapping +from collections.abc import Awaitable, Callable, Mapping, MutableMapping, Sequence from dataclasses import dataclass from datetime import timedelta from typing import ( Any, - Awaitable, Generic, List, NoReturn, Optional, - Sequence, Type, Union, ) @@ -52,7 +50,7 @@ def intercept_activity( def workflow_interceptor_class( self, input: WorkflowInterceptorClassInput - ) -> Optional[Type[WorkflowInboundInterceptor]]: + ) -> type[WorkflowInboundInterceptor] | None: """Class that will be instantiated and used to intercept workflows. This method is called on workflow start. The class must have the same @@ -91,7 +89,7 @@ class ExecuteActivityInput: fn: Callable[..., Any] args: Sequence[Any] - executor: Optional[concurrent.futures.Executor] + executor: concurrent.futures.Executor | None headers: Mapping[str, temporalio.api.common.v1.Payload] @@ -151,29 +149,27 @@ def heartbeat(self, *details: Any) -> None: class ContinueAsNewInput: """Input for :py:meth:`WorkflowOutboundInterceptor.continue_as_new`.""" - workflow: Optional[str] + workflow: str | None args: Sequence[Any] - task_queue: Optional[str] - run_timeout: Optional[timedelta] - task_timeout: Optional[timedelta] - retry_policy: Optional[temporalio.common.RetryPolicy] - memo: Optional[Mapping[str, Any]] - search_attributes: Optional[ - Union[ - temporalio.common.SearchAttributes, temporalio.common.TypedSearchAttributes - ] - ] + task_queue: str | None + run_timeout: timedelta | None + task_timeout: timedelta | None + retry_policy: temporalio.common.RetryPolicy | None + memo: Mapping[str, Any] | None + search_attributes: None | ( + temporalio.common.SearchAttributes | temporalio.common.TypedSearchAttributes + ) headers: Mapping[str, temporalio.api.common.v1.Payload] - versioning_intent: Optional[VersioningIntent] + versioning_intent: VersioningIntent | None # The types may be absent - arg_types: Optional[List[Type]] + arg_types: list[type] | None @dataclass class ExecuteWorkflowInput: """Input for :py:meth:`WorkflowInboundInterceptor.execute_workflow`.""" - type: Type + type: type # Note, this is an unbound method run_fn: Callable[..., Awaitable[Any]] args: Sequence[Any] @@ -229,7 +225,7 @@ class SignalExternalWorkflowInput: args: Sequence[Any] namespace: str workflow_id: str - workflow_run_id: Optional[str] + workflow_run_id: str | None headers: Mapping[str, temporalio.api.common.v1.Payload] @@ -239,22 +235,22 @@ class StartActivityInput: activity: str args: Sequence[Any] - activity_id: Optional[str] - task_queue: Optional[str] - schedule_to_close_timeout: Optional[timedelta] - schedule_to_start_timeout: Optional[timedelta] - start_to_close_timeout: Optional[timedelta] - heartbeat_timeout: Optional[timedelta] - retry_policy: Optional[temporalio.common.RetryPolicy] + activity_id: str | None + task_queue: str | None + schedule_to_close_timeout: timedelta | None + schedule_to_start_timeout: timedelta | None + start_to_close_timeout: timedelta | None + heartbeat_timeout: timedelta | None + retry_policy: temporalio.common.RetryPolicy | None cancellation_type: temporalio.workflow.ActivityCancellationType headers: Mapping[str, temporalio.api.common.v1.Payload] disable_eager_execution: bool - versioning_intent: Optional[VersioningIntent] - summary: Optional[str] + versioning_intent: VersioningIntent | None + summary: str | None priority: temporalio.common.Priority # The types may be absent - arg_types: Optional[List[Type]] - ret_type: Optional[Type] + arg_types: list[type] | None + ret_type: type | None @dataclass @@ -264,29 +260,27 @@ class StartChildWorkflowInput: workflow: str args: Sequence[Any] id: str - task_queue: Optional[str] + task_queue: str | None cancellation_type: temporalio.workflow.ChildWorkflowCancellationType parent_close_policy: temporalio.workflow.ParentClosePolicy - execution_timeout: Optional[timedelta] - run_timeout: Optional[timedelta] - task_timeout: Optional[timedelta] + execution_timeout: timedelta | None + run_timeout: timedelta | None + task_timeout: timedelta | None id_reuse_policy: temporalio.common.WorkflowIDReusePolicy - retry_policy: Optional[temporalio.common.RetryPolicy] + retry_policy: temporalio.common.RetryPolicy | None cron_schedule: str - memo: Optional[Mapping[str, Any]] - search_attributes: Optional[ - Union[ - temporalio.common.SearchAttributes, temporalio.common.TypedSearchAttributes - ] - ] + memo: Mapping[str, Any] | None + search_attributes: None | ( + temporalio.common.SearchAttributes | temporalio.common.TypedSearchAttributes + ) headers: Mapping[str, temporalio.api.common.v1.Payload] - versioning_intent: Optional[VersioningIntent] - static_summary: Optional[str] - static_details: Optional[str] + versioning_intent: VersioningIntent | None + static_summary: str | None + static_details: str | None priority: temporalio.common.Priority # The types may be absent - arg_types: Optional[List[Type]] - ret_type: Optional[Type] + arg_types: list[type] | None + ret_type: type | None @dataclass @@ -301,7 +295,7 @@ class StartNexusOperationInput(Generic[InputT, OutputT]): cancellation_type: temporalio.workflow.NexusOperationCancellationType headers: Mapping[str, str] | None summary: str | None - output_type: Type[OutputT] | None = None + output_type: type[OutputT] | None = None def __post_init__(self) -> None: """Initialize operation-specific attributes after dataclass creation.""" @@ -345,19 +339,19 @@ class StartLocalActivityInput: activity: str args: Sequence[Any] - activity_id: Optional[str] - schedule_to_close_timeout: Optional[timedelta] - schedule_to_start_timeout: Optional[timedelta] - start_to_close_timeout: Optional[timedelta] - retry_policy: Optional[temporalio.common.RetryPolicy] - local_retry_threshold: Optional[timedelta] + activity_id: str | None + schedule_to_close_timeout: timedelta | None + schedule_to_start_timeout: timedelta | None + start_to_close_timeout: timedelta | None + retry_policy: temporalio.common.RetryPolicy | None + local_retry_threshold: timedelta | None cancellation_type: temporalio.workflow.ActivityCancellationType headers: Mapping[str, temporalio.api.common.v1.Payload] - summary: Optional[str] + summary: str | None # The types may be absent - arg_types: Optional[List[Type]] - ret_type: Optional[Type] + arg_types: list[type] | None + ret_type: type | None class WorkflowInboundInterceptor: diff --git a/temporalio/worker/_nexus.py b/temporalio/worker/_nexus.py index 1083cc620..75afa090e 100644 --- a/temporalio/worker/_nexus.py +++ b/temporalio/worker/_nexus.py @@ -6,14 +6,12 @@ import concurrent.futures import json import threading +from collections.abc import Callable, Mapping, Sequence from dataclasses import dataclass from typing import ( Any, - Callable, - Mapping, NoReturn, Optional, - Sequence, Type, Union, ) @@ -66,7 +64,7 @@ def __init__( data_converter: temporalio.converter.DataConverter, interceptors: Sequence[Interceptor], metric_meter: temporalio.common.MetricMeter, - executor: Optional[concurrent.futures.Executor], + executor: concurrent.futures.Executor | None, ) -> None: # TODO: make it possible to query task queue of bridge worker instead of passing # unused task_queue into _NexusWorker, _ActivityWorker, etc? @@ -368,7 +366,7 @@ async def _start_operation( async def _nexus_error_to_nexus_failure_proto( self, - error: Union[nexusrpc.HandlerError, nexusrpc.OperationError], + error: nexusrpc.HandlerError | nexusrpc.OperationError, ) -> temporalio.api.nexus.v1.Failure: """Serialize ``error`` as a Nexus Failure proto. @@ -452,7 +450,7 @@ async def serialize(self, value: Any) -> nexusrpc.Content: async def deserialize( self, content: nexusrpc.Content, - as_type: Optional[Type[Any]] = None, + as_type: type[Any] | None = None, ) -> Any: try: [input] = await self.data_converter.decode( @@ -574,12 +572,12 @@ def __init__(self): self._thread_evt = threading.Event() self._async_evt = asyncio.Event() self._lock = threading.Lock() - self._reason: Optional[str] = None + self._reason: str | None = None def is_cancelled(self) -> bool: return self._thread_evt.is_set() - def cancellation_reason(self) -> Optional[str]: + def cancellation_reason(self) -> str | None: with self._lock: return self._reason diff --git a/temporalio/worker/_plugin.py b/temporalio/worker/_plugin.py index 2f4c04a1e..969b1d370 100644 --- a/temporalio/worker/_plugin.py +++ b/temporalio/worker/_plugin.py @@ -1,8 +1,9 @@ from __future__ import annotations import abc +from collections.abc import AsyncIterator, Awaitable, Callable from contextlib import AbstractAsyncContextManager -from typing import TYPE_CHECKING, AsyncIterator, Awaitable, Callable +from typing import TYPE_CHECKING from temporalio.client import WorkflowHistory diff --git a/temporalio/worker/_replayer.py b/temporalio/worker/_replayer.py index 5247ced8e..b93eeeaec 100644 --- a/temporalio/worker/_replayer.py +++ b/temporalio/worker/_replayer.py @@ -5,9 +5,10 @@ import asyncio import concurrent.futures import logging +from collections.abc import AsyncIterator, Mapping, Sequence from contextlib import AbstractAsyncContextManager, asynccontextmanager from dataclasses import dataclass -from typing import AsyncIterator, Dict, Mapping, Optional, Sequence, Type +from typing import Dict, Optional, Type from typing_extensions import TypedDict @@ -35,19 +36,19 @@ class Replayer: def __init__( self, *, - workflows: Sequence[Type], - workflow_task_executor: Optional[concurrent.futures.ThreadPoolExecutor] = None, + workflows: Sequence[type], + workflow_task_executor: concurrent.futures.ThreadPoolExecutor | None = None, workflow_runner: WorkflowRunner = SandboxedWorkflowRunner(), unsandboxed_workflow_runner: WorkflowRunner = UnsandboxedWorkflowRunner(), namespace: str = "ReplayNamespace", data_converter: temporalio.converter.DataConverter = temporalio.converter.DataConverter.default, interceptors: Sequence[Interceptor] = [], plugins: Sequence[temporalio.worker.Plugin] = [], - build_id: Optional[str] = None, - identity: Optional[str] = None, - workflow_failure_exception_types: Sequence[Type[BaseException]] = [], + build_id: str | None = None, + identity: str | None = None, + workflow_failure_exception_types: Sequence[type[BaseException]] = [], debug_mode: bool = False, - runtime: Optional[temporalio.runtime.Runtime] = None, + runtime: temporalio.runtime.Runtime | None = None, disable_safe_workflow_eviction: bool = False, header_codec_behavior: HeaderCodecBehavior = HeaderCodecBehavior.NO_CODEC, ) -> None: @@ -154,7 +155,7 @@ async def replay_workflows( Aggregated results. """ async with self.workflow_replay_iterator(histories) as replay_iterator: - replay_failures: Dict[str, Exception] = {} + replay_failures: dict[str, Exception] = {} async for result in replay_iterator: if result.replay_failure: if raise_on_replay_failure: @@ -192,7 +193,7 @@ async def _workflow_replay_iterator( self, histories: AsyncIterator[temporalio.client.WorkflowHistory] ) -> AsyncIterator[AsyncIterator[WorkflowReplayResult]]: try: - last_replay_failure: Optional[Exception] + last_replay_failure: Exception | None last_replay_complete = asyncio.Event() # Create eviction hook @@ -366,18 +367,18 @@ async def replay_iterator() -> AsyncIterator[WorkflowReplayResult]: class ReplayerConfig(TypedDict, total=False): """TypedDict of config originally passed to :py:class:`Replayer`.""" - workflows: Sequence[Type] - workflow_task_executor: Optional[concurrent.futures.ThreadPoolExecutor] + workflows: Sequence[type] + workflow_task_executor: concurrent.futures.ThreadPoolExecutor | None workflow_runner: WorkflowRunner unsandboxed_workflow_runner: WorkflowRunner namespace: str data_converter: temporalio.converter.DataConverter interceptors: Sequence[Interceptor] - build_id: Optional[str] - identity: Optional[str] - workflow_failure_exception_types: Sequence[Type[BaseException]] + build_id: str | None + identity: str | None + workflow_failure_exception_types: Sequence[type[BaseException]] debug_mode: bool - runtime: Optional[temporalio.runtime.Runtime] + runtime: temporalio.runtime.Runtime | None disable_safe_workflow_eviction: bool header_codec_behavior: HeaderCodecBehavior @@ -389,7 +390,7 @@ class WorkflowReplayResult: history: temporalio.client.WorkflowHistory """History originally passed for this workflow replay.""" - replay_failure: Optional[Exception] + replay_failure: Exception | None """Failure during replay if any. This does not mean your workflow exited by raising an error, but rather that diff --git a/temporalio/worker/_tuning.py b/temporalio/worker/_tuning.py index 84abd87ac..4843fee98 100644 --- a/temporalio/worker/_tuning.py +++ b/temporalio/worker/_tuning.py @@ -3,11 +3,12 @@ import asyncio import logging from abc import ABC, abstractmethod +from collections.abc import Callable from dataclasses import dataclass from datetime import timedelta -from typing import Any, Callable, Literal, Optional, Protocol, Union, runtime_checkable +from typing import Any, Literal, Optional, Protocol, TypeAlias, Union, runtime_checkable -from typing_extensions import Self, TypeAlias +from typing_extensions import Self import temporalio.bridge.worker from temporalio.common import WorkerDeploymentVersion @@ -42,12 +43,12 @@ class ResourceBasedTunerConfig: class ResourceBasedSlotConfig: """Options for a specific slot type being used with a :py:class:`ResourceBasedSlotSupplier`.""" - minimum_slots: Optional[int] = None + minimum_slots: int | None = None """Amount of slots that will be issued regardless of any other checks. Defaults to 5 for workflows and 1 for activities.""" - maximum_slots: Optional[int] = None + maximum_slots: int | None = None """Maximum amount of slots permitted. Defaults to 500.""" - ramp_throttle: Optional[timedelta] = None + ramp_throttle: timedelta | None = None """Minimum time we will wait (after passing the minimum slots number) between handing out new slots in milliseconds. Defaults to 0 for workflows and 50ms for activities. @@ -90,7 +91,7 @@ class SlotReserveContext(Protocol): .. warning:: Deprecated, use :py:attr:`worker_deployment_version` instead. """ - worker_deployment_version: Optional[WorkerDeploymentVersion] + worker_deployment_version: WorkerDeploymentVersion | None """The deployment version of the worker that is requesting the reservation, if any.""" is_sticky: bool """True iff this is a reservation for a sticky poll for a workflow task.""" @@ -151,7 +152,7 @@ class SlotMarkUsedContext(Protocol): class SlotReleaseContext: """Context for releasing a slot from a :py:class:`CustomSlotSupplier`.""" - slot_info: Optional[SlotInfo] + slot_info: SlotInfo | None """Info about the task that will be using the slot. May be None if the slot was never used.""" permit: SlotPermit """The permit that was issued when the slot was reserved.""" @@ -183,7 +184,7 @@ async def reserve_slot(self, ctx: SlotReserveContext) -> SlotPermit: ... @abstractmethod - def try_reserve_slot(self, ctx: SlotReserveContext) -> Optional[SlotPermit]: + def try_reserve_slot(self, ctx: SlotReserveContext) -> SlotPermit | None: """This function is called when trying to reserve slots for "eager" workflow and activity tasks. Eager tasks are those which are returned as a result of completing a workflow task, rather than from polling. Your implementation must not block, and if a slot is available, return a permit @@ -246,7 +247,7 @@ async def reserve_slot( # Error needs to be re-thrown here so the rust code will loop raise - def try_reserve_slot(self, ctx: SlotReserveContext) -> Optional[SlotPermit]: + def try_reserve_slot(self, ctx: SlotReserveContext) -> SlotPermit | None: try: return self._supplier.try_reserve_slot(ctx) except Exception: @@ -316,10 +317,10 @@ def create_resource_based( *, target_memory_usage: float, target_cpu_usage: float, - workflow_config: Optional[ResourceBasedSlotConfig] = None, - activity_config: Optional[ResourceBasedSlotConfig] = None, - local_activity_config: Optional[ResourceBasedSlotConfig] = None, - nexus_config: Optional[ResourceBasedSlotConfig] = None, + workflow_config: ResourceBasedSlotConfig | None = None, + activity_config: ResourceBasedSlotConfig | None = None, + local_activity_config: ResourceBasedSlotConfig | None = None, + nexus_config: ResourceBasedSlotConfig | None = None, ) -> WorkerTuner: """Create a resource-based tuner with the provided options.""" resource_cfg = ResourceBasedTunerConfig(target_memory_usage, target_cpu_usage) @@ -346,10 +347,10 @@ def create_resource_based( def create_fixed( cls, *, - workflow_slots: Optional[int] = None, - activity_slots: Optional[int] = None, - local_activity_slots: Optional[int] = None, - nexus_slots: Optional[int] = None, + workflow_slots: int | None = None, + activity_slots: int | None = None, + local_activity_slots: int | None = None, + nexus_slots: int | None = None, ) -> WorkerTuner: """Create a fixed-size tuner with the provided number of slots. @@ -411,16 +412,16 @@ def _to_bridge_tuner(self) -> temporalio.bridge.worker.TunerHolder: _to_bridge_slot_supplier(self._get_nexus_slot_supplier(), "nexus"), ) - def _get_activities_max(self) -> Optional[int]: + def _get_activities_max(self) -> int | None: return WorkerTuner._get_slot_supplier_max( self._get_activity_task_slot_supplier() ) - def _get_nexus_tasks_max(self) -> Optional[int]: + def _get_nexus_tasks_max(self) -> int | None: return WorkerTuner._get_slot_supplier_max(self._get_nexus_slot_supplier()) @staticmethod - def _get_slot_supplier_max(slot_supplier: SlotSupplier) -> Optional[int]: + def _get_slot_supplier_max(slot_supplier: SlotSupplier) -> int | None: if isinstance(slot_supplier, FixedSizeSlotSupplier): return slot_supplier.num_slots elif isinstance(slot_supplier, ResourceBasedSlotSupplier): diff --git a/temporalio/worker/_worker.py b/temporalio/worker/_worker.py index 1afae2c78..24ff06235 100644 --- a/temporalio/worker/_worker.py +++ b/temporalio/worker/_worker.py @@ -8,21 +8,20 @@ import logging import sys import warnings +from collections.abc import Awaitable, Callable, Sequence from dataclasses import dataclass from datetime import timedelta from typing import ( Any, - Awaitable, - Callable, List, Optional, - Sequence, Type, + TypeAlias, Union, cast, ) -from typing_extensions import TypeAlias, TypedDict +from typing_extensions import TypedDict import temporalio.bridge.worker import temporalio.client @@ -105,40 +104,40 @@ def __init__( task_queue: str, activities: Sequence[Callable] = [], nexus_service_handlers: Sequence[Any] = [], - workflows: Sequence[Type] = [], - activity_executor: Optional[concurrent.futures.Executor] = None, - workflow_task_executor: Optional[concurrent.futures.ThreadPoolExecutor] = None, - nexus_task_executor: Optional[concurrent.futures.Executor] = None, + workflows: Sequence[type] = [], + activity_executor: concurrent.futures.Executor | None = None, + workflow_task_executor: concurrent.futures.ThreadPoolExecutor | None = None, + nexus_task_executor: concurrent.futures.Executor | None = None, workflow_runner: WorkflowRunner = SandboxedWorkflowRunner(), unsandboxed_workflow_runner: WorkflowRunner = UnsandboxedWorkflowRunner(), plugins: Sequence[Plugin] = [], interceptors: Sequence[Interceptor] = [], - build_id: Optional[str] = None, - identity: Optional[str] = None, + build_id: str | None = None, + identity: str | None = None, max_cached_workflows: int = 1000, - max_concurrent_workflow_tasks: Optional[int] = None, - max_concurrent_activities: Optional[int] = None, - max_concurrent_local_activities: Optional[int] = None, - max_concurrent_nexus_tasks: Optional[int] = None, - tuner: Optional[WorkerTuner] = None, - max_concurrent_workflow_task_polls: Optional[int] = None, + max_concurrent_workflow_tasks: int | None = None, + max_concurrent_activities: int | None = None, + max_concurrent_local_activities: int | None = None, + max_concurrent_nexus_tasks: int | None = None, + tuner: WorkerTuner | None = None, + max_concurrent_workflow_task_polls: int | None = None, nonsticky_to_sticky_poll_ratio: float = 0.2, - max_concurrent_activity_task_polls: Optional[int] = None, + max_concurrent_activity_task_polls: int | None = None, no_remote_activities: bool = False, sticky_queue_schedule_to_start_timeout: timedelta = timedelta(seconds=10), max_heartbeat_throttle_interval: timedelta = timedelta(seconds=60), default_heartbeat_throttle_interval: timedelta = timedelta(seconds=30), - max_activities_per_second: Optional[float] = None, - max_task_queue_activities_per_second: Optional[float] = None, + max_activities_per_second: float | None = None, + max_task_queue_activities_per_second: float | None = None, graceful_shutdown_timeout: timedelta = timedelta(), - workflow_failure_exception_types: Sequence[Type[BaseException]] = [], - shared_state_manager: Optional[SharedStateManager] = None, + workflow_failure_exception_types: Sequence[type[BaseException]] = [], + shared_state_manager: SharedStateManager | None = None, debug_mode: bool = False, disable_eager_activity_execution: bool = False, - on_fatal_error: Optional[Callable[[BaseException], Awaitable[None]]] = None, + on_fatal_error: Callable[[BaseException], Awaitable[None]] | None = None, use_worker_versioning: bool = False, disable_safe_workflow_eviction: bool = False, - deployment_config: Optional[WorkerDeploymentConfig] = None, + deployment_config: WorkerDeploymentConfig | None = None, workflow_task_poller_behavior: PollerBehavior = PollerBehaviorSimpleMaximum( maximum=5 ), @@ -367,7 +366,7 @@ def __init__( ) plugins_from_client = cast( - List[Plugin], + list[Plugin], [p for p in client.config()["plugins"] if isinstance(p, Plugin)], ) for client_plugin in plugins_from_client: @@ -411,7 +410,7 @@ def _init_from_config(self, client: temporalio.client.Client, config: WorkerConf # Prepend applicable client interceptors to the given ones client_config = config["client"].config(active_config=True) interceptors_from_client = cast( - List[Interceptor], + list[Interceptor], [i for i in client_config["interceptors"] if isinstance(i, Interceptor)], ) interceptors = interceptors_from_client + list(config["interceptors"]) @@ -422,11 +421,11 @@ def _init_from_config(self, client: temporalio.client.Client, config: WorkerConf self._started = False self._shutdown_event = asyncio.Event() self._shutdown_complete_event = asyncio.Event() - self._async_context_inner_task: Optional[asyncio.Task] = None - self._async_context_run_task: Optional[asyncio.Task] = None - self._async_context_run_exception: Optional[BaseException] = None + self._async_context_inner_task: asyncio.Task | None = None + self._async_context_run_task: asyncio.Task | None = None + self._async_context_run_exception: BaseException | None = None - self._activity_worker: Optional[_ActivityWorker] = None + self._activity_worker: _ActivityWorker | None = None self._runtime = ( bridge_client.config.runtime or temporalio.runtime.Runtime.default() ) @@ -446,7 +445,7 @@ def _init_from_config(self, client: temporalio.client.Client, config: WorkerConf client_config["header_codec_behavior"] == HeaderCodecBehavior.CODEC ), ) - self._nexus_worker: Optional[_NexusWorker] = None + self._nexus_worker: _NexusWorker | None = None if config["nexus_service_handlers"]: _warn_if_nexus_task_executor_max_workers_is_inconsistent(config) self._nexus_worker = _NexusWorker( @@ -459,7 +458,7 @@ def _init_from_config(self, client: temporalio.client.Client, config: WorkerConf metric_meter=self._runtime.metric_meter, executor=config["nexus_task_executor"], ) - self._workflow_worker: Optional[_WorkflowWorker] = None + self._workflow_worker: _WorkflowWorker | None = None if config["workflows"]: should_enforce_versioning_behavior = ( config["deployment_config"] is not None @@ -555,7 +554,7 @@ def check_activity(activity): maximum=config["max_concurrent_activity_task_polls"] ) - deduped_plugin_names = list(set([plugin.name() for plugin in self._plugins])) + deduped_plugin_names = list({plugin.name() for plugin in self._plugins}) # Create bridge worker last. We have empirically observed that if it is # created before an error is raised from the activity worker @@ -729,7 +728,7 @@ async def raise_on_shutdown(): pass tasks: dict[ - Union[None, _ActivityWorker, _WorkflowWorker, _NexusWorker], asyncio.Task + None | _ActivityWorker | _WorkflowWorker | _NexusWorker, asyncio.Task ] = {None: asyncio.create_task(raise_on_shutdown())} # Create tasks for workers if self._activity_worker: @@ -857,7 +856,7 @@ async def run(): self._async_context_run_task = asyncio.create_task(run()) return self - async def __aexit__(self, exc_type: Optional[Type[BaseException]], *args) -> None: + async def __aexit__(self, exc_type: type[BaseException] | None, *args) -> None: """Same as :py:meth:`shutdown` for use by ``async with``. Note, this will raise the worker fatal error if one occurred and the @@ -881,40 +880,40 @@ class WorkerConfig(TypedDict, total=False): task_queue: str activities: Sequence[Callable] nexus_service_handlers: Sequence[Any] - workflows: Sequence[Type] - activity_executor: Optional[concurrent.futures.Executor] - workflow_task_executor: Optional[concurrent.futures.ThreadPoolExecutor] - nexus_task_executor: Optional[concurrent.futures.Executor] + workflows: Sequence[type] + activity_executor: concurrent.futures.Executor | None + workflow_task_executor: concurrent.futures.ThreadPoolExecutor | None + nexus_task_executor: concurrent.futures.Executor | None workflow_runner: WorkflowRunner unsandboxed_workflow_runner: WorkflowRunner plugins: Sequence[Plugin] interceptors: Sequence[Interceptor] - build_id: Optional[str] - identity: Optional[str] + build_id: str | None + identity: str | None max_cached_workflows: int - max_concurrent_workflow_tasks: Optional[int] - max_concurrent_activities: Optional[int] - max_concurrent_local_activities: Optional[int] - max_concurrent_nexus_tasks: Optional[int] - tuner: Optional[WorkerTuner] - max_concurrent_workflow_task_polls: Optional[int] + max_concurrent_workflow_tasks: int | None + max_concurrent_activities: int | None + max_concurrent_local_activities: int | None + max_concurrent_nexus_tasks: int | None + tuner: WorkerTuner | None + max_concurrent_workflow_task_polls: int | None nonsticky_to_sticky_poll_ratio: float - max_concurrent_activity_task_polls: Optional[int] + max_concurrent_activity_task_polls: int | None no_remote_activities: bool sticky_queue_schedule_to_start_timeout: timedelta max_heartbeat_throttle_interval: timedelta default_heartbeat_throttle_interval: timedelta - max_activities_per_second: Optional[float] - max_task_queue_activities_per_second: Optional[float] + max_activities_per_second: float | None + max_task_queue_activities_per_second: float | None graceful_shutdown_timeout: timedelta - workflow_failure_exception_types: Sequence[Type[BaseException]] - shared_state_manager: Optional[SharedStateManager] + workflow_failure_exception_types: Sequence[type[BaseException]] + shared_state_manager: SharedStateManager | None debug_mode: bool disable_eager_activity_execution: bool - on_fatal_error: Optional[Callable[[BaseException], Awaitable[None]]] + on_fatal_error: Callable[[BaseException], Awaitable[None]] | None use_worker_versioning: bool disable_safe_workflow_eviction: bool - deployment_config: Optional[WorkerDeploymentConfig] + deployment_config: WorkerDeploymentConfig | None workflow_task_poller_behavior: PollerBehavior activity_task_poller_behavior: PollerBehavior nexus_task_poller_behavior: PollerBehavior @@ -974,7 +973,7 @@ def _to_bridge_worker_deployment_options( ) -_default_build_id: Optional[str] = None +_default_build_id: str | None = None def load_default_build_id(*, memoize: bool = True) -> str: @@ -1008,10 +1007,7 @@ def load_default_build_id(*, memoize: bool = True) -> str: # * Using the loader's get_code in rare cases can cause a compile() got_temporal_code = False - if sys.version_info < (3, 9): - m = hashlib.md5() - else: - m = hashlib.md5(usedforsecurity=False) + m = hashlib.md5(usedforsecurity=False) for mod_name in sorted(sys.modules): # Try to read code code = _get_module_code(mod_name) @@ -1036,7 +1032,7 @@ def load_default_build_id(*, memoize: bool = True) -> str: return digest -def _get_module_code(mod_name: str) -> Optional[bytes]: +def _get_module_code(mod_name: str) -> bytes | None: # First try the module's loader and if that fails, try __cached__ file try: loader: Any = sys.modules[mod_name].__loader__ diff --git a/temporalio/worker/_workflow.py b/temporalio/worker/_workflow.py index 6e7c254aa..b5aa57fc2 100644 --- a/temporalio/worker/_workflow.py +++ b/temporalio/worker/_workflow.py @@ -8,17 +8,14 @@ import os import sys import threading +from collections.abc import Awaitable, Callable, MutableMapping, Sequence from dataclasses import dataclass from datetime import timezone from types import TracebackType from typing import ( - Awaitable, - Callable, Dict, List, - MutableMapping, Optional, - Sequence, Set, Type, ) @@ -63,22 +60,23 @@ def __init__( bridge_worker: Callable[[], temporalio.bridge.worker.Worker], namespace: str, task_queue: str, - workflows: Sequence[Type], - workflow_task_executor: Optional[concurrent.futures.ThreadPoolExecutor], - max_concurrent_workflow_tasks: Optional[int], + workflows: Sequence[type], + workflow_task_executor: concurrent.futures.ThreadPoolExecutor | None, + max_concurrent_workflow_tasks: int | None, workflow_runner: WorkflowRunner, unsandboxed_workflow_runner: WorkflowRunner, data_converter: temporalio.converter.DataConverter, interceptors: Sequence[Interceptor], - workflow_failure_exception_types: Sequence[Type[BaseException]], + workflow_failure_exception_types: Sequence[type[BaseException]], debug_mode: bool, disable_eager_activity_execution: bool, metric_meter: temporalio.common.MetricMeter, - on_eviction_hook: Optional[ + on_eviction_hook: None + | ( Callable[ [str, temporalio.bridge.proto.workflow_activation.RemoveFromCache], None ] - ], + ), disable_safe_eviction: bool, should_enforce_versioning_behavior: bool, assert_local_activity_valid: Callable[[str], None], @@ -100,7 +98,7 @@ def __init__( self._data_converter = data_converter # Build the interceptor classes and collect extern functions self._extern_functions: MutableMapping[str, Callable] = {} - self._interceptor_classes: List[Type[WorkflowInboundInterceptor]] = [] + self._interceptor_classes: list[type[WorkflowInboundInterceptor]] = [] interceptor_class_input = WorkflowInterceptorClassInput( unsafe_extern_functions=self._extern_functions ) @@ -116,12 +114,12 @@ def __init__( ) self._workflow_failure_exception_types = workflow_failure_exception_types - self._running_workflows: Dict[str, _RunningWorkflow] = {} + self._running_workflows: dict[str, _RunningWorkflow] = {} self._disable_eager_activity_execution = disable_eager_activity_execution self._on_eviction_hook = on_eviction_hook self._disable_safe_eviction = disable_safe_eviction self._encode_headers = encode_headers - self._throw_after_activation: Optional[Exception] = None + self._throw_after_activation: Exception | None = None # If there's a debug mode or a truthy TEMPORAL_DEBUG env var, disable # deadlock detection, otherwise set to 2 seconds @@ -138,8 +136,8 @@ def __init__( ) # Validate and build workflow dict - self._workflows: Dict[str, temporalio.workflow._Definition] = {} - self._dynamic_workflow: Optional[temporalio.workflow._Definition] = None + self._workflows: dict[str, temporalio.workflow._Definition] = {} + self._dynamic_workflow: temporalio.workflow._Definition | None = None for workflow in workflows: defn = temporalio.workflow._Definition.must_from_class(workflow) # Confirm name unique @@ -439,7 +437,7 @@ async def _handle_cache_eviction( # swallowed. Any error or timeout of eviction causes us to retry # forever because something in users code is preventing eviction. seen_fail = False - handle_eviction_task: Optional[asyncio.Future] = None + handle_eviction_task: asyncio.Future | None = None while True: try: # We only create the eviction task if we haven't already or @@ -532,8 +530,8 @@ def _create_workflow_instance( ) # Build info - parent: Optional[temporalio.workflow.ParentInfo] = None - root: Optional[temporalio.workflow.RootInfo] = None + parent: temporalio.workflow.ParentInfo | None = None + root: temporalio.workflow.RootInfo | None = None if init.HasField("parent_workflow_info"): parent = temporalio.workflow.ParentInfo( namespace=init.parent_workflow_info.namespace, @@ -611,21 +609,21 @@ def nondeterminism_as_workflow_fail(self) -> bool: for typ in self._workflow_failure_exception_types ) - def nondeterminism_as_workflow_fail_for_types(self) -> Set[str]: - return set( + def nondeterminism_as_workflow_fail_for_types(self) -> set[str]: + return { k for k, v in self._workflows.items() if any( issubclass(temporalio.workflow.NondeterminismError, typ) for typ in v.failure_exception_types ) - ) + } class _DeadlockError(Exception): """Exception class for deadlocks. Contains functionality to swap the default traceback for another.""" - def __init__(self, message: str, replacement_tb: Optional[TracebackType] = None): + def __init__(self, message: str, replacement_tb: TracebackType | None = None): """Create a new DeadlockError, with message `message` and optionally a traceback `replacement_tb` to be swapped in later. Args: @@ -646,9 +644,7 @@ def swap_traceback(self) -> None: self._new_tb = None @classmethod - def from_deadlocked_workflow( - cls, workflow: WorkflowInstance, timeout: Optional[int] - ): + def from_deadlocked_workflow(cls, workflow: WorkflowInstance, timeout: int | None): msg = f"[TMPRL1101] Potential deadlock detected: workflow didn't yield within {timeout} second(s)." tid = workflow.get_thread_id() if not tid: @@ -665,7 +661,7 @@ def from_deadlocked_workflow( @staticmethod def _gen_tb_helper( tid: int, - ) -> Optional[TracebackType]: + ) -> TracebackType | None: """Take a thread id and construct a stack trace. Returns: @@ -700,7 +696,7 @@ class _RunningWorkflow: def __init__(self, instance: WorkflowInstance, workflow_id: str): self.instance = instance self.workflow_id = workflow_id - self.deadlocked_activation_task: Optional[Awaitable] = None + self.deadlocked_activation_task: Awaitable | None = None self._deadlock_can_be_interrupted_lock = threading.Lock() self._deadlock_can_be_interrupted = False @@ -745,13 +741,13 @@ class _CommandAwarePayloadCodec(temporalio.converter.PayloadCodec): async def encode( self, payloads: Sequence[temporalio.api.common.v1.Payload], - ) -> List[temporalio.api.common.v1.Payload]: + ) -> list[temporalio.api.common.v1.Payload]: return await self._get_current_command_codec().encode(payloads) async def decode( self, payloads: Sequence[temporalio.api.common.v1.Payload], - ) -> List[temporalio.api.common.v1.Payload]: + ) -> list[temporalio.api.common.v1.Payload]: return await self._get_current_command_codec().decode(payloads) def _get_current_command_codec(self) -> temporalio.converter.PayloadCodec: diff --git a/temporalio/worker/_workflow_instance.py b/temporalio/worker/_workflow_instance.py index bfb49f6d7..ce70abc01 100644 --- a/temporalio/worker/_workflow_instance.py +++ b/temporalio/worker/_workflow_instance.py @@ -14,30 +14,33 @@ import traceback import warnings from abc import ABC, abstractmethod +from collections.abc import ( + Awaitable, + Callable, + Coroutine, + Generator, + Iterable, + Iterator, + Mapping, + MutableMapping, + Sequence, +) from contextlib import contextmanager from dataclasses import dataclass from datetime import timedelta from enum import IntEnum from typing import ( Any, - Awaitable, - Callable, - Coroutine, Deque, Dict, - Generator, Generic, - Iterable, - Iterator, List, - Mapping, - MutableMapping, NoReturn, Optional, - Sequence, Set, Tuple, Type, + TypeAlias, TypeVar, Union, cast, @@ -45,7 +48,7 @@ import nexusrpc.handler from nexusrpc import InputT, OutputT -from typing_extensions import Self, TypeAlias, TypedDict, TypeVarTuple, Unpack +from typing_extensions import Self, TypedDict, TypeVarTuple, Unpack import temporalio.activity import temporalio.api.common.v1 @@ -121,7 +124,7 @@ def create_instance(self, det: WorkflowInstanceDetails) -> WorkflowInstance: raise NotImplementedError def set_worker_level_failure_exception_types( - self, types: Sequence[Type[BaseException]] + self, types: Sequence[type[BaseException]] ) -> None: """Set worker-level failure exception types that will be used to validate in the sandbox when calling ``prepare_workflow``. @@ -136,17 +139,17 @@ def set_worker_level_failure_exception_types( class WorkflowInstanceDetails: """Immutable details for creating a workflow instance.""" - payload_converter_class: Type[temporalio.converter.PayloadConverter] - failure_converter_class: Type[temporalio.converter.FailureConverter] - interceptor_classes: Sequence[Type[WorkflowInboundInterceptor]] + payload_converter_class: type[temporalio.converter.PayloadConverter] + failure_converter_class: type[temporalio.converter.FailureConverter] + interceptor_classes: Sequence[type[WorkflowInboundInterceptor]] defn: temporalio.workflow._Definition info: temporalio.workflow.Info randomness_seed: int extern_functions: Mapping[str, Callable] disable_eager_activity_execution: bool - worker_level_failure_exception_types: Sequence[Type[BaseException]] + worker_level_failure_exception_types: Sequence[type[BaseException]] last_completion_result: temporalio.api.common.v1.Payloads - last_failure: Optional[Failure] + last_failure: Failure | None class WorkflowInstance(ABC): @@ -172,8 +175,8 @@ def activate( @abstractmethod def get_serialization_context( self, - command_info: Optional[_command_aware_visitor.CommandInfo], - ) -> Optional[temporalio.converter.SerializationContext]: + command_info: _command_aware_visitor.CommandInfo | None, + ) -> temporalio.converter.SerializationContext | None: """Return appropriate serialization context. Args: @@ -185,7 +188,7 @@ def get_serialization_context( """ raise NotImplementedError - def get_thread_id(self) -> Optional[int]: + def get_thread_id(self) -> int | None: """Return the thread identifier that this workflow is running on. Not an abstractmethod because it is not mandatory to implement. Used primarily for getting the frames of a deadlocked thread. @@ -213,7 +216,7 @@ def create_instance(self, det: WorkflowInstanceDetails) -> WorkflowInstance: _T = TypeVar("_T") -_Context: TypeAlias = Dict[str, Any] +_Context: TypeAlias = dict[str, Any] _ExceptionHandler: TypeAlias = Callable[[asyncio.AbstractEventLoop, _Context], Any] @@ -225,7 +228,7 @@ def __init__(self, det: WorkflowInstanceDetails) -> None: WorkflowInstance.__init__(self) temporalio.workflow._Runtime.__init__(self) self._defn = det.defn - self._workflow_input: Optional[ExecuteWorkflowInput] = None + self._workflow_input: ExecuteWorkflowInput | None = None self._info = det.info self._context_free_payload_converter = det.payload_converter_class() self._context_free_failure_converter = det.failure_converter_class() @@ -245,32 +248,32 @@ def __init__(self, det: WorkflowInstanceDetails) -> None: self._worker_level_failure_exception_types = ( det.worker_level_failure_exception_types ) - self._primary_task: Optional[asyncio.Task[None]] = None + self._primary_task: asyncio.Task[None] | None = None self._time_ns = 0 self._cancel_requested = False - self._deployment_version_for_current_task: Optional[ + self._deployment_version_for_current_task: None | ( temporalio.bridge.proto.common.WorkerDeploymentVersion - ] = None + ) = None self._current_history_length = 0 self._current_history_size = 0 self._continue_as_new_suggested = False # Lazily loaded - self._untyped_converted_memo: Optional[MutableMapping[str, Any]] = None + self._untyped_converted_memo: MutableMapping[str, Any] | None = None # Handles which are ready to run on the next event loop iteration self._ready: Deque[asyncio.Handle] = collections.deque() - self._conditions: List[Tuple[Callable[[], bool], asyncio.Future]] = [] + self._conditions: list[tuple[Callable[[], bool], asyncio.Future]] = [] # Keyed by seq - self._pending_timers: Dict[int, _TimerHandle] = {} - self._pending_activities: Dict[int, _ActivityHandle] = {} - self._pending_child_workflows: Dict[int, _ChildWorkflowHandle] = {} - self._pending_nexus_operations: Dict[int, _NexusOperationHandle] = {} - self._pending_external_signals: Dict[int, Tuple[asyncio.Future, str]] = {} - self._pending_external_cancels: Dict[int, Tuple[asyncio.Future, str]] = {} + self._pending_timers: dict[int, _TimerHandle] = {} + self._pending_activities: dict[int, _ActivityHandle] = {} + self._pending_child_workflows: dict[int, _ChildWorkflowHandle] = {} + self._pending_nexus_operations: dict[int, _NexusOperationHandle] = {} + self._pending_external_signals: dict[int, tuple[asyncio.Future, str]] = {} + self._pending_external_cancels: dict[int, tuple[asyncio.Future, str]] = {} # Keyed by type - self._curr_seqs: Dict[str, int] = {} + self._curr_seqs: dict[str, int] = {} # TODO(cretz): Any concerns about not sharing this? Maybe the types I # need to lookup should be done at definition time? - self._exception_handler: Optional[_ExceptionHandler] = None + self._exception_handler: _ExceptionHandler | None = None # The actual instance, instantiated on first _run_once self._object: Any = None self._is_replaying: bool = False @@ -278,14 +281,14 @@ def __init__(self, det: WorkflowInstanceDetails) -> None: self._read_only = False # Patches we have been notified of and memoized patch responses - self._patches_notified: Set[str] = set() - self._patches_memoized: Dict[str, bool] = {} + self._patches_notified: set[str] = set() + self._patches_memoized: dict[str, bool] = {} # Tasks stored by asyncio are weak references and therefore can get GC'd # which can cause warnings like "Task was destroyed but it is pending!". # So we store the tasks ourselves. # See https://bugs.python.org/issue21163 and others. - self._tasks: Set[asyncio.Task] = set() + self._tasks: set[asyncio.Task] = set() # We maintain signals, queries, and updates on this class since handlers can be # added during workflow execution @@ -298,8 +301,8 @@ def __init__(self, det: WorkflowInstanceDetails) -> None: # signals lack a unique per-invocation identifier, we introduce a sequence number for the # purpose. self._handled_signals_seq = 0 - self._in_progress_signals: Dict[int, HandlerExecution] = {} - self._in_progress_updates: Dict[str, HandlerExecution] = {} + self._in_progress_signals: dict[int, HandlerExecution] = {} + self._in_progress_updates: dict[str, HandlerExecution] = {} # Add stack trace handler # TODO(cretz): Is it ok that this can be forcefully overridden by the @@ -333,8 +336,8 @@ def __init__(self, det: WorkflowInstanceDetails) -> None: ) # Maintain buffered signals for later-added dynamic handlers - self._buffered_signals: Dict[ - str, List[temporalio.bridge.proto.workflow_activation.SignalWorkflow] + self._buffered_signals: dict[ + str, list[temporalio.bridge.proto.workflow_activation.SignalWorkflow] ] = {} # When we evict, we have to mark the workflow as deleting so we don't @@ -342,10 +345,10 @@ def __init__(self, det: WorkflowInstanceDetails) -> None: self._deleting = False # We only create the metric meter lazily - self._metric_meter: Optional[_ReplaySafeMetricMeter] = None + self._metric_meter: _ReplaySafeMetricMeter | None = None # For tracking the thread this workflow is running on (primarily for deadlock situations) - self._current_thread_id: Optional[int] = None + self._current_thread_id: int | None = None # The current details (as opposed to static details on workflow start), returned in the # metadata query @@ -356,12 +359,12 @@ def __init__(self, det: WorkflowInstanceDetails) -> None: # The versioning behavior of this workflow, as established by annotation or by the dynamic # config function. Is only set once upon initialization. - self._versioning_behavior: Optional[temporalio.common.VersioningBehavior] = None + self._versioning_behavior: temporalio.common.VersioningBehavior | None = None # Dynamic failure exception types as overridden by the dynamic config function - self._dynamic_failure_exception_types: Optional[ - Sequence[type[BaseException]] - ] = None + self._dynamic_failure_exception_types: ( + None | (Sequence[type[BaseException]]) + ) = None # Create interceptors. We do this with our runtime on the loop just in # case they want to access info() during init(). This should remain at the end of the constructor so that variables are defined during interceptor creation @@ -381,7 +384,7 @@ def __init__(self, det: WorkflowInstanceDetails) -> None: # Set ourselves on our own loop temporalio.workflow._Runtime.set_on_loop(self, self) - def get_thread_id(self) -> Optional[int]: + def get_thread_id(self) -> int | None: return self._current_thread_id #### Activation functions #### @@ -398,7 +401,7 @@ def activate( ) self._current_completion.successful.SetInParent() - self._current_activation_error: Optional[Exception] = None + self._current_activation_error: Exception | None = None self._deployment_version_for_current_task = ( act.deployment_version_for_current_task ) @@ -409,13 +412,13 @@ def activate( self._is_replaying = act.is_replaying self._current_thread_id = threading.get_ident() self._current_internal_flags = act.available_internal_flags - activation_err: Optional[Exception] = None + activation_err: Exception | None = None try: # Split into job sets with patches, then signals + updates, then # non-queries, then queries start_job = None - job_sets: List[ - List[temporalio.bridge.proto.workflow_activation.WorkflowActivationJob] + job_sets: list[ + list[temporalio.bridge.proto.workflow_activation.WorkflowActivationJob] ] = [[], [], [], []] for job in act.jobs: if job.HasField("notify_has_patch"): @@ -801,7 +804,7 @@ def _apply_resolve_activity( payload_converter = self._payload_converter_with_context(activity_context) failure_converter = self._failure_converter_with_context(activity_context) if job.result.HasField("completed"): - ret: Optional[Any] = None + ret: Any | None = None if job.result.completed.HasField("result"): ret_types = [handle._input.ret_type] if handle._input.ret_type else None ret_vals = self._convert_payloads( @@ -839,7 +842,7 @@ def _apply_resolve_child_workflow_execution( ) if job.result.HasField("completed"): - ret: Optional[Any] = None + ret: Any | None = None if job.result.completed.HasField("result"): ret_types = [handle._input.ret_type] if handle._input.ret_type else None ret_vals = self._convert_payloads( @@ -1109,24 +1112,22 @@ def workflow_all_handlers_finished(self) -> bool: def workflow_continue_as_new( self, *args: Any, - workflow: Union[None, Callable, str], - task_queue: Optional[str], - run_timeout: Optional[timedelta], - task_timeout: Optional[timedelta], - retry_policy: Optional[temporalio.common.RetryPolicy], - memo: Optional[Mapping[str, Any]], - search_attributes: Optional[ - Union[ - temporalio.common.SearchAttributes, - temporalio.common.TypedSearchAttributes, - ] - ], - versioning_intent: Optional[temporalio.workflow.VersioningIntent], + workflow: None | Callable | str, + task_queue: str | None, + run_timeout: timedelta | None, + task_timeout: timedelta | None, + retry_policy: temporalio.common.RetryPolicy | None, + memo: Mapping[str, Any] | None, + search_attributes: None + | ( + temporalio.common.SearchAttributes | temporalio.common.TypedSearchAttributes + ), + versioning_intent: temporalio.workflow.VersioningIntent | None, ) -> NoReturn: self._assert_not_read_only("continue as new") # Use definition if callable - name: Optional[str] = None - arg_types: Optional[List[Type]] = None + name: str | None = None + arg_types: list[type] | None = None if isinstance(workflow, str): name = workflow elif callable(workflow): @@ -1164,7 +1165,7 @@ def workflow_get_current_build_id(self) -> str: def workflow_get_current_deployment_version( self, - ) -> Optional[temporalio.common.WorkerDeploymentVersion]: + ) -> temporalio.common.WorkerDeploymentVersion | None: if not self._deployment_version_for_current_task: return None return temporalio.common.WorkerDeploymentVersion( @@ -1179,32 +1180,32 @@ def workflow_get_current_history_size(self) -> int: return self._current_history_size def workflow_get_external_workflow_handle( - self, id: str, *, run_id: Optional[str] + self, id: str, *, run_id: str | None ) -> temporalio.workflow.ExternalWorkflowHandle[Any]: return _ExternalWorkflowHandle(self, id, run_id) - def workflow_get_query_handler(self, name: Optional[str]) -> Optional[Callable]: + def workflow_get_query_handler(self, name: str | None) -> Callable | None: defn = self._queries.get(name) if not defn: return None # Bind if a method return defn.bind_fn(self._object) if defn.is_method else defn.fn - def workflow_get_signal_handler(self, name: Optional[str]) -> Optional[Callable]: + def workflow_get_signal_handler(self, name: str | None) -> Callable | None: defn = self._signals.get(name) if not defn: return None # Bind if a method return defn.bind_fn(self._object) if defn.is_method else defn.fn - def workflow_get_update_handler(self, name: Optional[str]) -> Optional[Callable]: + def workflow_get_update_handler(self, name: str | None) -> Callable | None: defn = self._updates.get(name) if not defn: return None # Bind if a method return defn.bind_fn(self._object) if defn.is_method else defn.fn - def workflow_get_update_validator(self, name: Optional[str]) -> Optional[Callable]: + def workflow_get_update_validator(self, name: str | None) -> Callable | None: defn = self._updates.get(name) or self._updates.get(None) if not defn or not defn.validator: return None @@ -1232,7 +1233,7 @@ def workflow_memo(self) -> Mapping[str, Any]: return self._untyped_converted_memo def workflow_memo_value( - self, key: str, default: Any, *, type_hint: Optional[Type] + self, key: str, default: Any, *, type_hint: type | None ) -> Any: payload = self._info.raw_memo.get(key) if not payload: @@ -1328,7 +1329,7 @@ def workflow_random(self) -> random.Random: return self._random def workflow_set_query_handler( - self, name: Optional[str], handler: Optional[Callable] + self, name: str | None, handler: Callable | None ) -> None: self._assert_not_read_only("set query handler") if handler: @@ -1352,7 +1353,7 @@ def workflow_set_query_handler( self._queries.pop(name, None) def workflow_set_signal_handler( - self, name: Optional[str], handler: Optional[Callable] + self, name: str | None, handler: Callable | None ) -> None: self._assert_not_read_only("set signal handler") if handler: @@ -1380,9 +1381,9 @@ def workflow_set_signal_handler( def workflow_set_update_handler( self, - name: Optional[str], - handler: Optional[Callable], - validator: Optional[Callable], + name: str | None, + handler: Callable | None, + validator: Callable | None, ) -> None: self._assert_not_read_only("set update handler") if handler: @@ -1403,23 +1404,23 @@ def workflow_start_activity( self, activity: Any, *args: Any, - task_queue: Optional[str], - result_type: Optional[Type], - schedule_to_close_timeout: Optional[timedelta], - schedule_to_start_timeout: Optional[timedelta], - start_to_close_timeout: Optional[timedelta], - heartbeat_timeout: Optional[timedelta], - retry_policy: Optional[temporalio.common.RetryPolicy], + task_queue: str | None, + result_type: type | None, + schedule_to_close_timeout: timedelta | None, + schedule_to_start_timeout: timedelta | None, + start_to_close_timeout: timedelta | None, + heartbeat_timeout: timedelta | None, + retry_policy: temporalio.common.RetryPolicy | None, cancellation_type: temporalio.workflow.ActivityCancellationType, - activity_id: Optional[str], - versioning_intent: Optional[temporalio.workflow.VersioningIntent], - summary: Optional[str] = None, + activity_id: str | None, + versioning_intent: temporalio.workflow.VersioningIntent | None, + summary: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> temporalio.workflow.ActivityHandle[Any]: self._assert_not_read_only("start activity") # Get activity definition if it's callable name: str - arg_types: Optional[List[Type]] = None + arg_types: list[type] | None = None ret_type = result_type if isinstance(activity, str): name = activity @@ -1461,31 +1462,29 @@ async def workflow_start_child_workflow( workflow: Any, *args: Any, id: str, - task_queue: Optional[str], - result_type: Optional[Type], + task_queue: str | None, + result_type: type | None, cancellation_type: temporalio.workflow.ChildWorkflowCancellationType, parent_close_policy: temporalio.workflow.ParentClosePolicy, - execution_timeout: Optional[timedelta], - run_timeout: Optional[timedelta], - task_timeout: Optional[timedelta], + execution_timeout: timedelta | None, + run_timeout: timedelta | None, + task_timeout: timedelta | None, id_reuse_policy: temporalio.common.WorkflowIDReusePolicy, - retry_policy: Optional[temporalio.common.RetryPolicy], + retry_policy: temporalio.common.RetryPolicy | None, cron_schedule: str, - memo: Optional[Mapping[str, Any]], - search_attributes: Optional[ - Union[ - temporalio.common.SearchAttributes, - temporalio.common.TypedSearchAttributes, - ] - ], - versioning_intent: Optional[temporalio.workflow.VersioningIntent], - static_summary: Optional[str] = None, - static_details: Optional[str] = None, + memo: Mapping[str, Any] | None, + search_attributes: None + | ( + temporalio.common.SearchAttributes | temporalio.common.TypedSearchAttributes + ), + versioning_intent: temporalio.workflow.VersioningIntent | None, + static_summary: str | None = None, + static_details: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> temporalio.workflow.ChildWorkflowHandle[Any, Any]: # Use definition if callable name: str - arg_types: Optional[List[Type]] = None + arg_types: list[type] | None = None ret_type = result_type if isinstance(workflow, str): name = workflow @@ -1529,19 +1528,19 @@ def workflow_start_local_activity( self, activity: Any, *args: Any, - result_type: Optional[Type], - schedule_to_close_timeout: Optional[timedelta], - schedule_to_start_timeout: Optional[timedelta], - start_to_close_timeout: Optional[timedelta], - retry_policy: Optional[temporalio.common.RetryPolicy], - local_retry_threshold: Optional[timedelta], + result_type: type | None, + schedule_to_close_timeout: timedelta | None, + schedule_to_start_timeout: timedelta | None, + start_to_close_timeout: timedelta | None, + retry_policy: temporalio.common.RetryPolicy | None, + local_retry_threshold: timedelta | None, cancellation_type: temporalio.workflow.ActivityCancellationType, - activity_id: Optional[str], - summary: Optional[str], + activity_id: str | None, + summary: str | None, ) -> temporalio.workflow.ActivityHandle[Any]: # Get activity definition if it's callable name: str - arg_types: Optional[List[Type]] = None + arg_types: list[type] | None = None ret_type = result_type if isinstance(activity, str): name = activity @@ -1583,7 +1582,7 @@ async def workflow_start_nexus_operation( service: str, operation: nexusrpc.Operation[InputT, OutputT] | str | Callable[..., Any], input: Any, - output_type: Type[OutputT] | None, + output_type: type[OutputT] | None, schedule_to_close_timeout: timedelta | None, cancellation_type: temporalio.workflow.NexusOperationCancellationType, headers: Mapping[str, str] | None, @@ -1609,10 +1608,10 @@ def workflow_time_ns(self) -> int: def workflow_upsert_search_attributes( self, - attributes: Union[ - temporalio.common.SearchAttributes, - Sequence[temporalio.common.SearchAttributeUpdate], - ], + attributes: ( + temporalio.common.SearchAttributes + | Sequence[temporalio.common.SearchAttributeUpdate] + ), ) -> None: v = self._add_command().upsert_workflow_search_attributes @@ -1622,7 +1621,7 @@ def workflow_upsert_search_attributes( self._info.search_attributes, ) mut_typed_attrs = cast( - List[temporalio.common.SearchAttributePair], + list[temporalio.common.SearchAttributePair], self._info.typed_search_attributes.search_attributes, ) @@ -1695,7 +1694,7 @@ def workflow_upsert_search_attributes( if index is not None: del mut_typed_attrs[index] # Just empty-list the untyped one - mut_attrs[update.key.name] = cast(List[str], []) + mut_attrs[update.key.name] = cast(list[str], []) else: # Update pair = temporalio.common.SearchAttributePair( @@ -1714,7 +1713,7 @@ def workflow_upsert_search_attributes( ) async def workflow_sleep( - self, duration: float, *, summary: Optional[str] = None + self, duration: float, *, summary: str | None = None ) -> None: user_metadata = ( temporalio.api.sdk.v1.UserMetadata( @@ -1735,8 +1734,8 @@ async def workflow_wait_condition( self, fn: Callable[[], bool], *, - timeout: Optional[float] = None, - timeout_summary: Optional[str] = None, + timeout: float | None = None, + timeout_summary: str | None = None, ) -> None: self._assert_not_read_only("wait condition") fut = self.create_future() @@ -1785,9 +1784,7 @@ def workflow_is_failure_exception(self, err: BaseException) -> bool: def workflow_has_last_completion_result(self) -> bool: return len(self._last_completion_result.payloads) > 0 - def workflow_last_completion_result( - self, type_hint: Optional[Type] - ) -> Optional[Any]: + def workflow_last_completion_result(self, type_hint: type | None) -> Any | None: if len(self._last_completion_result.payloads) == 0: return None elif len(self._last_completion_result.payloads) > 1: @@ -1805,7 +1802,7 @@ def workflow_last_completion_result( self._last_completion_result.payloads[0], type_hint ) - def workflow_last_failure(self) -> Optional[BaseException]: + def workflow_last_failure(self) -> BaseException | None: if self._last_failure: return self._workflow_context_failure_converter.from_failure( self._last_failure, self._workflow_context_payload_converter @@ -1822,7 +1819,7 @@ def _outbound_continue_as_new(self, input: ContinueAsNewInput) -> NoReturn: def _outbound_schedule_activity( self, - input: Union[StartActivityInput, StartLocalActivityInput], + input: StartActivityInput | StartLocalActivityInput, ) -> _ActivityHandle: # Validate if not input.start_to_close_timeout and not input.schedule_to_close_timeout: @@ -2062,9 +2059,9 @@ def _check_condition(self, fn: Callable[[], bool], fut: asyncio.Future) -> bool: def _convert_payloads( self, payloads: Sequence[temporalio.api.common.v1.Payload], - types: Optional[List[Type]], + types: list[type] | None, payload_converter: temporalio.converter.PayloadConverter, - ) -> List[Any]: + ) -> list[Any]: if not payloads: return [] # Only use type hints if they match count @@ -2110,8 +2107,8 @@ def _failure_converter_with_context( def get_serialization_context( self, - command_info: Optional[_command_aware_visitor.CommandInfo], - ) -> Optional[temporalio.converter.SerializationContext]: + command_info: _command_aware_visitor.CommandInfo | None, + ) -> temporalio.converter.SerializationContext | None: if command_info is None: # Use payload codec with workflow context by default (i.e. for payloads not associated # with a pending command) @@ -2188,7 +2185,7 @@ def _instantiate_workflow_object(self) -> Any: if not self._workflow_input: raise RuntimeError("Expected workflow input. This is a Python SDK bug.") - if hasattr(self._defn.cls.__init__, "__temporal_workflow_init"): + if hasattr(self._defn.cls.__init__, "__temporal_workflow_init"): # type:ignore[misc] workflow_instance = self._defn.cls(*self._workflow_input.args) else: workflow_instance = self._defn.cls() @@ -2257,10 +2254,10 @@ def _process_handler_args( self, job_name: str, job_input: Sequence[temporalio.api.common.v1.Payload], - defn_name: Optional[str], - defn_arg_types: Optional[List[Type]], + defn_name: str | None, + defn_arg_types: list[type] | None, defn_dynamic_vararg: bool, - ) -> List[Any]: + ) -> list[Any]: # If dynamic old-style vararg, args become name + varargs of given arg # types. If dynamic new-style raw value sequence, args become name + # seq of raw values. @@ -2324,15 +2321,14 @@ def _register_task( self, task: asyncio.Task, *, - name: Optional[str], + name: str | None, ) -> None: self._assert_not_read_only("create task") # Name not supported on older Python versions - if sys.version_info >= (3, 8): - # Put the workflow info at the end of the task name - name = name or task.get_name() - name += f" (workflow: {self._info.workflow_type}, id: {self._info.workflow_id}, run: {self._info.run_id})" - task.set_name(name) + # Put the workflow info at the end of the task name + name = name or task.get_name() + name += f" (workflow: {self._info.workflow_type}, id: {self._info.workflow_id}, run: {self._info.run_id})" + task.set_name(name) # Add to and remove from our own non-weak set instead of relying on # Python's weak set which can collect these too early self._tasks.add(task) @@ -2489,14 +2485,14 @@ def _enhanced_stack_trace(self) -> temporalio.api.sdk.v1.EnhancedStackTrace: # this is to use `open` with temporalio.workflow.unsafe.sandbox_unrestricted(): - sources: Dict[str, temporalio.api.sdk.v1.StackTraceFileSlice] = dict() - stacks: List[temporalio.api.sdk.v1.StackTrace] = [] + sources: dict[str, temporalio.api.sdk.v1.StackTraceFileSlice] = dict() + stacks: list[temporalio.api.sdk.v1.StackTrace] = [] # future TODO # site package filter list -- we want to filter out traces from Python's internals and our sdk's internals. This is what `internal_code` is for, but right now it's just set to false. for task in list(self._tasks): - locations: List[temporalio.api.sdk.v1.StackTraceFileLocation] = [] + locations: list[temporalio.api.sdk.v1.StackTraceFileLocation] = [] for frame in task.get_stack(): filename = frame.f_code.co_filename @@ -2505,7 +2501,7 @@ def _enhanced_stack_trace(self) -> temporalio.api.sdk.v1.EnhancedStackTrace: if filename not in sources.keys(): try: - with open(filename, "r") as f: + with open(filename) as f: code = f.read() except OSError as ose: code = f"Cannot access code.\n---\n{ose.strerror}" @@ -2578,7 +2574,7 @@ def _timer_impl( options: _TimerOptions, callback: Callable[..., Any], *args: Any, - context: Optional[contextvars.Context] = None, + context: contextvars.Context | None = None, ): self._assert_not_read_only("schedule timer") # Delay must be positive @@ -2611,7 +2607,7 @@ def call_soon( self, callback: Callable[[Unpack[_Ts]], object], *args: Unpack[_Ts], - context: Optional[contextvars.Context] = None, + context: contextvars.Context | None = None, ) -> asyncio.Handle: # We need to allow this during delete because this is how tasks schedule # entire cancellation calls @@ -2625,7 +2621,7 @@ def call_later( delay: float, callback: Callable[[Unpack[_Ts]], object], *args: Unpack[_Ts], - context: Optional[contextvars.Context] = None, + context: contextvars.Context | None = None, ) -> asyncio.TimerHandle: options = _TimerOptionsCtxVar.get() return self._timer_impl(delay, options, callback, *args, context=context) @@ -2635,7 +2631,7 @@ def call_at( when: float, callback: Callable[[Unpack[_Ts]], object], *args: Unpack[_Ts], - context: Optional[contextvars.Context] = None, + context: contextvars.Context | None = None, ) -> asyncio.TimerHandle: # We usually would not support fixed-future-time call (and we didn't # previously), but 3.11 added asyncio.timeout which uses it and 3.12 @@ -2657,10 +2653,10 @@ def create_future(self) -> asyncio.Future[Any]: def create_task( self, - coro: Union[Awaitable[_T], Generator[Any, None, _T]], + coro: Awaitable[_T] | Generator[Any, None, _T], *, - name: Optional[str] = None, - context: Optional[contextvars.Context] = None, + name: str | None = None, + context: contextvars.Context | None = None, ) -> asyncio.Task[_T]: # Context only supported on newer Python versions if sys.version_info >= (3, 11): @@ -2670,13 +2666,13 @@ def create_task( self._register_task(task, name=name) return task - def get_exception_handler(self) -> Optional[_ExceptionHandler]: + def get_exception_handler(self) -> _ExceptionHandler | None: return self._exception_handler def get_task_factory(self) -> None: return None - def set_exception_handler(self, handler: Optional[_ExceptionHandler]) -> None: + def set_exception_handler(self, handler: _ExceptionHandler | None) -> None: self._exception_handler = handler def default_exception_handler(self, context: _Context) -> None: @@ -2860,7 +2856,7 @@ def start_local_activity( @dataclass(frozen=True) class _TimerOptions: - user_metadata: Optional[temporalio.api.sdk.v1.UserMetadata] = None + user_metadata: temporalio.api.sdk.v1.UserMetadata | None = None _TimerOptionsCtxVar: contextvars.ContextVar[_TimerOptions] = contextvars.ContextVar( @@ -2873,11 +2869,11 @@ def __init__( self, seq: int, when: float, - options: Optional[_TimerOptions], + options: _TimerOptions | None, callback: Callable[..., Any], args: Sequence[Any], loop: asyncio.AbstractEventLoop, - context: Optional[contextvars.Context], + context: contextvars.Context | None, ) -> None: super().__init__(when, callback, args, loop, context) self._seq = seq @@ -2912,7 +2908,7 @@ class _ActivityHandle(temporalio.workflow.ActivityHandle[Any]): def __init__( self, instance: _WorkflowInstanceImpl, - input: Union[StartActivityInput, StartLocalActivityInput], + input: StartActivityInput | StartLocalActivityInput, fn: Coroutine[Any, Any, Any], ) -> None: super().__init__(fn) @@ -2937,7 +2933,7 @@ def __init__( ) ) - def cancel(self, msg: Optional[Any] = None) -> bool: + def cancel(self, msg: Any | None = None) -> bool: # Allow the cancel to go through for the task even if we're deleting, # just don't do any commands if not self._instance._deleting: @@ -2977,9 +2973,8 @@ def _resolve_backoff( def _apply_schedule_command( self, - local_backoff: Optional[ - temporalio.bridge.proto.activity_result.DoBackoff - ] = None, + local_backoff: None + | (temporalio.bridge.proto.activity_result.DoBackoff) = None, ) -> None: # Convert arguments before creating command in case it raises error payloads = ( @@ -2990,10 +2985,10 @@ def _apply_schedule_command( command = self._instance._add_command() # TODO(cretz): Why can't MyPy infer this? - v: Union[ - temporalio.bridge.proto.workflow_commands.ScheduleActivity, - temporalio.bridge.proto.workflow_commands.ScheduleLocalActivity, - ] = ( + v: ( + temporalio.bridge.proto.workflow_commands.ScheduleActivity + | temporalio.bridge.proto.workflow_commands.ScheduleLocalActivity + ) = ( command.schedule_local_activity if isinstance(self._input, StartLocalActivityInput) else command.schedule_activity @@ -3099,12 +3094,12 @@ def id(self) -> str: return self._input.id @property - def first_execution_run_id(self) -> Optional[str]: + def first_execution_run_id(self) -> str | None: return self._first_execution_run_id async def signal( self, - signal: Union[str, Callable], + signal: str | Callable, arg: Any = temporalio.common._arg_unset, *, args: Sequence[Any] = [], @@ -3213,7 +3208,7 @@ def __init__( self, instance: _WorkflowInstanceImpl, id: str, - run_id: Optional[str], + run_id: str | None, ) -> None: super().__init__() self._instance = instance @@ -3225,12 +3220,12 @@ def id(self) -> str: return self._id @property - def run_id(self) -> Optional[str]: + def run_id(self) -> str | None: return self._run_id async def signal( self, - signal: Union[str, Callable], + signal: str | Callable, arg: Any = temporalio.common._arg_unset, *, args: Sequence[Any] = [], @@ -3275,13 +3270,13 @@ def __init__( self._seq = seq self._input = input self._task = asyncio.Task(fn) - self._start_fut: asyncio.Future[Optional[str]] = instance.create_future() - self._result_fut: asyncio.Future[Optional[OutputT]] = instance.create_future() + self._start_fut: asyncio.Future[str | None] = instance.create_future() + self._result_fut: asyncio.Future[OutputT | None] = instance.create_future() self._payload_converter = self._instance._context_free_payload_converter self._failure_converter = self._instance._context_free_failure_converter @property - def operation_token(self) -> Optional[str]: + def operation_token(self) -> str | None: try: return self._start_fut.result() except BaseException: @@ -3293,7 +3288,7 @@ def __await__(self) -> Generator[Any, Any, OutputT]: def cancel(self) -> bool: return self._task.cancel() - def _resolve_start_success(self, operation_token: Optional[str]) -> None: + def _resolve_start_success(self, operation_token: str | None) -> None: # We intentionally let this error if already done self._start_fut.set_result(operation_token) @@ -3401,9 +3396,9 @@ def _apply_command(self) -> None: def _encode_search_attributes( - attributes: Union[ - temporalio.common.SearchAttributes, temporalio.common.TypedSearchAttributes - ], + attributes: ( + temporalio.common.SearchAttributes | temporalio.common.TypedSearchAttributes + ), payloads: Mapping[str, temporalio.api.common.v1.Payload], ) -> None: if isinstance(attributes, temporalio.common.TypedSearchAttributes): @@ -3430,42 +3425,42 @@ def __init__(self, underlying: temporalio.common.MetricMeter) -> None: self._underlying = underlying def create_counter( - self, name: str, description: Optional[str] = None, unit: Optional[str] = None + self, name: str, description: str | None = None, unit: str | None = None ) -> temporalio.common.MetricCounter: return _ReplaySafeMetricCounter( self._underlying.create_counter(name, description, unit) ) def create_histogram( - self, name: str, description: Optional[str] = None, unit: Optional[str] = None + self, name: str, description: str | None = None, unit: str | None = None ) -> temporalio.common.MetricHistogram: return _ReplaySafeMetricHistogram( self._underlying.create_histogram(name, description, unit) ) def create_histogram_float( - self, name: str, description: Optional[str] = None, unit: Optional[str] = None + self, name: str, description: str | None = None, unit: str | None = None ) -> temporalio.common.MetricHistogramFloat: return _ReplaySafeMetricHistogramFloat( self._underlying.create_histogram_float(name, description, unit) ) def create_histogram_timedelta( - self, name: str, description: Optional[str] = None, unit: Optional[str] = None + self, name: str, description: str | None = None, unit: str | None = None ) -> temporalio.common.MetricHistogramTimedelta: return _ReplaySafeMetricHistogramTimedelta( self._underlying.create_histogram_timedelta(name, description, unit) ) def create_gauge( - self, name: str, description: Optional[str] = None, unit: Optional[str] = None + self, name: str, description: str | None = None, unit: str | None = None ) -> temporalio.common.MetricGauge: return _ReplaySafeMetricGauge( self._underlying.create_gauge(name, description, unit) ) def create_gauge_float( - self, name: str, description: Optional[str] = None, unit: Optional[str] = None + self, name: str, description: str | None = None, unit: str | None = None ) -> temporalio.common.MetricGaugeFloat: return _ReplaySafeMetricGaugeFloat( self._underlying.create_gauge_float(name, description, unit) @@ -3491,11 +3486,11 @@ def name(self) -> str: return self._underlying.name @property - def description(self) -> Optional[str]: + def description(self) -> str | None: return self._underlying.description @property - def unit(self) -> Optional[str]: + def unit(self) -> str | None: return self._underlying.unit def with_additional_attributes( @@ -3513,7 +3508,7 @@ class _ReplaySafeMetricCounter( def add( self, value: int, - additional_attributes: Optional[temporalio.common.MetricAttributes] = None, + additional_attributes: temporalio.common.MetricAttributes | None = None, ) -> None: if not temporalio.workflow.unsafe.is_replaying(): self._underlying.add(value, additional_attributes) @@ -3526,7 +3521,7 @@ class _ReplaySafeMetricHistogram( def record( self, value: int, - additional_attributes: Optional[temporalio.common.MetricAttributes] = None, + additional_attributes: temporalio.common.MetricAttributes | None = None, ) -> None: if not temporalio.workflow.unsafe.is_replaying(): self._underlying.record(value, additional_attributes) @@ -3539,7 +3534,7 @@ class _ReplaySafeMetricHistogramFloat( def record( self, value: float, - additional_attributes: Optional[temporalio.common.MetricAttributes] = None, + additional_attributes: temporalio.common.MetricAttributes | None = None, ) -> None: if not temporalio.workflow.unsafe.is_replaying(): self._underlying.record(value, additional_attributes) @@ -3552,7 +3547,7 @@ class _ReplaySafeMetricHistogramTimedelta( def record( self, value: timedelta, - additional_attributes: Optional[temporalio.common.MetricAttributes] = None, + additional_attributes: temporalio.common.MetricAttributes | None = None, ) -> None: if not temporalio.workflow.unsafe.is_replaying(): self._underlying.record(value, additional_attributes) @@ -3565,7 +3560,7 @@ class _ReplaySafeMetricGauge( def set( self, value: int, - additional_attributes: Optional[temporalio.common.MetricAttributes] = None, + additional_attributes: temporalio.common.MetricAttributes | None = None, ) -> None: if not temporalio.workflow.unsafe.is_replaying(): self._underlying.set(value, additional_attributes) @@ -3578,7 +3573,7 @@ class _ReplaySafeMetricGaugeFloat( def set( self, value: float, - additional_attributes: Optional[temporalio.common.MetricAttributes] = None, + additional_attributes: temporalio.common.MetricAttributes | None = None, ) -> None: if not temporalio.workflow.unsafe.is_replaying(): self._underlying.set(value, additional_attributes) @@ -3594,11 +3589,11 @@ class HandlerExecution: name: str unfinished_policy: temporalio.workflow.HandlerUnfinishedPolicy - id: Optional[str] = None + id: str | None = None def _make_unfinished_update_handler_message( - handler_executions: List[HandlerExecution], + handler_executions: list[HandlerExecution], ) -> str: message = """ [TMPRL1102] Workflow finished while update handlers are still running. This may have interrupted work that the @@ -3617,7 +3612,7 @@ def _make_unfinished_update_handler_message( def _make_unfinished_signal_handler_message( - handler_executions: List[HandlerExecution], + handler_executions: list[HandlerExecution], ) -> str: message = """ [TMPRL1102] Workflow finished while signal handlers are still running. This may have interrupted work that the diff --git a/temporalio/worker/workflow_sandbox/_importer.py b/temporalio/worker/workflow_sandbox/_importer.py index 7b5263340..1ee48febb 100644 --- a/temporalio/worker/workflow_sandbox/_importer.py +++ b/temporalio/worker/workflow_sandbox/_importer.py @@ -15,18 +15,14 @@ import threading import types import warnings +from collections.abc import Callable, Iterator, Mapping, MutableMapping, Sequence from contextlib import ExitStack, contextmanager from typing import ( Any, - Callable, Dict, Generic, - Iterator, List, - Mapping, - MutableMapping, Optional, - Sequence, Set, Tuple, TypeVar, @@ -67,17 +63,17 @@ def __init__( """Create importer.""" self.restrictions = restrictions self.restriction_context = restriction_context - self.new_modules: Dict[str, types.ModuleType] = { + self.new_modules: dict[str, types.ModuleType] = { "sys": sys, "builtins": builtins, # Even though we don't want to, we have to have __main__ because # stdlib packages like inspect and others expect it to be present "__main__": types.ModuleType("__main__"), } - self.modules_checked_for_restrictions: Set[str] = set() + self.modules_checked_for_restrictions: set[str] = set() self.import_func = self._import if not LOG_TRACE else self._traced_import # Pre-collect restricted builtins - self.restricted_builtins: List[Tuple[str, _ThreadLocalCallable, Callable]] = [] + self.restricted_builtins: list[tuple[str, _ThreadLocalCallable, Callable]] = [] builtin_matcher = restrictions.invalid_module_members.child_matcher( "__builtins__" ) @@ -174,8 +170,8 @@ def _unapplied(self) -> Iterator[None]: def _traced_import( self, name: str, - globals: Optional[Mapping[str, object]] = None, - locals: Optional[Mapping[str, object]] = None, + globals: Mapping[str, object] | None = None, + locals: Mapping[str, object] | None = None, fromlist: Sequence[str] = (), level: int = 0, ) -> types.ModuleType: @@ -190,8 +186,8 @@ def _traced_import( def _import( self, name: str, - globals: Optional[Mapping[str, object]] = None, - locals: Optional[Mapping[str, object]] = None, + globals: Mapping[str, object] | None = None, + locals: Mapping[str, object] | None = None, fromlist: Sequence[str] = (), level: int = 0, ) -> types.ModuleType: @@ -305,7 +301,7 @@ def _is_import_notification_policy_applied( return policy in self.restrictions.import_notification_policy - def _maybe_passthrough_module(self, name: str) -> Optional[types.ModuleType]: + def _maybe_passthrough_module(self, name: str) -> types.ModuleType | None: # If imports not passed through and all modules are not passed through # and name not in passthrough modules, check parents if ( @@ -336,9 +332,7 @@ def _maybe_passthrough_module(self, name: str) -> Optional[types.ModuleType]: finally: _trace_depth -= 1 - def _maybe_restrict_module( - self, mod: types.ModuleType - ) -> Optional[types.ModuleType]: + def _maybe_restrict_module(self, mod: types.ModuleType) -> types.ModuleType | None: """Implements :py:meth:`_Environment.maybe_restrict_module`.""" matcher = self.restrictions.invalid_module_members.child_matcher( *mod.__name__.split(".") @@ -373,7 +367,7 @@ def _builtins_unrestricted(self) -> Iterator[None]: _thread_local_current = threading.local() @staticmethod - def current_importer() -> Optional[Importer]: + def current_importer() -> Importer | None: """Get the current importer if any.""" return Importer._thread_local_current.__dict__.get("importer") @@ -389,7 +383,7 @@ def __init__(self, orig: _T) -> None: self.applied_counter_lock = threading.Lock() @property - def maybe_current(self) -> Optional[_T]: + def maybe_current(self) -> _T | None: return self.thread_local.__dict__.get("data") @property @@ -447,7 +441,7 @@ def unapplied(self) -> Iterator[None]: class _ThreadLocalSysModules( - _ThreadLocalOverride[Dict[str, types.ModuleType]], + _ThreadLocalOverride[dict[str, types.ModuleType]], MutableMapping[str, types.ModuleType], ): def __contains__(self, key: object) -> bool: @@ -486,28 +480,28 @@ def __setitem__(self, key: str, value: types.ModuleType) -> None: def __or__( self, other: Mapping[str, types.ModuleType] - ) -> Dict[str, types.ModuleType]: + ) -> dict[str, types.ModuleType]: if sys.version_info < (3, 9): raise NotImplementedError return self.current.__or__(other) # type: ignore[operator] def __ior__( self, other: Mapping[str, types.ModuleType] - ) -> Dict[str, types.ModuleType]: + ) -> dict[str, types.ModuleType]: if sys.version_info < (3, 9): raise NotImplementedError return self.current.__ior__(other) __ror__ = __or__ - def copy(self) -> Dict[str, types.ModuleType]: + def copy(self) -> dict[str, types.ModuleType]: return self.current.copy() @classmethod def fromkeys(cls, *args, **kwargs) -> Any: return dict.fromkeys(*args, **kwargs) - def _lazily_passthrough_if_available(self, key: str) -> Optional[types.ModuleType]: + def _lazily_passthrough_if_available(self, key: str) -> types.ModuleType | None: # We only lazily pass through if it's in orig, lazy not disabled, and # module configured as pass through if ( @@ -534,7 +528,7 @@ def __call__(self, *args: _P.args, **kwargs: _P.kwargs) -> _T: _thread_local_import = _ThreadLocalCallable(builtins.__import__) -_thread_local_builtins: Dict[str, _ThreadLocalCallable] = {} +_thread_local_builtins: dict[str, _ThreadLocalCallable] = {} def _get_thread_local_builtin(name: str) -> _ThreadLocalCallable: @@ -546,7 +540,7 @@ def _get_thread_local_builtin(name: str) -> _ThreadLocalCallable: def _resolve_module_name( - name: str, globals: Optional[Mapping[str, object]], level: int + name: str, globals: Mapping[str, object] | None, level: int ) -> str: if level == 0: return name diff --git a/temporalio/worker/workflow_sandbox/_in_sandbox.py b/temporalio/worker/workflow_sandbox/_in_sandbox.py index 17a5c5742..3756749ca 100644 --- a/temporalio/worker/workflow_sandbox/_in_sandbox.py +++ b/temporalio/worker/workflow_sandbox/_in_sandbox.py @@ -32,8 +32,8 @@ class InSandbox: def __init__( self, instance_details: temporalio.worker._workflow_instance.WorkflowInstanceDetails, - runner_class: Type[temporalio.worker._workflow_instance.WorkflowRunner], - workflow_class: Type, + runner_class: type[temporalio.worker._workflow_instance.WorkflowRunner], + workflow_class: type, ) -> None: """Create in-sandbox instance.""" _trace("Initializing workflow %s in sandbox", workflow_class) @@ -84,7 +84,7 @@ def activate( def get_serialization_context( self, - command_info: Optional[_command_aware_visitor.CommandInfo], - ) -> Optional[temporalio.converter.SerializationContext]: + command_info: _command_aware_visitor.CommandInfo | None, + ) -> temporalio.converter.SerializationContext | None: """Get serialization context.""" return self.instance.get_serialization_context(command_info) diff --git a/temporalio/worker/workflow_sandbox/_restrictions.py b/temporalio/worker/workflow_sandbox/_restrictions.py index 6eae9944e..c8438b669 100644 --- a/temporalio/worker/workflow_sandbox/_restrictions.py +++ b/temporalio/worker/workflow_sandbox/_restrictions.py @@ -17,16 +17,14 @@ import sys import types import warnings +from collections.abc import Callable, Mapping, Sequence from copy import copy, deepcopy from dataclasses import dataclass from typing import ( Any, - Callable, ClassVar, Dict, - Mapping, Optional, - Sequence, Set, Tuple, Type, @@ -63,7 +61,7 @@ class RestrictedWorkflowAccessError(temporalio.workflow.NondeterminismError): """ def __init__( - self, qualified_name: str, *, override_message: Optional[str] = None + self, qualified_name: str, *, override_message: str | None = None ) -> None: """Create restricted workflow access error.""" super().__init__( @@ -102,7 +100,7 @@ def __init__(self, qualified_name: str) -> None: class SandboxRestrictions: """Set of restrictions that can be applied to a sandbox.""" - passthrough_modules: Set[str] + passthrough_modules: set[str] """ Modules which pass through because we know they are side-effect free (or the side-effecting pieces are restricted). These modules will not be reloaded, @@ -153,19 +151,19 @@ class methods (including __init__, etc). The check compares the against the to have been explicitly imported. """ - passthrough_modules_minimum: ClassVar[Set[str]] + passthrough_modules_minimum: ClassVar[set[str]] """Set of modules that must be passed through at the minimum.""" - passthrough_modules_with_temporal: ClassVar[Set[str]] + passthrough_modules_with_temporal: ClassVar[set[str]] """Minimum modules that must be passed through and the Temporal modules.""" - passthrough_modules_maximum: ClassVar[Set[str]] + passthrough_modules_maximum: ClassVar[set[str]] """ All modules that can be passed through. This includes all standard library modules. """ - passthrough_modules_default: ClassVar[Set[str]] + passthrough_modules_default: ClassVar[set[str]] """Same as :py:attr:`passthrough_modules_maximum`.""" invalid_module_members_default: ClassVar[SandboxMatcher] @@ -227,7 +225,7 @@ def nested_child(cls, path: Sequence[str], child: SandboxMatcher) -> SandboxMatc ret = cls(children={key: ret}) return ret - access: Set[str] = frozenset() # type: ignore + access: set[str] = frozenset() # type: ignore """Immutable set of names to match access. This is often only used for pass through checks and not member restrictions. @@ -237,7 +235,7 @@ def nested_child(cls, path: Sequence[str], child: SandboxMatcher) -> SandboxMatc An string containing a single asterisk can be used to match all. """ - use: Set[str] = frozenset() # type: ignore + use: set[str] = frozenset() # type: ignore """Immutable set of names to match use. This is best used for member restrictions on functions/classes because the @@ -259,21 +257,21 @@ def nested_child(cls, path: Sequence[str], child: SandboxMatcher) -> SandboxMatc time. """ - leaf_message: Optional[str] = None + leaf_message: str | None = None """ Override message to use in error/warning. Defaults to a common message. This is only applicable to leafs, so this must only be set when ``match_self`` is ``True`` and this matcher is on ``children`` of a parent. """ - leaf_warning: Optional[Type[Warning]] = None + leaf_warning: type[Warning] | None = None """ If set, issues a warning instead of raising an error. This is only applicable to leafs, so this must only be set when ``match_self`` is ``True`` and this matcher is on ``children`` of a parent. """ - exclude: Set[str] = frozenset() # type: ignore + exclude: set[str] = frozenset() # type: ignore """Immutable set of names to exclude. These override anything that may have been matched elsewhere. @@ -303,7 +301,7 @@ def __post_init__(self): def access_matcher( self, context: RestrictionContext, *child_path: str, include_use: bool = False - ) -> Optional[SandboxMatcher]: + ) -> SandboxMatcher | None: """Perform a match check and return matcher. Args: @@ -360,7 +358,7 @@ def match_access( is not None ) - def child_matcher(self, *child_path: str) -> Optional[SandboxMatcher]: + def child_matcher(self, *child_path: str) -> SandboxMatcher | None: """Return a child matcher for the given path. Unlike :py:meth:`match_access`, this will match if in py:attr:`use` in @@ -373,7 +371,7 @@ def child_matcher(self, *child_path: str) -> Optional[SandboxMatcher]: Matcher that can be used to check children. """ # We prefer to avoid recursion - matcher: Optional[SandboxMatcher] = self + matcher: SandboxMatcher | None = self only_runtime = self.only_runtime for v in child_path: # Use all if it matches self, access, _or_ use. Use doesn't match @@ -441,7 +439,7 @@ def with_child_unrestricted(self, *child_path: str) -> SandboxMatcher: assert child_path # If there's only one item in path, make sure not in access, use, or # children. Otherwise, just remove from child. - to_replace: Dict[str, Any] = {} + to_replace: dict[str, Any] = {} if len(child_path) == 1: if child_path[0] in self.access: to_replace["access"] = set(self.access) @@ -545,8 +543,8 @@ def with_child_unrestricted(self, *child_path: str) -> SandboxMatcher: ) -def _public_callables(parent: Any, *, exclude: Set[str] = set()) -> Set[str]: - ret: Set[str] = set() +def _public_callables(parent: Any, *, exclude: set[str] = set()) -> set[str]: + ret: set[str] = set() for name, member in inspect.getmembers(parent): # Name must be public and callable and not in exclude and not a class if ( @@ -865,13 +863,13 @@ def set_on_proxy(self, v: _RestrictedProxy) -> None: class _RestrictedProxyLookup: def __init__( self, - access_func: Optional[Callable] = None, + access_func: Callable | None = None, *, - fallback_func: Optional[Callable] = None, - class_value: Optional[Any] = None, + fallback_func: Callable | None = None, + class_value: Any | None = None, is_attr: bool = False, ) -> None: - bind_func: Optional[Callable[[_RestrictedProxy, Any], Callable]] + bind_func: Callable[[_RestrictedProxy, Any], Callable] | None if hasattr(access_func, "__get__"): # A Python function, can be turned into a bound method. @@ -896,7 +894,7 @@ def bind_func(instance: _RestrictedProxy, obj: Any) -> Callable: def __set_name__(self, owner: _RestrictedProxy, name: str) -> None: self.name = name - def __get__(self, instance: _RestrictedProxy, owner: Optional[Type] = None) -> Any: + def __get__(self, instance: _RestrictedProxy, owner: type | None = None) -> Any: if instance is None: if self.class_value is not None: return self.class_value @@ -942,9 +940,9 @@ class _RestrictedProxyIOp(_RestrictedProxyLookup): def __init__( self, - access_func: Optional[Callable] = None, + access_func: Callable | None = None, *, - fallback_func: Optional[Callable] = None, + fallback_func: Callable | None = None, ) -> None: super().__init__(access_func, fallback_func=fallback_func) @@ -970,7 +968,7 @@ def r_op(obj: Any, other: Any) -> Any: return cast(_OpF, r_op) -_do_not_restrict: Tuple[Type, ...] = (bool, int, float, complex, str, bytes, bytearray) +_do_not_restrict: tuple[type, ...] = (bool, int, float, complex, str, bytes, bytearray) if HAVE_PYDANTIC: # The datetime validator in pydantic_core # https://github.com/pydantic/pydantic-core/blob/741961c05847d9e9ee517cd783e24c2b58e5596b/src/input/input_python.rs#L548-L582 diff --git a/temporalio/worker/workflow_sandbox/_runner.py b/temporalio/worker/workflow_sandbox/_runner.py index f87736f9d..35023f141 100644 --- a/temporalio/worker/workflow_sandbox/_runner.py +++ b/temporalio/worker/workflow_sandbox/_runner.py @@ -7,9 +7,10 @@ from __future__ import annotations import threading +from collections.abc import Sequence from dataclasses import dataclass, field from datetime import datetime, timedelta, timezone -from typing import Any, Optional, Sequence, Type +from typing import Any, Optional, Type import temporalio.bridge.proto.workflow_activation import temporalio.bridge.proto.workflow_completion @@ -64,7 +65,7 @@ class SandboxedWorkflowRunner(WorkflowRunner): restrictions: SandboxRestrictions = SandboxRestrictions.default """Set of restrictions to apply to this sandbox""" - runner_class: Type[WorkflowRunner] = UnsandboxedWorkflowRunner + runner_class: type[WorkflowRunner] = UnsandboxedWorkflowRunner """The class for underlying runner the sandbox will instantiate and use to run workflows. Note, this class is re-imported and instantiated for *each* workflow run.""" @@ -109,14 +110,14 @@ class _Instance(WorkflowInstance): def __init__( self, instance_details: WorkflowInstanceDetails, - runner_class: Type[WorkflowRunner], + runner_class: type[WorkflowRunner], restrictions: SandboxRestrictions, ) -> None: self.instance_details = instance_details self.runner_class = runner_class self.importer = Importer(restrictions, RestrictionContext()) - self._current_thread_id: Optional[int] = None + self._current_thread_id: int | None = None # Create the instance self.globals_and_locals = { @@ -185,13 +186,13 @@ def _run_code(self, code: str, **extra_globals: Any) -> None: for k, v in extra_globals.items(): self.globals_and_locals.pop(k, None) - def get_thread_id(self) -> Optional[int]: + def get_thread_id(self) -> int | None: return self._current_thread_id def get_serialization_context( self, - command_info: Optional[_command_aware_visitor.CommandInfo], - ) -> Optional[temporalio.converter.SerializationContext]: + command_info: _command_aware_visitor.CommandInfo | None, + ) -> temporalio.converter.SerializationContext | None: # Forward call to the sandboxed instance self.importer.restriction_context.is_runtime = True try: diff --git a/temporalio/workflow.py b/temporalio/workflow.py index 506769c63..89454da89 100644 --- a/temporalio/workflow.py +++ b/temporalio/workflow.py @@ -10,6 +10,16 @@ import uuid import warnings from abc import ABC, abstractmethod +from collections.abc import ( + Awaitable, + Callable, + Generator, + Iterable, + Iterator, + Mapping, + MutableMapping, + Sequence, +) from contextlib import contextmanager from dataclasses import dataclass from datetime import datetime, timedelta, timezone @@ -19,19 +29,13 @@ from typing import ( TYPE_CHECKING, Any, - Awaitable, - Callable, + Concatenate, Dict, - Generator, Generic, - Iterable, - Iterator, List, - Mapping, - MutableMapping, + Literal, NoReturn, Optional, - Sequence, Tuple, Type, TypeVar, @@ -44,8 +48,6 @@ import nexusrpc.handler from nexusrpc import InputT, OutputT from typing_extensions import ( - Concatenate, - Literal, Protocol, TypedDict, runtime_checkable, @@ -93,9 +95,9 @@ def defn(cls: ClassType) -> ClassType: ... @overload def defn( *, - name: Optional[str] = None, + name: str | None = None, sandboxed: bool = True, - failure_exception_types: Sequence[Type[BaseException]] = [], + failure_exception_types: Sequence[type[BaseException]] = [], versioning_behavior: temporalio.common.VersioningBehavior = temporalio.common.VersioningBehavior.UNSPECIFIED, ) -> Callable[[ClassType], ClassType]: ... @@ -110,12 +112,12 @@ def defn( def defn( - cls: Optional[ClassType] = None, + cls: ClassType | None = None, *, - name: Optional[str] = None, + name: str | None = None, sandboxed: bool = True, dynamic: bool = False, - failure_exception_types: Sequence[Type[BaseException]] = [], + failure_exception_types: Sequence[type[BaseException]] = [], versioning_behavior: temporalio.common.VersioningBehavior = temporalio.common.VersioningBehavior.UNSPECIFIED, ): """Decorator for workflow classes. @@ -239,7 +241,7 @@ def signal( def signal( *, unfinished_policy: HandlerUnfinishedPolicy = HandlerUnfinishedPolicy.WARN_AND_ABANDON, - description: Optional[str] = None, + description: str | None = None, ) -> Callable[ [CallableSyncOrAsyncReturnNoneType], CallableSyncOrAsyncReturnNoneType ]: ... @@ -250,7 +252,7 @@ def signal( *, name: str, unfinished_policy: HandlerUnfinishedPolicy = HandlerUnfinishedPolicy.WARN_AND_ABANDON, - description: Optional[str] = None, + description: str | None = None, ) -> Callable[ [CallableSyncOrAsyncReturnNoneType], CallableSyncOrAsyncReturnNoneType ]: ... @@ -261,19 +263,19 @@ def signal( *, dynamic: Literal[True], unfinished_policy: HandlerUnfinishedPolicy = HandlerUnfinishedPolicy.WARN_AND_ABANDON, - description: Optional[str] = None, + description: str | None = None, ) -> Callable[ [CallableSyncOrAsyncReturnNoneType], CallableSyncOrAsyncReturnNoneType ]: ... def signal( - fn: Optional[CallableSyncOrAsyncReturnNoneType] = None, + fn: CallableSyncOrAsyncReturnNoneType | None = None, *, - name: Optional[str] = None, - dynamic: Optional[bool] = False, + name: str | None = None, + dynamic: bool | None = False, unfinished_policy: HandlerUnfinishedPolicy = HandlerUnfinishedPolicy.WARN_AND_ABANDON, - description: Optional[str] = None, + description: str | None = None, ): """Decorator for a workflow signal method. @@ -300,7 +302,7 @@ def signal( """ def decorator( - name: Optional[str], + name: str | None, unfinished_policy: HandlerUnfinishedPolicy, fn: CallableSyncOrAsyncReturnNoneType, ) -> CallableSyncOrAsyncReturnNoneType: @@ -336,13 +338,13 @@ def query(fn: CallableType) -> CallableType: ... @overload def query( - *, name: str, description: Optional[str] = None + *, name: str, description: str | None = None ) -> Callable[[CallableType], CallableType]: ... @overload def query( - *, dynamic: Literal[True], description: Optional[str] = None + *, dynamic: Literal[True], description: str | None = None ) -> Callable[[CallableType], CallableType]: ... @@ -351,11 +353,11 @@ def query(*, description: str) -> Callable[[CallableType], CallableType]: ... def query( - fn: Optional[CallableType] = None, + fn: CallableType | None = None, *, - name: Optional[str] = None, - dynamic: Optional[bool] = False, - description: Optional[str] = None, + name: str | None = None, + dynamic: bool | None = False, + description: str | None = None, ): """Decorator for a workflow query method. @@ -380,8 +382,8 @@ def query( """ def decorator( - name: Optional[str], - description: Optional[str], + name: str | None, + description: str | None, fn: CallableType, *, bypass_async_check: bool = False, @@ -425,7 +427,7 @@ def decorator( class DynamicWorkflowConfig: """Returned by functions using the :py:func:`dynamic_config` decorator, see it for more.""" - failure_exception_types: Optional[Sequence[Type[BaseException]]] = None + failure_exception_types: Sequence[type[BaseException]] | None = None """The types of exceptions that, if a workflow-thrown exception extends, will cause the workflow/update to fail instead of suspending the workflow via task failure. These are applied in addition to ones set on the worker constructor. If ``Exception`` is set, it effectively will @@ -490,21 +492,21 @@ class Info: """ attempt: int - continued_run_id: Optional[str] - cron_schedule: Optional[str] - execution_timeout: Optional[timedelta] + continued_run_id: str | None + cron_schedule: str | None + execution_timeout: timedelta | None first_execution_run_id: str headers: Mapping[str, temporalio.api.common.v1.Payload] namespace: str - parent: Optional[ParentInfo] - root: Optional[RootInfo] + parent: ParentInfo | None + root: RootInfo | None priority: temporalio.common.Priority """The priority of this workflow execution. If not set, or this server predates priorities, then returns a default instance.""" raw_memo: Mapping[str, temporalio.api.common.v1.Payload] - retry_policy: Optional[temporalio.common.RetryPolicy] + retry_policy: temporalio.common.RetryPolicy | None run_id: str - run_timeout: Optional[timedelta] + run_timeout: timedelta | None search_attributes: temporalio.common.SearchAttributes """Search attributes for the workflow. @@ -560,7 +562,7 @@ def get_current_build_id(self) -> str: def get_current_deployment_version( self, - ) -> Optional[temporalio.common.WorkerDeploymentVersion]: + ) -> temporalio.common.WorkerDeploymentVersion | None: """Get the deployment version of the worker which executed the current Workflow Task. May be None if the task was completed by a worker without a deployment version or build @@ -647,7 +649,7 @@ def current() -> _Runtime: return loop @staticmethod - def maybe_current() -> Optional[_Runtime]: + def maybe_current() -> _Runtime | None: try: return getattr( asyncio.get_running_loop(), "__temporal_workflow_runtime", None @@ -656,9 +658,7 @@ def maybe_current() -> Optional[_Runtime]: return None @staticmethod - def set_on_loop( - loop: asyncio.AbstractEventLoop, runtime: Optional[_Runtime] - ) -> None: + def set_on_loop(loop: asyncio.AbstractEventLoop, runtime: _Runtime | None) -> None: if runtime: setattr(loop, "__temporal_workflow_runtime", runtime) elif hasattr(loop, "__temporal_workflow_runtime"): @@ -666,7 +666,7 @@ def set_on_loop( def __init__(self) -> None: super().__init__() - self._logger_details: Optional[Mapping[str, Any]] = None + self._logger_details: Mapping[str, Any] | None = None @property def logger_details(self) -> Mapping[str, Any]: @@ -681,19 +681,17 @@ def workflow_all_handlers_finished(self) -> bool: ... def workflow_continue_as_new( self, *args: Any, - workflow: Union[None, Callable, str], - task_queue: Optional[str], - run_timeout: Optional[timedelta], - task_timeout: Optional[timedelta], - retry_policy: Optional[temporalio.common.RetryPolicy], - memo: Optional[Mapping[str, Any]], - search_attributes: Optional[ - Union[ - temporalio.common.SearchAttributes, - temporalio.common.TypedSearchAttributes, - ] - ], - versioning_intent: Optional[VersioningIntent], + workflow: None | Callable | str, + task_queue: str | None, + run_timeout: timedelta | None, + task_timeout: timedelta | None, + retry_policy: temporalio.common.RetryPolicy | None, + memo: Mapping[str, Any] | None, + search_attributes: None + | ( + temporalio.common.SearchAttributes | temporalio.common.TypedSearchAttributes + ), + versioning_intent: VersioningIntent | None, ) -> NoReturn: ... @abstractmethod @@ -705,7 +703,7 @@ def workflow_get_current_build_id(self) -> str: ... @abstractmethod def workflow_get_current_deployment_version( self, - ) -> Optional[temporalio.common.WorkerDeploymentVersion]: ... + ) -> temporalio.common.WorkerDeploymentVersion | None: ... @abstractmethod def workflow_get_current_history_length(self) -> int: ... @@ -715,26 +713,20 @@ def workflow_get_current_history_size(self) -> int: ... @abstractmethod def workflow_get_external_workflow_handle( - self, id: str, *, run_id: Optional[str] + self, id: str, *, run_id: str | None ) -> ExternalWorkflowHandle[Any]: ... @abstractmethod - def workflow_get_query_handler(self, name: Optional[str]) -> Optional[Callable]: ... + def workflow_get_query_handler(self, name: str | None) -> Callable | None: ... @abstractmethod - def workflow_get_signal_handler( - self, name: Optional[str] - ) -> Optional[Callable]: ... + def workflow_get_signal_handler(self, name: str | None) -> Callable | None: ... @abstractmethod - def workflow_get_update_handler( - self, name: Optional[str] - ) -> Optional[Callable]: ... + def workflow_get_update_handler(self, name: str | None) -> Callable | None: ... @abstractmethod - def workflow_get_update_validator( - self, name: Optional[str] - ) -> Optional[Callable]: ... + def workflow_get_update_validator(self, name: str | None) -> Callable | None: ... @abstractmethod def workflow_info(self) -> Info: ... @@ -753,7 +745,7 @@ def workflow_memo(self) -> Mapping[str, Any]: ... @abstractmethod def workflow_memo_value( - self, key: str, default: Any, *, type_hint: Optional[Type] + self, key: str, default: Any, *, type_hint: type | None ) -> Any: ... @abstractmethod @@ -773,20 +765,20 @@ def workflow_random(self) -> Random: ... @abstractmethod def workflow_set_query_handler( - self, name: Optional[str], handler: Optional[Callable] + self, name: str | None, handler: Callable | None ) -> None: ... @abstractmethod def workflow_set_signal_handler( - self, name: Optional[str], handler: Optional[Callable] + self, name: str | None, handler: Callable | None ) -> None: ... @abstractmethod def workflow_set_update_handler( self, - name: Optional[str], - handler: Optional[Callable], - validator: Optional[Callable], + name: str | None, + handler: Callable | None, + validator: Callable | None, ) -> None: ... @abstractmethod @@ -794,17 +786,17 @@ def workflow_start_activity( self, activity: Any, *args: Any, - task_queue: Optional[str], - result_type: Optional[Type], - schedule_to_close_timeout: Optional[timedelta], - schedule_to_start_timeout: Optional[timedelta], - start_to_close_timeout: Optional[timedelta], - heartbeat_timeout: Optional[timedelta], - retry_policy: Optional[temporalio.common.RetryPolicy], + task_queue: str | None, + result_type: type | None, + schedule_to_close_timeout: timedelta | None, + schedule_to_start_timeout: timedelta | None, + start_to_close_timeout: timedelta | None, + heartbeat_timeout: timedelta | None, + retry_policy: temporalio.common.RetryPolicy | None, cancellation_type: ActivityCancellationType, - activity_id: Optional[str], - versioning_intent: Optional[VersioningIntent], - summary: Optional[str] = None, + activity_id: str | None, + versioning_intent: VersioningIntent | None, + summary: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> ActivityHandle[Any]: ... @@ -814,26 +806,24 @@ async def workflow_start_child_workflow( workflow: Any, *args: Any, id: str, - task_queue: Optional[str], - result_type: Optional[Type], + task_queue: str | None, + result_type: type | None, cancellation_type: ChildWorkflowCancellationType, parent_close_policy: ParentClosePolicy, - execution_timeout: Optional[timedelta], - run_timeout: Optional[timedelta], - task_timeout: Optional[timedelta], + execution_timeout: timedelta | None, + run_timeout: timedelta | None, + task_timeout: timedelta | None, id_reuse_policy: temporalio.common.WorkflowIDReusePolicy, - retry_policy: Optional[temporalio.common.RetryPolicy], + retry_policy: temporalio.common.RetryPolicy | None, cron_schedule: str, - memo: Optional[Mapping[str, Any]], - search_attributes: Optional[ - Union[ - temporalio.common.SearchAttributes, - temporalio.common.TypedSearchAttributes, - ] - ], - versioning_intent: Optional[VersioningIntent], - static_summary: Optional[str] = None, - static_details: Optional[str] = None, + memo: Mapping[str, Any] | None, + search_attributes: None + | ( + temporalio.common.SearchAttributes | temporalio.common.TypedSearchAttributes + ), + versioning_intent: VersioningIntent | None, + static_summary: str | None = None, + static_details: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> ChildWorkflowHandle[Any, Any]: ... @@ -842,15 +832,15 @@ def workflow_start_local_activity( self, activity: Any, *args: Any, - result_type: Optional[Type], - schedule_to_close_timeout: Optional[timedelta], - schedule_to_start_timeout: Optional[timedelta], - start_to_close_timeout: Optional[timedelta], - retry_policy: Optional[temporalio.common.RetryPolicy], - local_retry_threshold: Optional[timedelta], + result_type: type | None, + schedule_to_close_timeout: timedelta | None, + schedule_to_start_timeout: timedelta | None, + start_to_close_timeout: timedelta | None, + retry_policy: temporalio.common.RetryPolicy | None, + local_retry_threshold: timedelta | None, cancellation_type: ActivityCancellationType, - activity_id: Optional[str], - summary: Optional[str], + activity_id: str | None, + summary: str | None, ) -> ActivityHandle[Any]: ... @abstractmethod @@ -860,7 +850,7 @@ async def workflow_start_nexus_operation( service: str, operation: nexusrpc.Operation[InputT, OutputT] | str | Callable[..., Any], input: Any, - output_type: Type[OutputT] | None, + output_type: type[OutputT] | None, schedule_to_close_timeout: timedelta | None, cancellation_type: temporalio.workflow.NexusOperationCancellationType, headers: Mapping[str, str] | None, @@ -873,15 +863,15 @@ def workflow_time_ns(self) -> int: ... @abstractmethod def workflow_upsert_search_attributes( self, - attributes: Union[ - temporalio.common.SearchAttributes, - Sequence[temporalio.common.SearchAttributeUpdate], - ], + attributes: ( + temporalio.common.SearchAttributes + | Sequence[temporalio.common.SearchAttributeUpdate] + ), ) -> None: ... @abstractmethod async def workflow_sleep( - self, duration: float, *, summary: Optional[str] = None + self, duration: float, *, summary: str | None = None ) -> None: ... @abstractmethod @@ -889,8 +879,8 @@ async def workflow_wait_condition( self, fn: Callable[[], bool], *, - timeout: Optional[float] = None, - timeout_summary: Optional[str] = None, + timeout: float | None = None, + timeout_summary: str | None = None, ) -> None: ... @abstractmethod @@ -906,12 +896,10 @@ def workflow_is_failure_exception(self, err: BaseException) -> bool: ... def workflow_has_last_completion_result(self) -> bool: ... @abstractmethod - def workflow_last_completion_result( - self, type_hint: Optional[Type] - ) -> Optional[Any]: ... + def workflow_last_completion_result(self, type_hint: type | None) -> Any | None: ... @abstractmethod - def workflow_last_failure(self) -> Optional[BaseException]: ... + def workflow_last_failure(self) -> BaseException | None: ... _current_update_info: contextvars.ContextVar[UpdateInfo] = contextvars.ContextVar( @@ -923,7 +911,7 @@ def _set_current_update_info(info: UpdateInfo) -> None: _current_update_info.set(info) -def current_update_info() -> Optional[UpdateInfo]: +def current_update_info() -> UpdateInfo | None: """Info for the current update if any. This is powered by :py:mod:`contextvars` so it is only valid within the @@ -1011,20 +999,20 @@ def memo_value(key: str, default: Any = temporalio.common._arg_unset) -> Any: .. @overload -def memo_value(key: str, *, type_hint: Type[ParamType]) -> ParamType: ... +def memo_value(key: str, *, type_hint: type[ParamType]) -> ParamType: ... @overload def memo_value( - key: str, default: AnyType, *, type_hint: Type[ParamType] -) -> Union[AnyType, ParamType]: ... + key: str, default: AnyType, *, type_hint: type[ParamType] +) -> AnyType | ParamType: ... def memo_value( key: str, default: Any = temporalio.common._arg_unset, *, - type_hint: Optional[Type] = None, + type_hint: type | None = None, ) -> Any: """Memo value for the given key, optional default, and optional type hint. @@ -1070,14 +1058,14 @@ def has_last_completion_result() -> bool: @overload -def get_last_completion_result() -> Optional[Any]: ... +def get_last_completion_result() -> Any | None: ... @overload -def get_last_completion_result(type_hint: Type[ParamType]) -> Optional[ParamType]: ... +def get_last_completion_result(type_hint: type[ParamType]) -> ParamType | None: ... -def get_last_completion_result(type_hint: Optional[Type] = None) -> Optional[Any]: +def get_last_completion_result(type_hint: type | None = None) -> Any | None: """Get the result of the last run of the workflow. This will be None if there was no previous completion or the result was None. has_last_completion_result() can be used to differentiate. @@ -1085,7 +1073,7 @@ def get_last_completion_result(type_hint: Optional[Type] = None) -> Optional[Any return _Runtime.current().workflow_last_completion_result(type_hint) -def get_last_failure() -> Optional[BaseException]: +def get_last_failure() -> BaseException | None: """Get the last failure of the workflow if it has run previously.""" return _Runtime.current().workflow_last_failure() @@ -1190,10 +1178,10 @@ def time_ns() -> int: def upsert_search_attributes( - attributes: Union[ - temporalio.common.SearchAttributes, - Sequence[temporalio.common.SearchAttributeUpdate], - ], + attributes: ( + temporalio.common.SearchAttributes + | Sequence[temporalio.common.SearchAttributeUpdate] + ), ) -> None: """Upsert search attributes for this workflow. @@ -1219,7 +1207,7 @@ class UpdateMethodMultiParam(Protocol[MultiParamSpec, ProtocolReturnType]): def __call__( self, *args: MultiParamSpec.args, **kwargs: MultiParamSpec.kwargs - ) -> Union[ProtocolReturnType, Awaitable[ProtocolReturnType]]: + ) -> ProtocolReturnType | Awaitable[ProtocolReturnType]: """Generic callable type callback.""" ... @@ -1246,7 +1234,7 @@ def update( def update( *, unfinished_policy: HandlerUnfinishedPolicy = HandlerUnfinishedPolicy.WARN_AND_ABANDON, - description: Optional[str] = None, + description: str | None = None, ) -> Callable[ [Callable[MultiParamSpec, ReturnType]], UpdateMethodMultiParam[MultiParamSpec, ReturnType], @@ -1258,7 +1246,7 @@ def update( *, name: str, unfinished_policy: HandlerUnfinishedPolicy = HandlerUnfinishedPolicy.WARN_AND_ABANDON, - description: Optional[str] = None, + description: str | None = None, ) -> Callable[ [Callable[MultiParamSpec, ReturnType]], UpdateMethodMultiParam[MultiParamSpec, ReturnType], @@ -1270,7 +1258,7 @@ def update( *, dynamic: Literal[True], unfinished_policy: HandlerUnfinishedPolicy = HandlerUnfinishedPolicy.WARN_AND_ABANDON, - description: Optional[str] = None, + description: str | None = None, ) -> Callable[ [Callable[MultiParamSpec, ReturnType]], UpdateMethodMultiParam[MultiParamSpec, ReturnType], @@ -1278,12 +1266,12 @@ def update( def update( - fn: Optional[CallableSyncOrAsyncType] = None, + fn: CallableSyncOrAsyncType | None = None, *, - name: Optional[str] = None, - dynamic: Optional[bool] = False, + name: str | None = None, + dynamic: bool | None = False, unfinished_policy: HandlerUnfinishedPolicy = HandlerUnfinishedPolicy.WARN_AND_ABANDON, - description: Optional[str] = None, + description: str | None = None, ): """Decorator for a workflow update handler method. @@ -1314,7 +1302,7 @@ def update( """ def decorator( - name: Optional[str], + name: str | None, unfinished_policy: HandlerUnfinishedPolicy, fn: CallableSyncOrAsyncType, ) -> CallableSyncOrAsyncType: @@ -1344,8 +1332,8 @@ def decorator( def _update_validator( - update_def: _UpdateDefinition, fn: Optional[Callable[..., None]] = None -) -> Optional[Callable[..., None]]: + update_def: _UpdateDefinition, fn: Callable[..., None] | None = None +) -> Callable[..., None] | None: """Decorator for a workflow update validator method.""" if fn is not None: update_def.set_validator(fn) @@ -1364,9 +1352,7 @@ def uuid4() -> uuid.UUID: return uuid.UUID(bytes=random().getrandbits(16 * 8).to_bytes(16, "big"), version=4) -async def sleep( - duration: Union[float, timedelta], *, summary: Optional[str] = None -) -> None: +async def sleep(duration: float | timedelta, *, summary: str | None = None) -> None: """Sleep for the given duration. Args: @@ -1385,8 +1371,8 @@ async def sleep( async def wait_condition( fn: Callable[[], bool], *, - timeout: Optional[Union[timedelta, float]] = None, - timeout_summary: Optional[str] = None, + timeout: timedelta | float | None = None, + timeout_summary: str | None = None, ) -> None: """Wait on a callback to become true. @@ -1515,7 +1501,7 @@ def imports_passed_through() -> Iterator[None]: @staticmethod def current_import_notification_policy_override() -> ( - Optional[SandboxImportNotificationPolicy] + SandboxImportNotificationPolicy | None ): """Gets the current import notification policy override if one is set.""" applied_policy = getattr( @@ -1566,9 +1552,7 @@ class LoggerAdapter(logging.LoggerAdapter): behavior is that of ``merge_extra=True`` in Python >= 3.13. """ - def __init__( - self, logger: logging.Logger, extra: Optional[Mapping[str, Any]] - ) -> None: + def __init__(self, logger: logging.Logger, extra: Mapping[str, Any] | None) -> None: """Create the logger adapter.""" super().__init__(logger, extra or {}) self.workflow_info_on_message = True @@ -1578,10 +1562,10 @@ def __init__( def process( self, msg: Any, kwargs: MutableMapping[str, Any] - ) -> Tuple[Any, MutableMapping[str, Any]]: + ) -> tuple[Any, MutableMapping[str, Any]]: """Override to add workflow details.""" - extra: Dict[str, Any] = {} - msg_extra: Dict[str, Any] = {} + extra: dict[str, Any] = {} + msg_extra: dict[str, Any] = {} if ( self.workflow_info_on_message @@ -1633,22 +1617,22 @@ def base_logger(self) -> logging.Logger: @dataclass(frozen=True) class _Definition: - name: Optional[str] - cls: Type + name: str | None + cls: type run_fn: Callable[..., Awaitable] - signals: Mapping[Optional[str], _SignalDefinition] - queries: Mapping[Optional[str], _QueryDefinition] - updates: Mapping[Optional[str], _UpdateDefinition] + signals: Mapping[str | None, _SignalDefinition] + queries: Mapping[str | None, _QueryDefinition] + updates: Mapping[str | None, _UpdateDefinition] sandboxed: bool - failure_exception_types: Sequence[Type[BaseException]] + failure_exception_types: Sequence[type[BaseException]] # Types loaded on post init if both are None - arg_types: Optional[List[Type]] = None - ret_type: Optional[Type] = None - versioning_behavior: Optional[temporalio.common.VersioningBehavior] = None - dynamic_config_fn: Optional[Callable[..., DynamicWorkflowConfig]] = None + arg_types: list[type] | None = None + ret_type: type | None = None + versioning_behavior: temporalio.common.VersioningBehavior | None = None + dynamic_config_fn: Callable[..., DynamicWorkflowConfig] | None = None @staticmethod - def from_class(cls: Type) -> Optional[_Definition]: + def from_class(cls: type) -> _Definition | None: # We make sure to only return it if it's on _this_ class defn = getattr(cls, "__temporal_workflow_definition", None) if defn and defn.cls == cls: @@ -1656,7 +1640,7 @@ def from_class(cls: Type) -> Optional[_Definition]: return None @staticmethod - def must_from_class(cls: Type) -> _Definition: + def must_from_class(cls: type) -> _Definition: ret = _Definition.from_class(cls) if ret: return ret @@ -1666,7 +1650,7 @@ def must_from_class(cls: Type) -> _Definition: ) @staticmethod - def from_run_fn(fn: Callable[..., Awaitable[Any]]) -> Optional[_Definition]: + def from_run_fn(fn: Callable[..., Awaitable[Any]]) -> _Definition | None: return getattr(fn, "__temporal_workflow_definition", None) @staticmethod @@ -1681,8 +1665,8 @@ def must_from_run_fn(fn: Callable[..., Awaitable[Any]]) -> _Definition: @classmethod def get_name_and_result_type( - cls, name_or_run_fn: Union[str, Callable[..., Awaitable[Any]]] - ) -> Tuple[str, Optional[Type]]: + cls, name_or_run_fn: str | Callable[..., Awaitable[Any]] + ) -> tuple[str, type | None]: if isinstance(name_or_run_fn, str): return name_or_run_fn, None elif callable(name_or_run_fn): @@ -1695,26 +1679,26 @@ def get_name_and_result_type( @staticmethod def _apply_to_class( - cls: Type, + cls: type, *, - workflow_name: Optional[str], + workflow_name: str | None, sandboxed: bool, - failure_exception_types: Sequence[Type[BaseException]], + failure_exception_types: Sequence[type[BaseException]], versioning_behavior: temporalio.common.VersioningBehavior, ) -> None: # Check it's not being doubly applied if _Definition.from_class(cls): raise ValueError("Class already contains workflow definition") - issues: List[str] = [] + issues: list[str] = [] # Collect run fn and all signal/query/update fns - init_fn: Optional[Callable[..., None]] = None - run_fn: Optional[Callable[..., Awaitable[Any]]] = None - dynamic_config_fn: Optional[Callable[..., DynamicWorkflowConfig]] = None + init_fn: Callable[..., None] | None = None + run_fn: Callable[..., Awaitable[Any]] | None = None + dynamic_config_fn: Callable[..., DynamicWorkflowConfig] | None = None seen_run_attr = False - signals: Dict[Optional[str], _SignalDefinition] = {} - queries: Dict[Optional[str], _QueryDefinition] = {} - updates: Dict[Optional[str], _UpdateDefinition] = {} + signals: dict[str | None, _SignalDefinition] = {} + queries: dict[str | None, _QueryDefinition] = {} + updates: dict[str | None, _UpdateDefinition] = {} for name, member in inspect.getmembers(cls): if hasattr(member, "__temporal_workflow_run"): seen_run_attr = True @@ -1877,7 +1861,7 @@ def __post_init__(self) -> None: def _parameters_identical_up_to_naming(fn1: Callable, fn2: Callable) -> bool: """Return True if the functions have identical parameter lists, ignoring parameter names.""" - def params(fn: Callable) -> List[inspect.Parameter]: + def params(fn: Callable) -> list[inspect.Parameter]: # Ignore name when comparing parameters (remaining fields are kind, # default, and annotation). return [p.replace(name="x") for p in inspect.signature(fn).parameters.values()] @@ -1905,7 +1889,7 @@ async def with_object(*args, **kwargs) -> Any: # Returns true if normal form, false if vararg form def _assert_dynamic_handler_args( - fn: Callable, arg_types: Optional[List[Type]], is_method: bool + fn: Callable, arg_types: list[type] | None, is_method: bool ) -> bool: # Dynamic query/signal/update must have three args: self, name, and # Sequence[RawValue]. An older form accepted varargs for the third param for signals/queries so @@ -1934,23 +1918,23 @@ def _assert_dynamic_handler_args( @dataclass(frozen=True) class _SignalDefinition: # None if dynamic - name: Optional[str] - fn: Callable[..., Union[None, Awaitable[None]]] + name: str | None + fn: Callable[..., None | Awaitable[None]] is_method: bool unfinished_policy: HandlerUnfinishedPolicy = ( HandlerUnfinishedPolicy.WARN_AND_ABANDON ) - description: Optional[str] = None + description: str | None = None # Types loaded on post init if None - arg_types: Optional[List[Type]] = None + arg_types: list[type] | None = None dynamic_vararg: bool = False @staticmethod - def from_fn(fn: Callable) -> Optional[_SignalDefinition]: + def from_fn(fn: Callable) -> _SignalDefinition | None: return getattr(fn, "__temporal_signal_definition", None) @staticmethod - def must_name_from_fn_or_str(signal: Union[str, Callable]) -> str: + def must_name_from_fn_or_str(signal: str | Callable) -> str: if callable(signal): defn = _SignalDefinition.from_fn(signal) if not defn: @@ -1985,17 +1969,17 @@ def bind_fn(self, obj: Any) -> Callable[..., Any]: @dataclass(frozen=True) class _QueryDefinition: # None if dynamic - name: Optional[str] + name: str | None fn: Callable[..., Any] is_method: bool - description: Optional[str] = None + description: str | None = None # Types loaded on post init if both are None - arg_types: Optional[List[Type]] = None - ret_type: Optional[Type] = None + arg_types: list[type] | None = None + ret_type: type | None = None dynamic_vararg: bool = False @staticmethod - def from_fn(fn: Callable) -> Optional[_QueryDefinition]: + def from_fn(fn: Callable) -> _QueryDefinition | None: return getattr(fn, "__temporal_query_definition", None) def __post_init__(self) -> None: @@ -2020,17 +2004,17 @@ def bind_fn(self, obj: Any) -> Callable[..., Any]: @dataclass(frozen=True) class _UpdateDefinition: # None if dynamic - name: Optional[str] - fn: Callable[..., Union[Any, Awaitable[Any]]] + name: str | None + fn: Callable[..., Any | Awaitable[Any]] is_method: bool unfinished_policy: HandlerUnfinishedPolicy = ( HandlerUnfinishedPolicy.WARN_AND_ABANDON ) - description: Optional[str] = None + description: str | None = None # Types loaded on post init if None - arg_types: Optional[List[Type]] = None - ret_type: Optional[Type] = None - validator: Optional[Callable[..., None]] = None + arg_types: list[type] | None = None + ret_type: type | None = None + validator: Callable[..., None] | None = None dynamic_vararg: bool = False def __post_init__(self) -> None: @@ -2062,8 +2046,8 @@ def set_validator(self, validator: Callable[..., None]) -> None: @classmethod def get_name_and_result_type( cls, - name_or_update_fn: Union[str, Callable[..., Any]], - ) -> Tuple[str, Optional[Type]]: + name_or_update_fn: str | Callable[..., Any], + ) -> tuple[str, type | None]: if isinstance(name_or_update_fn, temporalio.workflow.UpdateMethodMultiParam): defn = name_or_update_fn._defn if not defn.name: @@ -2115,16 +2099,16 @@ class ActivityConfig(TypedDict, total=False): :py:func:`execute_activity`. """ - task_queue: Optional[str] - schedule_to_close_timeout: Optional[timedelta] - schedule_to_start_timeout: Optional[timedelta] - start_to_close_timeout: Optional[timedelta] - heartbeat_timeout: Optional[timedelta] - retry_policy: Optional[temporalio.common.RetryPolicy] + task_queue: str | None + schedule_to_close_timeout: timedelta | None + schedule_to_start_timeout: timedelta | None + start_to_close_timeout: timedelta | None + heartbeat_timeout: timedelta | None + retry_policy: temporalio.common.RetryPolicy | None cancellation_type: ActivityCancellationType - activity_id: Optional[str] - versioning_intent: Optional[VersioningIntent] - summary: Optional[str] + activity_id: str | None + versioning_intent: VersioningIntent | None + summary: str | None priority: temporalio.common.Priority @@ -2133,16 +2117,16 @@ class ActivityConfig(TypedDict, total=False): def start_activity( activity: CallableAsyncNoParam[ReturnType], *, - task_queue: Optional[str] = None, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - heartbeat_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + task_queue: str | None = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + heartbeat_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - versioning_intent: Optional[VersioningIntent] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + versioning_intent: VersioningIntent | None = None, + summary: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> ActivityHandle[ReturnType]: ... @@ -2152,16 +2136,16 @@ def start_activity( def start_activity( activity: CallableSyncNoParam[ReturnType], *, - task_queue: Optional[str] = None, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - heartbeat_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + task_queue: str | None = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + heartbeat_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - versioning_intent: Optional[VersioningIntent] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + versioning_intent: VersioningIntent | None = None, + summary: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> ActivityHandle[ReturnType]: ... @@ -2172,16 +2156,16 @@ def start_activity( activity: CallableAsyncSingleParam[ParamType, ReturnType], arg: ParamType, *, - task_queue: Optional[str] = None, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - heartbeat_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + task_queue: str | None = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + heartbeat_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - versioning_intent: Optional[VersioningIntent] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + versioning_intent: VersioningIntent | None = None, + summary: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> ActivityHandle[ReturnType]: ... @@ -2192,16 +2176,16 @@ def start_activity( activity: CallableSyncSingleParam[ParamType, ReturnType], arg: ParamType, *, - task_queue: Optional[str] = None, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - heartbeat_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + task_queue: str | None = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + heartbeat_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - versioning_intent: Optional[VersioningIntent] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + versioning_intent: VersioningIntent | None = None, + summary: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> ActivityHandle[ReturnType]: ... @@ -2212,16 +2196,16 @@ def start_activity( activity: Callable[..., Awaitable[ReturnType]], *, args: Sequence[Any], - task_queue: Optional[str] = None, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - heartbeat_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + task_queue: str | None = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + heartbeat_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - versioning_intent: Optional[VersioningIntent] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + versioning_intent: VersioningIntent | None = None, + summary: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> ActivityHandle[ReturnType]: ... @@ -2232,16 +2216,16 @@ def start_activity( activity: Callable[..., ReturnType], *, args: Sequence[Any], - task_queue: Optional[str] = None, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - heartbeat_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + task_queue: str | None = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + heartbeat_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - versioning_intent: Optional[VersioningIntent] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + versioning_intent: VersioningIntent | None = None, + summary: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> ActivityHandle[ReturnType]: ... @@ -2253,17 +2237,17 @@ def start_activity( arg: Any = temporalio.common._arg_unset, *, args: Sequence[Any] = [], - task_queue: Optional[str] = None, - result_type: Optional[type] = None, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - heartbeat_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + task_queue: str | None = None, + result_type: type | None = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + heartbeat_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - versioning_intent: Optional[VersioningIntent] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + versioning_intent: VersioningIntent | None = None, + summary: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> ActivityHandle[Any]: ... @@ -2273,17 +2257,17 @@ def start_activity( arg: Any = temporalio.common._arg_unset, *, args: Sequence[Any] = [], - task_queue: Optional[str] = None, - result_type: Optional[type] = None, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - heartbeat_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + task_queue: str | None = None, + result_type: type | None = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + heartbeat_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - versioning_intent: Optional[VersioningIntent] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + versioning_intent: VersioningIntent | None = None, + summary: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> ActivityHandle[Any]: """Start an activity and return its handle. @@ -2349,16 +2333,16 @@ def start_activity( async def execute_activity( activity: CallableAsyncNoParam[ReturnType], *, - task_queue: Optional[str] = None, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - heartbeat_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + task_queue: str | None = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + heartbeat_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - versioning_intent: Optional[VersioningIntent] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + versioning_intent: VersioningIntent | None = None, + summary: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> ReturnType: ... @@ -2368,16 +2352,16 @@ async def execute_activity( async def execute_activity( activity: CallableSyncNoParam[ReturnType], *, - task_queue: Optional[str] = None, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - heartbeat_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + task_queue: str | None = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + heartbeat_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - versioning_intent: Optional[VersioningIntent] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + versioning_intent: VersioningIntent | None = None, + summary: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> ReturnType: ... @@ -2388,16 +2372,16 @@ async def execute_activity( activity: CallableAsyncSingleParam[ParamType, ReturnType], arg: ParamType, *, - task_queue: Optional[str] = None, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - heartbeat_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + task_queue: str | None = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + heartbeat_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - versioning_intent: Optional[VersioningIntent] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + versioning_intent: VersioningIntent | None = None, + summary: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> ReturnType: ... @@ -2408,16 +2392,16 @@ async def execute_activity( activity: CallableSyncSingleParam[ParamType, ReturnType], arg: ParamType, *, - task_queue: Optional[str] = None, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - heartbeat_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + task_queue: str | None = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + heartbeat_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - versioning_intent: Optional[VersioningIntent] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + versioning_intent: VersioningIntent | None = None, + summary: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> ReturnType: ... @@ -2428,16 +2412,16 @@ async def execute_activity( activity: Callable[..., Awaitable[ReturnType]], *, args: Sequence[Any], - task_queue: Optional[str] = None, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - heartbeat_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + task_queue: str | None = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + heartbeat_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - versioning_intent: Optional[VersioningIntent] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + versioning_intent: VersioningIntent | None = None, + summary: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> ReturnType: ... @@ -2448,16 +2432,16 @@ async def execute_activity( activity: Callable[..., ReturnType], *, args: Sequence[Any], - task_queue: Optional[str] = None, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - heartbeat_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + task_queue: str | None = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + heartbeat_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - versioning_intent: Optional[VersioningIntent] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + versioning_intent: VersioningIntent | None = None, + summary: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> ReturnType: ... @@ -2469,17 +2453,17 @@ async def execute_activity( arg: Any = temporalio.common._arg_unset, *, args: Sequence[Any] = [], - task_queue: Optional[str] = None, - result_type: Optional[type] = None, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - heartbeat_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + task_queue: str | None = None, + result_type: type | None = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + heartbeat_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - versioning_intent: Optional[VersioningIntent] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + versioning_intent: VersioningIntent | None = None, + summary: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> Any: ... @@ -2489,17 +2473,17 @@ async def execute_activity( arg: Any = temporalio.common._arg_unset, *, args: Sequence[Any] = [], - task_queue: Optional[str] = None, - result_type: Optional[type] = None, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - heartbeat_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + task_queue: str | None = None, + result_type: type | None = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + heartbeat_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - versioning_intent: Optional[VersioningIntent] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + versioning_intent: VersioningIntent | None = None, + summary: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> Any: """Start an activity and wait for completion. @@ -2529,18 +2513,18 @@ async def execute_activity( # Overload for async no-param activity @overload def start_activity_class( - activity: Type[CallableAsyncNoParam[ReturnType]], + activity: type[CallableAsyncNoParam[ReturnType]], *, - task_queue: Optional[str] = None, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - heartbeat_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + task_queue: str | None = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + heartbeat_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - versioning_intent: Optional[VersioningIntent] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + versioning_intent: VersioningIntent | None = None, + summary: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> ActivityHandle[ReturnType]: ... @@ -2548,18 +2532,18 @@ def start_activity_class( # Overload for sync no-param activity @overload def start_activity_class( - activity: Type[CallableSyncNoParam[ReturnType]], + activity: type[CallableSyncNoParam[ReturnType]], *, - task_queue: Optional[str] = None, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - heartbeat_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + task_queue: str | None = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + heartbeat_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - versioning_intent: Optional[VersioningIntent] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + versioning_intent: VersioningIntent | None = None, + summary: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> ActivityHandle[ReturnType]: ... @@ -2567,19 +2551,19 @@ def start_activity_class( # Overload for async single-param activity @overload def start_activity_class( - activity: Type[CallableAsyncSingleParam[ParamType, ReturnType]], + activity: type[CallableAsyncSingleParam[ParamType, ReturnType]], arg: ParamType, *, - task_queue: Optional[str] = None, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - heartbeat_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + task_queue: str | None = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + heartbeat_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - versioning_intent: Optional[VersioningIntent] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + versioning_intent: VersioningIntent | None = None, + summary: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> ActivityHandle[ReturnType]: ... @@ -2587,19 +2571,19 @@ def start_activity_class( # Overload for sync single-param activity @overload def start_activity_class( - activity: Type[CallableSyncSingleParam[ParamType, ReturnType]], + activity: type[CallableSyncSingleParam[ParamType, ReturnType]], arg: ParamType, *, - task_queue: Optional[str] = None, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - heartbeat_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + task_queue: str | None = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + heartbeat_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - versioning_intent: Optional[VersioningIntent] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + versioning_intent: VersioningIntent | None = None, + summary: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> ActivityHandle[ReturnType]: ... @@ -2607,19 +2591,19 @@ def start_activity_class( # Overload for async multi-param activity @overload def start_activity_class( - activity: Type[Callable[..., Awaitable[ReturnType]]], + activity: type[Callable[..., Awaitable[ReturnType]]], *, args: Sequence[Any], - task_queue: Optional[str] = None, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - heartbeat_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + task_queue: str | None = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + heartbeat_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - versioning_intent: Optional[VersioningIntent] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + versioning_intent: VersioningIntent | None = None, + summary: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> ActivityHandle[ReturnType]: ... @@ -2627,38 +2611,38 @@ def start_activity_class( # Overload for sync multi-param activity @overload def start_activity_class( - activity: Type[Callable[..., ReturnType]], + activity: type[Callable[..., ReturnType]], *, args: Sequence[Any], - task_queue: Optional[str] = None, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - heartbeat_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + task_queue: str | None = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + heartbeat_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - versioning_intent: Optional[VersioningIntent] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + versioning_intent: VersioningIntent | None = None, + summary: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> ActivityHandle[ReturnType]: ... def start_activity_class( - activity: Type[Callable], + activity: type[Callable], arg: Any = temporalio.common._arg_unset, *, args: Sequence[Any] = [], - task_queue: Optional[str] = None, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - heartbeat_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + task_queue: str | None = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + heartbeat_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - versioning_intent: Optional[VersioningIntent] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + versioning_intent: VersioningIntent | None = None, + summary: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> ActivityHandle[Any]: """Start an activity from a callable class. @@ -2686,18 +2670,18 @@ def start_activity_class( # Overload for async no-param activity @overload async def execute_activity_class( - activity: Type[CallableAsyncNoParam[ReturnType]], + activity: type[CallableAsyncNoParam[ReturnType]], *, - task_queue: Optional[str] = None, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - heartbeat_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + task_queue: str | None = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + heartbeat_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - versioning_intent: Optional[VersioningIntent] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + versioning_intent: VersioningIntent | None = None, + summary: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> ReturnType: ... @@ -2705,18 +2689,18 @@ async def execute_activity_class( # Overload for sync no-param activity @overload async def execute_activity_class( - activity: Type[CallableSyncNoParam[ReturnType]], + activity: type[CallableSyncNoParam[ReturnType]], *, - task_queue: Optional[str] = None, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - heartbeat_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + task_queue: str | None = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + heartbeat_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - versioning_intent: Optional[VersioningIntent] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + versioning_intent: VersioningIntent | None = None, + summary: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> ReturnType: ... @@ -2724,19 +2708,19 @@ async def execute_activity_class( # Overload for async single-param activity @overload async def execute_activity_class( - activity: Type[CallableAsyncSingleParam[ParamType, ReturnType]], + activity: type[CallableAsyncSingleParam[ParamType, ReturnType]], arg: ParamType, *, - task_queue: Optional[str] = None, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - heartbeat_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + task_queue: str | None = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + heartbeat_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - versioning_intent: Optional[VersioningIntent] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + versioning_intent: VersioningIntent | None = None, + summary: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> ReturnType: ... @@ -2744,19 +2728,19 @@ async def execute_activity_class( # Overload for sync single-param activity @overload async def execute_activity_class( - activity: Type[CallableSyncSingleParam[ParamType, ReturnType]], + activity: type[CallableSyncSingleParam[ParamType, ReturnType]], arg: ParamType, *, - task_queue: Optional[str] = None, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - heartbeat_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + task_queue: str | None = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + heartbeat_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - versioning_intent: Optional[VersioningIntent] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + versioning_intent: VersioningIntent | None = None, + summary: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> ReturnType: ... @@ -2764,19 +2748,19 @@ async def execute_activity_class( # Overload for async multi-param activity @overload async def execute_activity_class( - activity: Type[Callable[..., Awaitable[ReturnType]]], + activity: type[Callable[..., Awaitable[ReturnType]]], *, args: Sequence[Any], - task_queue: Optional[str] = None, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - heartbeat_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + task_queue: str | None = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + heartbeat_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - versioning_intent: Optional[VersioningIntent] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + versioning_intent: VersioningIntent | None = None, + summary: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> ReturnType: ... @@ -2784,38 +2768,38 @@ async def execute_activity_class( # Overload for sync multi-param activity @overload async def execute_activity_class( - activity: Type[Callable[..., ReturnType]], + activity: type[Callable[..., ReturnType]], *, args: Sequence[Any], - task_queue: Optional[str] = None, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - heartbeat_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + task_queue: str | None = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + heartbeat_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - versioning_intent: Optional[VersioningIntent] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + versioning_intent: VersioningIntent | None = None, + summary: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> ReturnType: ... async def execute_activity_class( - activity: Type[Callable], + activity: type[Callable], arg: Any = temporalio.common._arg_unset, *, args: Sequence[Any] = [], - task_queue: Optional[str] = None, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - heartbeat_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + task_queue: str | None = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + heartbeat_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - versioning_intent: Optional[VersioningIntent] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + versioning_intent: VersioningIntent | None = None, + summary: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> Any: """Start an activity from a callable class and wait for completion. @@ -2845,16 +2829,16 @@ async def execute_activity_class( def start_activity_method( activity: MethodAsyncNoParam[SelfType, ReturnType], *, - task_queue: Optional[str] = None, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - heartbeat_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + task_queue: str | None = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + heartbeat_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - versioning_intent: Optional[VersioningIntent] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + versioning_intent: VersioningIntent | None = None, + summary: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> ActivityHandle[ReturnType]: ... @@ -2864,16 +2848,16 @@ def start_activity_method( def start_activity_method( activity: MethodSyncNoParam[SelfType, ReturnType], *, - task_queue: Optional[str] = None, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - heartbeat_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + task_queue: str | None = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + heartbeat_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - versioning_intent: Optional[VersioningIntent] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + versioning_intent: VersioningIntent | None = None, + summary: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> ActivityHandle[ReturnType]: ... @@ -2884,16 +2868,16 @@ def start_activity_method( activity: MethodAsyncSingleParam[SelfType, ParamType, ReturnType], arg: ParamType, *, - task_queue: Optional[str] = None, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - heartbeat_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + task_queue: str | None = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + heartbeat_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - versioning_intent: Optional[VersioningIntent] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + versioning_intent: VersioningIntent | None = None, + summary: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> ActivityHandle[ReturnType]: ... @@ -2904,16 +2888,16 @@ def start_activity_method( activity: MethodSyncSingleParam[SelfType, ParamType, ReturnType], arg: ParamType, *, - task_queue: Optional[str] = None, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - heartbeat_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + task_queue: str | None = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + heartbeat_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - versioning_intent: Optional[VersioningIntent] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + versioning_intent: VersioningIntent | None = None, + summary: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> ActivityHandle[ReturnType]: ... @@ -2924,16 +2908,16 @@ def start_activity_method( activity: Callable[Concatenate[SelfType, MultiParamSpec], Awaitable[ReturnType]], *, args: Sequence[Any], - task_queue: Optional[str] = None, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - heartbeat_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + task_queue: str | None = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + heartbeat_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - versioning_intent: Optional[VersioningIntent] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + versioning_intent: VersioningIntent | None = None, + summary: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> ActivityHandle[ReturnType]: ... @@ -2944,16 +2928,16 @@ def start_activity_method( activity: Callable[Concatenate[SelfType, MultiParamSpec], ReturnType], *, args: Sequence[Any], - task_queue: Optional[str] = None, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - heartbeat_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + task_queue: str | None = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + heartbeat_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - versioning_intent: Optional[VersioningIntent] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + versioning_intent: VersioningIntent | None = None, + summary: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> ActivityHandle[ReturnType]: ... @@ -2963,16 +2947,16 @@ def start_activity_method( arg: Any = temporalio.common._arg_unset, *, args: Sequence[Any] = [], - task_queue: Optional[str] = None, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - heartbeat_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + task_queue: str | None = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + heartbeat_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - versioning_intent: Optional[VersioningIntent] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + versioning_intent: VersioningIntent | None = None, + summary: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> ActivityHandle[Any]: """Start an activity from a method. @@ -3002,16 +2986,16 @@ def start_activity_method( async def execute_activity_method( activity: MethodAsyncNoParam[SelfType, ReturnType], *, - task_queue: Optional[str] = None, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - heartbeat_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + task_queue: str | None = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + heartbeat_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - versioning_intent: Optional[VersioningIntent] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + versioning_intent: VersioningIntent | None = None, + summary: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> ReturnType: ... @@ -3021,16 +3005,16 @@ async def execute_activity_method( async def execute_activity_method( activity: MethodSyncNoParam[SelfType, ReturnType], *, - task_queue: Optional[str] = None, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - heartbeat_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + task_queue: str | None = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + heartbeat_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - versioning_intent: Optional[VersioningIntent] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + versioning_intent: VersioningIntent | None = None, + summary: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> ReturnType: ... @@ -3041,16 +3025,16 @@ async def execute_activity_method( activity: MethodAsyncSingleParam[SelfType, ParamType, ReturnType], arg: ParamType, *, - task_queue: Optional[str] = None, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - heartbeat_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + task_queue: str | None = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + heartbeat_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - versioning_intent: Optional[VersioningIntent] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + versioning_intent: VersioningIntent | None = None, + summary: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> ReturnType: ... @@ -3061,16 +3045,16 @@ async def execute_activity_method( activity: MethodSyncSingleParam[SelfType, ParamType, ReturnType], arg: ParamType, *, - task_queue: Optional[str] = None, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - heartbeat_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + task_queue: str | None = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + heartbeat_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - versioning_intent: Optional[VersioningIntent] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + versioning_intent: VersioningIntent | None = None, + summary: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> ReturnType: ... @@ -3081,16 +3065,16 @@ async def execute_activity_method( activity: Callable[Concatenate[SelfType, MultiParamSpec], Awaitable[ReturnType]], *, args: Sequence[Any], - task_queue: Optional[str] = None, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - heartbeat_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + task_queue: str | None = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + heartbeat_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - versioning_intent: Optional[VersioningIntent] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + versioning_intent: VersioningIntent | None = None, + summary: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> ReturnType: ... @@ -3101,16 +3085,16 @@ async def execute_activity_method( activity: Callable[Concatenate[SelfType, MultiParamSpec], ReturnType], *, args: Sequence[Any], - task_queue: Optional[str] = None, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - heartbeat_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + task_queue: str | None = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + heartbeat_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - versioning_intent: Optional[VersioningIntent] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + versioning_intent: VersioningIntent | None = None, + summary: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> ReturnType: ... @@ -3120,16 +3104,16 @@ async def execute_activity_method( arg: Any = temporalio.common._arg_unset, *, args: Sequence[Any] = [], - task_queue: Optional[str] = None, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - heartbeat_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + task_queue: str | None = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + heartbeat_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - versioning_intent: Optional[VersioningIntent] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + versioning_intent: VersioningIntent | None = None, + summary: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> Any: """Start an activity from a method and wait for completion. @@ -3161,14 +3145,14 @@ class LocalActivityConfig(TypedDict, total=False): and :py:func:`execute_local_activity`. """ - schedule_to_close_timeout: Optional[timedelta] - schedule_to_start_timeout: Optional[timedelta] - start_to_close_timeout: Optional[timedelta] - retry_policy: Optional[temporalio.common.RetryPolicy] - local_retry_threshold: Optional[timedelta] + schedule_to_close_timeout: timedelta | None + schedule_to_start_timeout: timedelta | None + start_to_close_timeout: timedelta | None + retry_policy: temporalio.common.RetryPolicy | None + local_retry_threshold: timedelta | None cancellation_type: ActivityCancellationType - activity_id: Optional[str] - summary: Optional[str] + activity_id: str | None + summary: str | None # Overload for async no-param activity @@ -3176,14 +3160,14 @@ class LocalActivityConfig(TypedDict, total=False): def start_local_activity( activity: CallableAsyncNoParam[ReturnType], *, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, - local_retry_threshold: Optional[timedelta] = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, + local_retry_threshold: timedelta | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + summary: str | None = None, ) -> ActivityHandle[ReturnType]: ... @@ -3192,14 +3176,14 @@ def start_local_activity( def start_local_activity( activity: CallableSyncNoParam[ReturnType], *, - activity_id: Optional[str] = None, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, - local_retry_threshold: Optional[timedelta] = None, + activity_id: str | None = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, + local_retry_threshold: timedelta | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - summary: Optional[str] = None, + summary: str | None = None, ) -> ActivityHandle[ReturnType]: ... @@ -3209,14 +3193,14 @@ def start_local_activity( activity: CallableAsyncSingleParam[ParamType, ReturnType], arg: ParamType, *, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, - local_retry_threshold: Optional[timedelta] = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, + local_retry_threshold: timedelta | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + summary: str | None = None, ) -> ActivityHandle[ReturnType]: ... @@ -3226,14 +3210,14 @@ def start_local_activity( activity: CallableSyncSingleParam[ParamType, ReturnType], arg: ParamType, *, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, - local_retry_threshold: Optional[timedelta] = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, + local_retry_threshold: timedelta | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + summary: str | None = None, ) -> ActivityHandle[ReturnType]: ... @@ -3243,14 +3227,14 @@ def start_local_activity( activity: Callable[..., Awaitable[ReturnType]], *, args: Sequence[Any], - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, - local_retry_threshold: Optional[timedelta] = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, + local_retry_threshold: timedelta | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + summary: str | None = None, ) -> ActivityHandle[ReturnType]: ... @@ -3260,14 +3244,14 @@ def start_local_activity( activity: Callable[..., ReturnType], *, args: Sequence[Any], - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, - local_retry_threshold: Optional[timedelta] = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, + local_retry_threshold: timedelta | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + summary: str | None = None, ) -> ActivityHandle[ReturnType]: ... @@ -3278,15 +3262,15 @@ def start_local_activity( arg: Any = temporalio.common._arg_unset, *, args: Sequence[Any] = [], - result_type: Optional[Type] = None, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, - local_retry_threshold: Optional[timedelta] = None, + result_type: type | None = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, + local_retry_threshold: timedelta | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + summary: str | None = None, ) -> ActivityHandle[Any]: ... @@ -3295,15 +3279,15 @@ def start_local_activity( arg: Any = temporalio.common._arg_unset, *, args: Sequence[Any] = [], - result_type: Optional[Type] = None, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, - local_retry_threshold: Optional[timedelta] = None, + result_type: type | None = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, + local_retry_threshold: timedelta | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + summary: str | None = None, ) -> ActivityHandle[Any]: """Start a local activity and return its handle. @@ -3356,14 +3340,14 @@ def start_local_activity( async def execute_local_activity( activity: CallableAsyncNoParam[ReturnType], *, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, - local_retry_threshold: Optional[timedelta] = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, + local_retry_threshold: timedelta | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + summary: str | None = None, ) -> ReturnType: ... @@ -3372,14 +3356,14 @@ async def execute_local_activity( async def execute_local_activity( activity: CallableSyncNoParam[ReturnType], *, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, - local_retry_threshold: Optional[timedelta] = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, + local_retry_threshold: timedelta | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + summary: str | None = None, ) -> ReturnType: ... @@ -3389,14 +3373,14 @@ async def execute_local_activity( activity: CallableAsyncSingleParam[ParamType, ReturnType], arg: ParamType, *, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, - local_retry_threshold: Optional[timedelta] = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, + local_retry_threshold: timedelta | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + summary: str | None = None, ) -> ReturnType: ... @@ -3406,14 +3390,14 @@ async def execute_local_activity( activity: CallableSyncSingleParam[ParamType, ReturnType], arg: ParamType, *, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, - local_retry_threshold: Optional[timedelta] = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, + local_retry_threshold: timedelta | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + summary: str | None = None, ) -> ReturnType: ... @@ -3423,14 +3407,14 @@ async def execute_local_activity( activity: Callable[..., Awaitable[ReturnType]], *, args: Sequence[Any], - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, - local_retry_threshold: Optional[timedelta] = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, + local_retry_threshold: timedelta | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + summary: str | None = None, ) -> ReturnType: ... @@ -3440,14 +3424,14 @@ async def execute_local_activity( activity: Callable[..., ReturnType], *, args: Sequence[Any], - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, - local_retry_threshold: Optional[timedelta] = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, + local_retry_threshold: timedelta | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + summary: str | None = None, ) -> ReturnType: ... @@ -3458,15 +3442,15 @@ async def execute_local_activity( arg: Any = temporalio.common._arg_unset, *, args: Sequence[Any] = [], - result_type: Optional[Type] = None, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, - local_retry_threshold: Optional[timedelta] = None, + result_type: type | None = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, + local_retry_threshold: timedelta | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + summary: str | None = None, ) -> Any: ... @@ -3475,15 +3459,15 @@ async def execute_local_activity( arg: Any = temporalio.common._arg_unset, *, args: Sequence[Any] = [], - result_type: Optional[Type] = None, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, - local_retry_threshold: Optional[timedelta] = None, + result_type: type | None = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, + local_retry_threshold: timedelta | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + summary: str | None = None, ) -> Any: """Start a local activity and wait for completion. @@ -3509,110 +3493,110 @@ async def execute_local_activity( # Overload for async no-param activity @overload def start_local_activity_class( - activity: Type[CallableAsyncNoParam[ReturnType]], + activity: type[CallableAsyncNoParam[ReturnType]], *, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, - local_retry_threshold: Optional[timedelta] = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, + local_retry_threshold: timedelta | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, + activity_id: str | None = None, ) -> ActivityHandle[ReturnType]: ... # Overload for sync no-param activity @overload def start_local_activity_class( - activity: Type[CallableSyncNoParam[ReturnType]], + activity: type[CallableSyncNoParam[ReturnType]], *, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, - local_retry_threshold: Optional[timedelta] = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, + local_retry_threshold: timedelta | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, + activity_id: str | None = None, ) -> ActivityHandle[ReturnType]: ... # Overload for async single-param activity @overload def start_local_activity_class( - activity: Type[CallableAsyncSingleParam[ParamType, ReturnType]], + activity: type[CallableAsyncSingleParam[ParamType, ReturnType]], arg: ParamType, *, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, - local_retry_threshold: Optional[timedelta] = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, + local_retry_threshold: timedelta | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, + activity_id: str | None = None, ) -> ActivityHandle[ReturnType]: ... # Overload for sync single-param activity @overload def start_local_activity_class( - activity: Type[CallableSyncSingleParam[ParamType, ReturnType]], + activity: type[CallableSyncSingleParam[ParamType, ReturnType]], arg: ParamType, *, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, - local_retry_threshold: Optional[timedelta] = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, + local_retry_threshold: timedelta | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, + activity_id: str | None = None, ) -> ActivityHandle[ReturnType]: ... # Overload for async multi-param activity @overload def start_local_activity_class( - activity: Type[Callable[..., Awaitable[ReturnType]]], + activity: type[Callable[..., Awaitable[ReturnType]]], *, args: Sequence[Any], - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, - local_retry_threshold: Optional[timedelta] = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, + local_retry_threshold: timedelta | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, + activity_id: str | None = None, ) -> ActivityHandle[ReturnType]: ... # Overload for sync multi-param activity @overload def start_local_activity_class( - activity: Type[Callable[..., ReturnType]], + activity: type[Callable[..., ReturnType]], *, args: Sequence[Any], - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, - local_retry_threshold: Optional[timedelta] = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, + local_retry_threshold: timedelta | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, + activity_id: str | None = None, ) -> ActivityHandle[ReturnType]: ... def start_local_activity_class( - activity: Type[Callable], + activity: type[Callable], arg: Any = temporalio.common._arg_unset, *, args: Sequence[Any] = [], - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, - local_retry_threshold: Optional[timedelta] = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, + local_retry_threshold: timedelta | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + summary: str | None = None, ) -> ActivityHandle[Any]: """Start a local activity from a callable class. @@ -3636,116 +3620,116 @@ def start_local_activity_class( # Overload for async no-param activity @overload async def execute_local_activity_class( - activity: Type[CallableAsyncNoParam[ReturnType]], + activity: type[CallableAsyncNoParam[ReturnType]], *, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, - local_retry_threshold: Optional[timedelta] = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, + local_retry_threshold: timedelta | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + summary: str | None = None, ) -> ReturnType: ... # Overload for sync no-param activity @overload async def execute_local_activity_class( - activity: Type[CallableSyncNoParam[ReturnType]], + activity: type[CallableSyncNoParam[ReturnType]], *, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, - local_retry_threshold: Optional[timedelta] = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, + local_retry_threshold: timedelta | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + summary: str | None = None, ) -> ReturnType: ... # Overload for async single-param activity @overload async def execute_local_activity_class( - activity: Type[CallableAsyncSingleParam[ParamType, ReturnType]], + activity: type[CallableAsyncSingleParam[ParamType, ReturnType]], arg: ParamType, *, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, - local_retry_threshold: Optional[timedelta] = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, + local_retry_threshold: timedelta | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + summary: str | None = None, ) -> ReturnType: ... # Overload for sync single-param activity @overload async def execute_local_activity_class( - activity: Type[CallableSyncSingleParam[ParamType, ReturnType]], + activity: type[CallableSyncSingleParam[ParamType, ReturnType]], arg: ParamType, *, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, - local_retry_threshold: Optional[timedelta] = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, + local_retry_threshold: timedelta | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + summary: str | None = None, ) -> ReturnType: ... # Overload for async multi-param activity @overload async def execute_local_activity_class( - activity: Type[Callable[..., Awaitable[ReturnType]]], + activity: type[Callable[..., Awaitable[ReturnType]]], *, args: Sequence[Any], - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, - local_retry_threshold: Optional[timedelta] = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, + local_retry_threshold: timedelta | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + summary: str | None = None, ) -> ReturnType: ... # Overload for sync multi-param activity @overload async def execute_local_activity_class( - activity: Type[Callable[..., ReturnType]], + activity: type[Callable[..., ReturnType]], *, args: Sequence[Any], - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, - local_retry_threshold: Optional[timedelta] = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, + local_retry_threshold: timedelta | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + summary: str | None = None, ) -> ReturnType: ... async def execute_local_activity_class( - activity: Type[Callable], + activity: type[Callable], arg: Any = temporalio.common._arg_unset, *, args: Sequence[Any] = [], - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, - local_retry_threshold: Optional[timedelta] = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, + local_retry_threshold: timedelta | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + summary: str | None = None, ) -> Any: """Start a local activity from a callable class and wait for completion. @@ -3773,14 +3757,14 @@ async def execute_local_activity_class( def start_local_activity_method( activity: MethodAsyncNoParam[SelfType, ReturnType], *, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, - local_retry_threshold: Optional[timedelta] = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, + local_retry_threshold: timedelta | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + summary: str | None = None, ) -> ActivityHandle[ReturnType]: ... @@ -3789,14 +3773,14 @@ def start_local_activity_method( def start_local_activity_method( activity: MethodSyncNoParam[SelfType, ReturnType], *, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, - local_retry_threshold: Optional[timedelta] = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, + local_retry_threshold: timedelta | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + summary: str | None = None, ) -> ActivityHandle[ReturnType]: ... @@ -3806,14 +3790,14 @@ def start_local_activity_method( activity: MethodAsyncSingleParam[SelfType, ParamType, ReturnType], arg: ParamType, *, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, - local_retry_threshold: Optional[timedelta] = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, + local_retry_threshold: timedelta | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + summary: str | None = None, ) -> ActivityHandle[ReturnType]: ... @@ -3823,14 +3807,14 @@ def start_local_activity_method( activity: MethodSyncSingleParam[SelfType, ParamType, ReturnType], arg: ParamType, *, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, - local_retry_threshold: Optional[timedelta] = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, + local_retry_threshold: timedelta | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + summary: str | None = None, ) -> ActivityHandle[ReturnType]: ... @@ -3840,14 +3824,14 @@ def start_local_activity_method( activity: Callable[Concatenate[SelfType, MultiParamSpec], Awaitable[ReturnType]], *, args: Sequence[Any], - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, - local_retry_threshold: Optional[timedelta] = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, + local_retry_threshold: timedelta | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + summary: str | None = None, ) -> ActivityHandle[ReturnType]: ... @@ -3857,14 +3841,14 @@ def start_local_activity_method( activity: Callable[Concatenate[SelfType, MultiParamSpec], ReturnType], *, args: Sequence[Any], - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, - local_retry_threshold: Optional[timedelta] = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, + local_retry_threshold: timedelta | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + summary: str | None = None, ) -> ActivityHandle[ReturnType]: ... @@ -3873,14 +3857,14 @@ def start_local_activity_method( arg: Any = temporalio.common._arg_unset, *, args: Sequence[Any] = [], - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, - local_retry_threshold: Optional[timedelta] = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, + local_retry_threshold: timedelta | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + summary: str | None = None, ) -> ActivityHandle[Any]: """Start a local activity from a method. @@ -3906,14 +3890,14 @@ def start_local_activity_method( async def execute_local_activity_method( activity: MethodAsyncNoParam[SelfType, ReturnType], *, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, - local_retry_threshold: Optional[timedelta] = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, + local_retry_threshold: timedelta | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + summary: str | None = None, ) -> ReturnType: ... @@ -3922,14 +3906,14 @@ async def execute_local_activity_method( async def execute_local_activity_method( activity: MethodSyncNoParam[SelfType, ReturnType], *, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, - local_retry_threshold: Optional[timedelta] = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, + local_retry_threshold: timedelta | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + summary: str | None = None, ) -> ReturnType: ... @@ -3939,14 +3923,14 @@ async def execute_local_activity_method( activity: MethodAsyncSingleParam[SelfType, ParamType, ReturnType], arg: ParamType, *, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, - local_retry_threshold: Optional[timedelta] = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, + local_retry_threshold: timedelta | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + summary: str | None = None, ) -> ReturnType: ... @@ -3956,14 +3940,14 @@ async def execute_local_activity_method( activity: MethodSyncSingleParam[SelfType, ParamType, ReturnType], arg: ParamType, *, - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, - local_retry_threshold: Optional[timedelta] = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, + local_retry_threshold: timedelta | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + summary: str | None = None, ) -> ReturnType: ... @@ -3973,14 +3957,14 @@ async def execute_local_activity_method( activity: Callable[Concatenate[SelfType, MultiParamSpec], Awaitable[ReturnType]], *, args: Sequence[Any], - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, - local_retry_threshold: Optional[timedelta] = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, + local_retry_threshold: timedelta | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + summary: str | None = None, ) -> ReturnType: ... @@ -3990,14 +3974,14 @@ async def execute_local_activity_method( activity: Callable[Concatenate[SelfType, MultiParamSpec], ReturnType], *, args: Sequence[Any], - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, - local_retry_threshold: Optional[timedelta] = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, + local_retry_threshold: timedelta | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + summary: str | None = None, ) -> ReturnType: ... @@ -4006,14 +3990,14 @@ async def execute_local_activity_method( arg: Any = temporalio.common._arg_unset, *, args: Sequence[Any] = [], - schedule_to_close_timeout: Optional[timedelta] = None, - schedule_to_start_timeout: Optional[timedelta] = None, - start_to_close_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, - local_retry_threshold: Optional[timedelta] = None, + schedule_to_close_timeout: timedelta | None = None, + schedule_to_start_timeout: timedelta | None = None, + start_to_close_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, + local_retry_threshold: timedelta | None = None, cancellation_type: ActivityCancellationType = ActivityCancellationType.TRY_CANCEL, - activity_id: Optional[str] = None, - summary: Optional[str] = None, + activity_id: str | None = None, + summary: str | None = None, ) -> Any: """Start a local activity from a method and wait for completion. @@ -4050,7 +4034,7 @@ def id(self) -> str: raise NotImplementedError @property - def first_execution_run_id(self) -> Optional[str]: + def first_execution_run_id(self) -> str | None: """Run ID for the workflow.""" raise NotImplementedError @@ -4070,9 +4054,7 @@ async def signal( @overload async def signal( self, - signal: Callable[ - Concatenate[SelfType, MultiParamSpec], Union[Awaitable[None], None] - ], + signal: Callable[Concatenate[SelfType, MultiParamSpec], Awaitable[None] | None], *, args: Sequence[Any], ) -> None: ... @@ -4088,7 +4070,7 @@ async def signal( async def signal( self, - signal: Union[str, Callable], + signal: str | Callable, arg: Any = temporalio.common._arg_unset, *, args: Sequence[Any] = [], @@ -4143,25 +4125,23 @@ class ChildWorkflowConfig(TypedDict, total=False): and :py:func:`execute_child_workflow`. """ - id: Optional[str] - task_queue: Optional[str] + id: str | None + task_queue: str | None cancellation_type: ChildWorkflowCancellationType parent_close_policy: ParentClosePolicy - execution_timeout: Optional[timedelta] - run_timeout: Optional[timedelta] - task_timeout: Optional[timedelta] + execution_timeout: timedelta | None + run_timeout: timedelta | None + task_timeout: timedelta | None id_reuse_policy: temporalio.common.WorkflowIDReusePolicy - retry_policy: Optional[temporalio.common.RetryPolicy] + retry_policy: temporalio.common.RetryPolicy | None cron_schedule: str - memo: Optional[Mapping[str, Any]] - search_attributes: Optional[ - Union[ - temporalio.common.SearchAttributes, temporalio.common.TypedSearchAttributes - ] - ] - versioning_intent: Optional[VersioningIntent] - static_summary: Optional[str] - static_details: Optional[str] + memo: Mapping[str, Any] | None + search_attributes: None | ( + temporalio.common.SearchAttributes | temporalio.common.TypedSearchAttributes + ) + versioning_intent: VersioningIntent | None + static_summary: str | None + static_details: str | None priority: temporalio.common.Priority @@ -4170,25 +4150,24 @@ class ChildWorkflowConfig(TypedDict, total=False): async def start_child_workflow( workflow: MethodAsyncNoParam[SelfType, ReturnType], *, - id: Optional[str] = None, - task_queue: Optional[str] = None, + id: str | None = None, + task_queue: str | None = None, cancellation_type: ChildWorkflowCancellationType = ChildWorkflowCancellationType.WAIT_CANCELLATION_COMPLETED, parent_close_policy: ParentClosePolicy = ParentClosePolicy.TERMINATE, - execution_timeout: Optional[timedelta] = None, - run_timeout: Optional[timedelta] = None, - task_timeout: Optional[timedelta] = None, + execution_timeout: timedelta | None = None, + run_timeout: timedelta | None = None, + task_timeout: timedelta | None = None, id_reuse_policy: temporalio.common.WorkflowIDReusePolicy = temporalio.common.WorkflowIDReusePolicy.ALLOW_DUPLICATE, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cron_schedule: str = "", - memo: Optional[Mapping[str, Any]] = None, - search_attributes: Optional[ - Union[ - temporalio.common.SearchAttributes, temporalio.common.TypedSearchAttributes - ] - ] = None, - versioning_intent: Optional[VersioningIntent] = None, - static_summary: Optional[str] = None, - static_details: Optional[str] = None, + memo: Mapping[str, Any] | None = None, + search_attributes: None + | ( + temporalio.common.SearchAttributes | temporalio.common.TypedSearchAttributes + ) = None, + versioning_intent: VersioningIntent | None = None, + static_summary: str | None = None, + static_details: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> ChildWorkflowHandle[SelfType, ReturnType]: ... @@ -4199,25 +4178,24 @@ async def start_child_workflow( workflow: MethodAsyncSingleParam[SelfType, ParamType, ReturnType], arg: ParamType, *, - id: Optional[str] = None, - task_queue: Optional[str] = None, + id: str | None = None, + task_queue: str | None = None, cancellation_type: ChildWorkflowCancellationType = ChildWorkflowCancellationType.WAIT_CANCELLATION_COMPLETED, parent_close_policy: ParentClosePolicy = ParentClosePolicy.TERMINATE, - execution_timeout: Optional[timedelta] = None, - run_timeout: Optional[timedelta] = None, - task_timeout: Optional[timedelta] = None, + execution_timeout: timedelta | None = None, + run_timeout: timedelta | None = None, + task_timeout: timedelta | None = None, id_reuse_policy: temporalio.common.WorkflowIDReusePolicy = temporalio.common.WorkflowIDReusePolicy.ALLOW_DUPLICATE, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cron_schedule: str = "", - memo: Optional[Mapping[str, Any]] = None, - search_attributes: Optional[ - Union[ - temporalio.common.SearchAttributes, temporalio.common.TypedSearchAttributes - ] - ] = None, - versioning_intent: Optional[VersioningIntent] = None, - static_summary: Optional[str] = None, - static_details: Optional[str] = None, + memo: Mapping[str, Any] | None = None, + search_attributes: None + | ( + temporalio.common.SearchAttributes | temporalio.common.TypedSearchAttributes + ) = None, + versioning_intent: VersioningIntent | None = None, + static_summary: str | None = None, + static_details: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> ChildWorkflowHandle[SelfType, ReturnType]: ... @@ -4228,25 +4206,24 @@ async def start_child_workflow( workflow: Callable[Concatenate[SelfType, MultiParamSpec], Awaitable[ReturnType]], *, args: Sequence[Any], - id: Optional[str] = None, - task_queue: Optional[str] = None, + id: str | None = None, + task_queue: str | None = None, cancellation_type: ChildWorkflowCancellationType = ChildWorkflowCancellationType.WAIT_CANCELLATION_COMPLETED, parent_close_policy: ParentClosePolicy = ParentClosePolicy.TERMINATE, - execution_timeout: Optional[timedelta] = None, - run_timeout: Optional[timedelta] = None, - task_timeout: Optional[timedelta] = None, + execution_timeout: timedelta | None = None, + run_timeout: timedelta | None = None, + task_timeout: timedelta | None = None, id_reuse_policy: temporalio.common.WorkflowIDReusePolicy = temporalio.common.WorkflowIDReusePolicy.ALLOW_DUPLICATE, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cron_schedule: str = "", - memo: Optional[Mapping[str, Any]] = None, - search_attributes: Optional[ - Union[ - temporalio.common.SearchAttributes, temporalio.common.TypedSearchAttributes - ] - ] = None, - versioning_intent: Optional[VersioningIntent] = None, - static_summary: Optional[str] = None, - static_details: Optional[str] = None, + memo: Mapping[str, Any] | None = None, + search_attributes: None + | ( + temporalio.common.SearchAttributes | temporalio.common.TypedSearchAttributes + ) = None, + versioning_intent: VersioningIntent | None = None, + static_summary: str | None = None, + static_details: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> ChildWorkflowHandle[SelfType, ReturnType]: ... @@ -4258,26 +4235,25 @@ async def start_child_workflow( arg: Any = temporalio.common._arg_unset, *, args: Sequence[Any] = [], - id: Optional[str] = None, - task_queue: Optional[str] = None, - result_type: Optional[Type] = None, + id: str | None = None, + task_queue: str | None = None, + result_type: type | None = None, cancellation_type: ChildWorkflowCancellationType = ChildWorkflowCancellationType.WAIT_CANCELLATION_COMPLETED, parent_close_policy: ParentClosePolicy = ParentClosePolicy.TERMINATE, - execution_timeout: Optional[timedelta] = None, - run_timeout: Optional[timedelta] = None, - task_timeout: Optional[timedelta] = None, + execution_timeout: timedelta | None = None, + run_timeout: timedelta | None = None, + task_timeout: timedelta | None = None, id_reuse_policy: temporalio.common.WorkflowIDReusePolicy = temporalio.common.WorkflowIDReusePolicy.ALLOW_DUPLICATE, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cron_schedule: str = "", - memo: Optional[Mapping[str, Any]] = None, - search_attributes: Optional[ - Union[ - temporalio.common.SearchAttributes, temporalio.common.TypedSearchAttributes - ] - ] = None, - versioning_intent: Optional[VersioningIntent] = None, - static_summary: Optional[str] = None, - static_details: Optional[str] = None, + memo: Mapping[str, Any] | None = None, + search_attributes: None + | ( + temporalio.common.SearchAttributes | temporalio.common.TypedSearchAttributes + ) = None, + versioning_intent: VersioningIntent | None = None, + static_summary: str | None = None, + static_details: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> ChildWorkflowHandle[Any, Any]: ... @@ -4287,26 +4263,25 @@ async def start_child_workflow( arg: Any = temporalio.common._arg_unset, *, args: Sequence[Any] = [], - id: Optional[str] = None, - task_queue: Optional[str] = None, - result_type: Optional[Type] = None, + id: str | None = None, + task_queue: str | None = None, + result_type: type | None = None, cancellation_type: ChildWorkflowCancellationType = ChildWorkflowCancellationType.WAIT_CANCELLATION_COMPLETED, parent_close_policy: ParentClosePolicy = ParentClosePolicy.TERMINATE, - execution_timeout: Optional[timedelta] = None, - run_timeout: Optional[timedelta] = None, - task_timeout: Optional[timedelta] = None, + execution_timeout: timedelta | None = None, + run_timeout: timedelta | None = None, + task_timeout: timedelta | None = None, id_reuse_policy: temporalio.common.WorkflowIDReusePolicy = temporalio.common.WorkflowIDReusePolicy.ALLOW_DUPLICATE, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cron_schedule: str = "", - memo: Optional[Mapping[str, Any]] = None, - search_attributes: Optional[ - Union[ - temporalio.common.SearchAttributes, temporalio.common.TypedSearchAttributes - ] - ] = None, - versioning_intent: Optional[VersioningIntent] = None, - static_summary: Optional[str] = None, - static_details: Optional[str] = None, + memo: Mapping[str, Any] | None = None, + search_attributes: None + | ( + temporalio.common.SearchAttributes | temporalio.common.TypedSearchAttributes + ) = None, + versioning_intent: VersioningIntent | None = None, + static_summary: str | None = None, + static_details: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> ChildWorkflowHandle[Any, Any]: """Start a child workflow and return its handle. @@ -4378,25 +4353,24 @@ async def start_child_workflow( async def execute_child_workflow( workflow: MethodAsyncNoParam[SelfType, ReturnType], *, - id: Optional[str] = None, - task_queue: Optional[str] = None, + id: str | None = None, + task_queue: str | None = None, cancellation_type: ChildWorkflowCancellationType = ChildWorkflowCancellationType.WAIT_CANCELLATION_COMPLETED, parent_close_policy: ParentClosePolicy = ParentClosePolicy.TERMINATE, - execution_timeout: Optional[timedelta] = None, - run_timeout: Optional[timedelta] = None, - task_timeout: Optional[timedelta] = None, + execution_timeout: timedelta | None = None, + run_timeout: timedelta | None = None, + task_timeout: timedelta | None = None, id_reuse_policy: temporalio.common.WorkflowIDReusePolicy = temporalio.common.WorkflowIDReusePolicy.ALLOW_DUPLICATE, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cron_schedule: str = "", - memo: Optional[Mapping[str, Any]] = None, - search_attributes: Optional[ - Union[ - temporalio.common.SearchAttributes, temporalio.common.TypedSearchAttributes - ] - ] = None, - versioning_intent: Optional[VersioningIntent] = None, - static_summary: Optional[str] = None, - static_details: Optional[str] = None, + memo: Mapping[str, Any] | None = None, + search_attributes: None + | ( + temporalio.common.SearchAttributes | temporalio.common.TypedSearchAttributes + ) = None, + versioning_intent: VersioningIntent | None = None, + static_summary: str | None = None, + static_details: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> ReturnType: ... @@ -4407,25 +4381,24 @@ async def execute_child_workflow( workflow: MethodAsyncSingleParam[SelfType, ParamType, ReturnType], arg: ParamType, *, - id: Optional[str] = None, - task_queue: Optional[str] = None, + id: str | None = None, + task_queue: str | None = None, cancellation_type: ChildWorkflowCancellationType = ChildWorkflowCancellationType.WAIT_CANCELLATION_COMPLETED, parent_close_policy: ParentClosePolicy = ParentClosePolicy.TERMINATE, - execution_timeout: Optional[timedelta] = None, - run_timeout: Optional[timedelta] = None, - task_timeout: Optional[timedelta] = None, + execution_timeout: timedelta | None = None, + run_timeout: timedelta | None = None, + task_timeout: timedelta | None = None, id_reuse_policy: temporalio.common.WorkflowIDReusePolicy = temporalio.common.WorkflowIDReusePolicy.ALLOW_DUPLICATE, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cron_schedule: str = "", - memo: Optional[Mapping[str, Any]] = None, - search_attributes: Optional[ - Union[ - temporalio.common.SearchAttributes, temporalio.common.TypedSearchAttributes - ] - ] = None, - versioning_intent: Optional[VersioningIntent] = None, - static_summary: Optional[str] = None, - static_details: Optional[str] = None, + memo: Mapping[str, Any] | None = None, + search_attributes: None + | ( + temporalio.common.SearchAttributes | temporalio.common.TypedSearchAttributes + ) = None, + versioning_intent: VersioningIntent | None = None, + static_summary: str | None = None, + static_details: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> ReturnType: ... @@ -4436,25 +4409,24 @@ async def execute_child_workflow( workflow: Callable[Concatenate[SelfType, MultiParamSpec], Awaitable[ReturnType]], *, args: Sequence[Any], - id: Optional[str] = None, - task_queue: Optional[str] = None, + id: str | None = None, + task_queue: str | None = None, cancellation_type: ChildWorkflowCancellationType = ChildWorkflowCancellationType.WAIT_CANCELLATION_COMPLETED, parent_close_policy: ParentClosePolicy = ParentClosePolicy.TERMINATE, - execution_timeout: Optional[timedelta] = None, - run_timeout: Optional[timedelta] = None, - task_timeout: Optional[timedelta] = None, + execution_timeout: timedelta | None = None, + run_timeout: timedelta | None = None, + task_timeout: timedelta | None = None, id_reuse_policy: temporalio.common.WorkflowIDReusePolicy = temporalio.common.WorkflowIDReusePolicy.ALLOW_DUPLICATE, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cron_schedule: str = "", - memo: Optional[Mapping[str, Any]] = None, - search_attributes: Optional[ - Union[ - temporalio.common.SearchAttributes, temporalio.common.TypedSearchAttributes - ] - ] = None, - versioning_intent: Optional[VersioningIntent] = None, - static_summary: Optional[str] = None, - static_details: Optional[str] = None, + memo: Mapping[str, Any] | None = None, + search_attributes: None + | ( + temporalio.common.SearchAttributes | temporalio.common.TypedSearchAttributes + ) = None, + versioning_intent: VersioningIntent | None = None, + static_summary: str | None = None, + static_details: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> ReturnType: ... @@ -4466,26 +4438,25 @@ async def execute_child_workflow( arg: Any = temporalio.common._arg_unset, *, args: Sequence[Any] = [], - id: Optional[str] = None, - task_queue: Optional[str] = None, - result_type: Optional[Type] = None, + id: str | None = None, + task_queue: str | None = None, + result_type: type | None = None, cancellation_type: ChildWorkflowCancellationType = ChildWorkflowCancellationType.WAIT_CANCELLATION_COMPLETED, parent_close_policy: ParentClosePolicy = ParentClosePolicy.TERMINATE, - execution_timeout: Optional[timedelta] = None, - run_timeout: Optional[timedelta] = None, - task_timeout: Optional[timedelta] = None, + execution_timeout: timedelta | None = None, + run_timeout: timedelta | None = None, + task_timeout: timedelta | None = None, id_reuse_policy: temporalio.common.WorkflowIDReusePolicy = temporalio.common.WorkflowIDReusePolicy.ALLOW_DUPLICATE, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cron_schedule: str = "", - memo: Optional[Mapping[str, Any]] = None, - search_attributes: Optional[ - Union[ - temporalio.common.SearchAttributes, temporalio.common.TypedSearchAttributes - ] - ] = None, - versioning_intent: Optional[VersioningIntent] = None, - static_summary: Optional[str] = None, - static_details: Optional[str] = None, + memo: Mapping[str, Any] | None = None, + search_attributes: None + | ( + temporalio.common.SearchAttributes | temporalio.common.TypedSearchAttributes + ) = None, + versioning_intent: VersioningIntent | None = None, + static_summary: str | None = None, + static_details: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> Any: ... @@ -4495,26 +4466,25 @@ async def execute_child_workflow( arg: Any = temporalio.common._arg_unset, *, args: Sequence[Any] = [], - id: Optional[str] = None, - task_queue: Optional[str] = None, - result_type: Optional[Type] = None, + id: str | None = None, + task_queue: str | None = None, + result_type: type | None = None, cancellation_type: ChildWorkflowCancellationType = ChildWorkflowCancellationType.WAIT_CANCELLATION_COMPLETED, parent_close_policy: ParentClosePolicy = ParentClosePolicy.TERMINATE, - execution_timeout: Optional[timedelta] = None, - run_timeout: Optional[timedelta] = None, - task_timeout: Optional[timedelta] = None, + execution_timeout: timedelta | None = None, + run_timeout: timedelta | None = None, + task_timeout: timedelta | None = None, id_reuse_policy: temporalio.common.WorkflowIDReusePolicy = temporalio.common.WorkflowIDReusePolicy.ALLOW_DUPLICATE, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, + retry_policy: temporalio.common.RetryPolicy | None = None, cron_schedule: str = "", - memo: Optional[Mapping[str, Any]] = None, - search_attributes: Optional[ - Union[ - temporalio.common.SearchAttributes, temporalio.common.TypedSearchAttributes - ] - ] = None, - versioning_intent: Optional[VersioningIntent] = None, - static_summary: Optional[str] = None, - static_details: Optional[str] = None, + memo: Mapping[str, Any] | None = None, + search_attributes: None + | ( + temporalio.common.SearchAttributes | temporalio.common.TypedSearchAttributes + ) = None, + versioning_intent: VersioningIntent | None = None, + static_summary: str | None = None, + static_details: str | None = None, priority: temporalio.common.Priority = temporalio.common.Priority.default, ) -> Any: """Start a child workflow and wait for completion. @@ -4566,7 +4536,7 @@ def __await__(self) -> Generator[Any, Any, OutputT]: raise NotImplementedError @property - def operation_token(self) -> Optional[str]: + def operation_token(self) -> str | None: """The operation token for this handle.""" raise NotImplementedError @@ -4584,7 +4554,7 @@ def id(self) -> str: raise NotImplementedError @property - def run_id(self) -> Optional[str]: + def run_id(self) -> str | None: """Run ID for the workflow if any.""" raise NotImplementedError @@ -4612,7 +4582,7 @@ async def signal( async def signal( self, - signal: Union[str, Callable], + signal: str | Callable, arg: Any = temporalio.common._arg_unset, *, args: Sequence[Any] = [], @@ -4639,7 +4609,7 @@ async def cancel(self) -> None: def get_external_workflow_handle( workflow_id: str, *, - run_id: Optional[str] = None, + run_id: str | None = None, ) -> ExternalWorkflowHandle[Any]: """Get a workflow handle to an existing workflow by its ID. @@ -4656,12 +4626,12 @@ def get_external_workflow_handle( def get_external_workflow_handle_for( - workflow: Union[ - MethodAsyncNoParam[SelfType, Any], MethodAsyncSingleParam[SelfType, Any, Any] - ], + workflow: ( + MethodAsyncNoParam[SelfType, Any] | MethodAsyncSingleParam[SelfType, Any, Any] + ), workflow_id: str, *, - run_id: Optional[str] = None, + run_id: str | None = None, ) -> ExternalWorkflowHandle[SelfType]: """Get a typed workflow handle to an existing workflow by its ID. @@ -4700,17 +4670,16 @@ def continue_as_new( arg: Any = temporalio.common._arg_unset, *, args: Sequence[Any] = [], - task_queue: Optional[str] = None, - run_timeout: Optional[timedelta] = None, - task_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, - memo: Optional[Mapping[str, Any]] = None, - search_attributes: Optional[ - Union[ - temporalio.common.SearchAttributes, temporalio.common.TypedSearchAttributes - ] - ] = None, - versioning_intent: Optional[VersioningIntent] = None, + task_queue: str | None = None, + run_timeout: timedelta | None = None, + task_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, + memo: Mapping[str, Any] | None = None, + search_attributes: None + | ( + temporalio.common.SearchAttributes | temporalio.common.TypedSearchAttributes + ) = None, + versioning_intent: VersioningIntent | None = None, ) -> NoReturn: ... @@ -4719,17 +4688,16 @@ def continue_as_new( def continue_as_new( *, workflow: MethodAsyncNoParam[SelfType, Any], - task_queue: Optional[str] = None, - run_timeout: Optional[timedelta] = None, - task_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, - memo: Optional[Mapping[str, Any]] = None, - search_attributes: Optional[ - Union[ - temporalio.common.SearchAttributes, temporalio.common.TypedSearchAttributes - ] - ] = None, - versioning_intent: Optional[VersioningIntent] = None, + task_queue: str | None = None, + run_timeout: timedelta | None = None, + task_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, + memo: Mapping[str, Any] | None = None, + search_attributes: None + | ( + temporalio.common.SearchAttributes | temporalio.common.TypedSearchAttributes + ) = None, + versioning_intent: VersioningIntent | None = None, ) -> NoReturn: ... @@ -4739,17 +4707,16 @@ def continue_as_new( arg: ParamType, *, workflow: MethodAsyncSingleParam[SelfType, ParamType, Any], - task_queue: Optional[str] = None, - run_timeout: Optional[timedelta] = None, - task_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, - memo: Optional[Mapping[str, Any]] = None, - search_attributes: Optional[ - Union[ - temporalio.common.SearchAttributes, temporalio.common.TypedSearchAttributes - ] - ] = None, - versioning_intent: Optional[VersioningIntent] = None, + task_queue: str | None = None, + run_timeout: timedelta | None = None, + task_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, + memo: Mapping[str, Any] | None = None, + search_attributes: None + | ( + temporalio.common.SearchAttributes | temporalio.common.TypedSearchAttributes + ) = None, + versioning_intent: VersioningIntent | None = None, ) -> NoReturn: ... @@ -4759,17 +4726,16 @@ def continue_as_new( *, workflow: Callable[Concatenate[SelfType, MultiParamSpec], Awaitable[Any]], args: Sequence[Any], - task_queue: Optional[str] = None, - run_timeout: Optional[timedelta] = None, - task_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, - memo: Optional[Mapping[str, Any]] = None, - search_attributes: Optional[ - Union[ - temporalio.common.SearchAttributes, temporalio.common.TypedSearchAttributes - ] - ] = None, - versioning_intent: Optional[VersioningIntent] = None, + task_queue: str | None = None, + run_timeout: timedelta | None = None, + task_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, + memo: Mapping[str, Any] | None = None, + search_attributes: None + | ( + temporalio.common.SearchAttributes | temporalio.common.TypedSearchAttributes + ) = None, + versioning_intent: VersioningIntent | None = None, ) -> NoReturn: ... @@ -4779,17 +4745,16 @@ def continue_as_new( *, workflow: str, args: Sequence[Any] = [], - task_queue: Optional[str] = None, - run_timeout: Optional[timedelta] = None, - task_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, - memo: Optional[Mapping[str, Any]] = None, - search_attributes: Optional[ - Union[ - temporalio.common.SearchAttributes, temporalio.common.TypedSearchAttributes - ] - ] = None, - versioning_intent: Optional[VersioningIntent] = None, + task_queue: str | None = None, + run_timeout: timedelta | None = None, + task_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, + memo: Mapping[str, Any] | None = None, + search_attributes: None + | ( + temporalio.common.SearchAttributes | temporalio.common.TypedSearchAttributes + ) = None, + versioning_intent: VersioningIntent | None = None, ) -> NoReturn: ... @@ -4797,18 +4762,17 @@ def continue_as_new( arg: Any = temporalio.common._arg_unset, *, args: Sequence[Any] = [], - workflow: Union[None, Callable, str] = None, - task_queue: Optional[str] = None, - run_timeout: Optional[timedelta] = None, - task_timeout: Optional[timedelta] = None, - retry_policy: Optional[temporalio.common.RetryPolicy] = None, - memo: Optional[Mapping[str, Any]] = None, - search_attributes: Optional[ - Union[ - temporalio.common.SearchAttributes, temporalio.common.TypedSearchAttributes - ] - ] = None, - versioning_intent: Optional[VersioningIntent] = None, + workflow: None | Callable | str = None, + task_queue: str | None = None, + run_timeout: timedelta | None = None, + task_timeout: timedelta | None = None, + retry_policy: temporalio.common.RetryPolicy | None = None, + memo: Mapping[str, Any] | None = None, + search_attributes: None + | ( + temporalio.common.SearchAttributes | temporalio.common.TypedSearchAttributes + ) = None, + versioning_intent: VersioningIntent | None = None, ) -> NoReturn: """Stop the workflow immediately and continue as new. @@ -4853,7 +4817,7 @@ def continue_as_new( ) -def get_signal_handler(name: str) -> Optional[Callable]: +def get_signal_handler(name: str) -> Callable | None: """Get the signal handler for the given name if any. This includes handlers created via the ``@workflow.signal`` decorator. @@ -4868,7 +4832,7 @@ def get_signal_handler(name: str) -> Optional[Callable]: return _Runtime.current().workflow_get_signal_handler(name) -def set_signal_handler(name: str, handler: Optional[Callable]) -> None: +def set_signal_handler(name: str, handler: Callable | None) -> None: """Set or unset the signal handler for the given name. This overrides any existing handlers for the given name, including handlers @@ -4884,7 +4848,7 @@ def set_signal_handler(name: str, handler: Optional[Callable]) -> None: _Runtime.current().workflow_set_signal_handler(name, handler) -def get_dynamic_signal_handler() -> Optional[Callable]: +def get_dynamic_signal_handler() -> Callable | None: """Get the dynamic signal handler if any. This includes dynamic handlers created via the ``@workflow.signal`` @@ -4896,7 +4860,7 @@ def get_dynamic_signal_handler() -> Optional[Callable]: return _Runtime.current().workflow_get_signal_handler(None) -def set_dynamic_signal_handler(handler: Optional[Callable]) -> None: +def set_dynamic_signal_handler(handler: Callable | None) -> None: """Set or unset the dynamic signal handler. This overrides the existing dynamic handler even if it was created via the @@ -4910,7 +4874,7 @@ def set_dynamic_signal_handler(handler: Optional[Callable]) -> None: _Runtime.current().workflow_set_signal_handler(None, handler) -def get_query_handler(name: str) -> Optional[Callable]: +def get_query_handler(name: str) -> Callable | None: """Get the query handler for the given name if any. This includes handlers created via the ``@workflow.query`` decorator. @@ -4925,7 +4889,7 @@ def get_query_handler(name: str) -> Optional[Callable]: return _Runtime.current().workflow_get_query_handler(name) -def set_query_handler(name: str, handler: Optional[Callable]) -> None: +def set_query_handler(name: str, handler: Callable | None) -> None: """Set or unset the query handler for the given name. This overrides any existing handlers for the given name, including handlers @@ -4938,7 +4902,7 @@ def set_query_handler(name: str, handler: Optional[Callable]) -> None: _Runtime.current().workflow_set_query_handler(name, handler) -def get_dynamic_query_handler() -> Optional[Callable]: +def get_dynamic_query_handler() -> Callable | None: """Get the dynamic query handler if any. This includes dynamic handlers created via the ``@workflow.query`` @@ -4950,7 +4914,7 @@ def get_dynamic_query_handler() -> Optional[Callable]: return _Runtime.current().workflow_get_query_handler(None) -def set_dynamic_query_handler(handler: Optional[Callable]) -> None: +def set_dynamic_query_handler(handler: Callable | None) -> None: """Set or unset the dynamic query handler. This overrides the existing dynamic handler even if it was created via the @@ -4962,7 +4926,7 @@ def set_dynamic_query_handler(handler: Optional[Callable]) -> None: _Runtime.current().workflow_set_query_handler(None, handler) -def get_update_handler(name: str) -> Optional[Callable]: +def get_update_handler(name: str) -> Callable | None: """Get the update handler for the given name if any. This includes handlers created via the ``@workflow.update`` decorator. @@ -4978,7 +4942,7 @@ def get_update_handler(name: str) -> Optional[Callable]: def set_update_handler( - name: str, handler: Optional[Callable], *, validator: Optional[Callable] = None + name: str, handler: Callable | None, *, validator: Callable | None = None ) -> None: """Set or unset the update handler for the given name. @@ -4993,7 +4957,7 @@ def set_update_handler( _Runtime.current().workflow_set_update_handler(name, handler, validator) -def get_dynamic_update_handler() -> Optional[Callable]: +def get_dynamic_update_handler() -> Callable | None: """Get the dynamic update handler if any. This includes dynamic handlers created via the ``@workflow.update`` @@ -5006,7 +4970,7 @@ def get_dynamic_update_handler() -> Optional[Callable]: def set_dynamic_update_handler( - handler: Optional[Callable], *, validator: Optional[Callable] = None + handler: Callable | None, *, validator: Callable | None = None ) -> None: """Set or unset the dynamic update handler. @@ -5034,7 +4998,7 @@ def all_handlers_finished() -> bool: def as_completed( - fs: Iterable[Awaitable[AnyType]], *, timeout: Optional[float] = None + fs: Iterable[Awaitable[AnyType]], *, timeout: float | None = None ) -> Iterator[Awaitable[AnyType]]: """Return an iterator whose values are coroutines. @@ -5048,10 +5012,10 @@ def as_completed( if asyncio.isfuture(fs) or asyncio.iscoroutine(fs): raise TypeError(f"expect an iterable of futures, not {type(fs).__name__}") - done: asyncio.Queue[Optional[asyncio.Future]] = asyncio.Queue() + done: asyncio.Queue[asyncio.Future | None] = asyncio.Queue() loop = asyncio.get_event_loop() - todo: List[asyncio.Future] = [asyncio.ensure_future(f, loop=loop) for f in list(fs)] + todo: list[asyncio.Future] = [asyncio.ensure_future(f, loop=loop) for f in list(fs)] timeout_handle = None def _on_timeout(): @@ -5093,26 +5057,26 @@ async def _wait_for_one(): async def wait( # type: ignore[misc] fs: Iterable[_FT], *, - timeout: Optional[float] = None, + timeout: float | None = None, return_when: str = asyncio.ALL_COMPLETED, -) -> Tuple[List[_FT], List[_FT]]: ... +) -> tuple[list[_FT], list[_FT]]: ... @overload async def wait( fs: Iterable[asyncio.Task[AnyType]], *, - timeout: Optional[float] = None, + timeout: float | None = None, return_when: str = asyncio.ALL_COMPLETED, -) -> Tuple[List[asyncio.Task[AnyType]], List[asyncio.Task[AnyType]]]: ... +) -> tuple[list[asyncio.Task[AnyType]], list[asyncio.Task[AnyType]]]: ... async def wait( fs: Iterable, *, - timeout: Optional[float] = None, + timeout: float | None = None, return_when: str = asyncio.ALL_COMPLETED, -) -> Tuple: +) -> tuple: """Wait for the Futures or Tasks given by fs to complete. This is a deterministic version of :py:func:`asyncio.wait`. This function @@ -5143,11 +5107,11 @@ async def wait( async def _wait( - fs: Iterable[Union[asyncio.Future, asyncio.Task]], - timeout: Optional[float], + fs: Iterable[asyncio.Future | asyncio.Task], + timeout: float | None, return_when: str, loop: asyncio.AbstractEventLoop, -) -> Tuple[List, List]: +) -> tuple[list, list]: # Taken almost verbatim from # https://github.com/python/cpython/blob/v3.12.3/Lib/asyncio/tasks.py#L522 # but the "set" is changed out for a "list" and fixed up some typing/format @@ -5201,7 +5165,7 @@ def _release_waiter(waiter: asyncio.Future[Any], *args) -> None: waiter.set_result(None) -def _is_unbound_method_on_cls(fn: Callable[..., Any], cls: Type) -> bool: +def _is_unbound_method_on_cls(fn: Callable[..., Any], cls: type) -> bool: # Python 3 does not make this easy, ref https://stackoverflow.com/questions/3589311 return ( inspect.isfunction(fn) @@ -5347,7 +5311,7 @@ async def start_operation( operation: nexusrpc.Operation[InputT, OutputT], input: InputT, *, - output_type: Type[OutputT] | None = None, + output_type: type[OutputT] | None = None, schedule_to_close_timeout: timedelta | None = None, cancellation_type: NexusOperationCancellationType = NexusOperationCancellationType.WAIT_COMPLETED, headers: Mapping[str, str] | None = None, @@ -5362,7 +5326,7 @@ async def start_operation( operation: str, input: Any, *, - output_type: Type[OutputT] | None = None, + output_type: type[OutputT] | None = None, schedule_to_close_timeout: timedelta | None = None, cancellation_type: NexusOperationCancellationType = NexusOperationCancellationType.WAIT_COMPLETED, headers: Mapping[str, str] | None = None, @@ -5380,7 +5344,7 @@ async def start_operation( ], input: InputT, *, - output_type: Type[OutputT] | None = None, + output_type: type[OutputT] | None = None, schedule_to_close_timeout: timedelta | None = None, cancellation_type: NexusOperationCancellationType = NexusOperationCancellationType.WAIT_COMPLETED, headers: Mapping[str, str] | None = None, @@ -5398,7 +5362,7 @@ async def start_operation( ], input: InputT, *, - output_type: Type[OutputT] | None = None, + output_type: type[OutputT] | None = None, schedule_to_close_timeout: timedelta | None = None, cancellation_type: NexusOperationCancellationType = NexusOperationCancellationType.WAIT_COMPLETED, headers: Mapping[str, str] | None = None, @@ -5416,7 +5380,7 @@ async def start_operation( ], input: InputT, *, - output_type: Type[OutputT] | None = None, + output_type: type[OutputT] | None = None, schedule_to_close_timeout: timedelta | None = None, cancellation_type: NexusOperationCancellationType = NexusOperationCancellationType.WAIT_COMPLETED, headers: Mapping[str, str] | None = None, @@ -5433,7 +5397,7 @@ async def start_operation( ], input: InputT, *, - output_type: Type[OutputT] | None = None, + output_type: type[OutputT] | None = None, schedule_to_close_timeout: timedelta | None = None, cancellation_type: NexusOperationCancellationType = NexusOperationCancellationType.WAIT_COMPLETED, headers: Mapping[str, str] | None = None, @@ -5446,7 +5410,7 @@ async def start_operation( operation: Any, input: Any, *, - output_type: Type[OutputT] | None = None, + output_type: type[OutputT] | None = None, schedule_to_close_timeout: timedelta | None = None, cancellation_type: NexusOperationCancellationType = NexusOperationCancellationType.WAIT_COMPLETED, headers: Mapping[str, str] | None = None, @@ -5477,7 +5441,7 @@ async def execute_operation( operation: nexusrpc.Operation[InputT, OutputT], input: InputT, *, - output_type: Type[OutputT] | None = None, + output_type: type[OutputT] | None = None, schedule_to_close_timeout: timedelta | None = None, cancellation_type: NexusOperationCancellationType = NexusOperationCancellationType.WAIT_COMPLETED, headers: Mapping[str, str] | None = None, @@ -5492,7 +5456,7 @@ async def execute_operation( operation: str, input: Any, *, - output_type: Type[OutputT] | None = None, + output_type: type[OutputT] | None = None, schedule_to_close_timeout: timedelta | None = None, cancellation_type: NexusOperationCancellationType = NexusOperationCancellationType.WAIT_COMPLETED, headers: Mapping[str, str] | None = None, @@ -5510,7 +5474,7 @@ async def execute_operation( ], input: InputT, *, - output_type: Type[OutputT] | None = None, + output_type: type[OutputT] | None = None, schedule_to_close_timeout: timedelta | None = None, cancellation_type: NexusOperationCancellationType = NexusOperationCancellationType.WAIT_COMPLETED, headers: Mapping[str, str] | None = None, @@ -5531,7 +5495,7 @@ async def execute_operation( ], input: InputT, *, - output_type: Type[OutputT] | None = None, + output_type: type[OutputT] | None = None, schedule_to_close_timeout: timedelta | None = None, cancellation_type: NexusOperationCancellationType = NexusOperationCancellationType.WAIT_COMPLETED, headers: Mapping[str, str] | None = None, @@ -5549,7 +5513,7 @@ async def execute_operation( ], input: InputT, *, - output_type: Type[OutputT] | None = None, + output_type: type[OutputT] | None = None, schedule_to_close_timeout: timedelta | None = None, cancellation_type: NexusOperationCancellationType = NexusOperationCancellationType.WAIT_COMPLETED, headers: Mapping[str, str] | None = None, @@ -5567,7 +5531,7 @@ async def execute_operation( ], input: InputT, *, - output_type: Type[OutputT] | None = None, + output_type: type[OutputT] | None = None, schedule_to_close_timeout: timedelta | None = None, cancellation_type: NexusOperationCancellationType = NexusOperationCancellationType.WAIT_COMPLETED, headers: Mapping[str, str] | None = None, @@ -5580,7 +5544,7 @@ async def execute_operation( operation: Any, input: Any, *, - output_type: Type[OutputT] | None = None, + output_type: type[OutputT] | None = None, schedule_to_close_timeout: timedelta | None = None, cancellation_type: NexusOperationCancellationType = NexusOperationCancellationType.WAIT_COMPLETED, headers: Mapping[str, str] | None = None, @@ -5606,7 +5570,7 @@ def __init__( self, *, endpoint: str, - service: Union[Type[ServiceT], str], + service: type[ServiceT] | str, ) -> None: """Create a Nexus client. @@ -5633,7 +5597,7 @@ async def start_operation( operation: Any, input: Any, *, - output_type: Type[OutputT] | None = None, + output_type: type[OutputT] | None = None, schedule_to_close_timeout: timedelta | None = None, cancellation_type: NexusOperationCancellationType = NexusOperationCancellationType.WAIT_COMPLETED, headers: Mapping[str, str] | None = None, @@ -5658,7 +5622,7 @@ async def execute_operation( operation: Any, input: Any, *, - output_type: Type[OutputT] | None = None, + output_type: type[OutputT] | None = None, schedule_to_close_timeout: timedelta | None = None, cancellation_type: NexusOperationCancellationType = NexusOperationCancellationType.WAIT_COMPLETED, headers: Mapping[str, str] | None = None, @@ -5679,7 +5643,7 @@ async def execute_operation( @overload def create_nexus_client( *, - service: Type[ServiceT], + service: type[ServiceT], endpoint: str, ) -> NexusClient[ServiceT]: ... @@ -5694,7 +5658,7 @@ def create_nexus_client( def create_nexus_client( *, - service: Union[Type[ServiceT], str], + service: type[ServiceT] | str, endpoint: str, ) -> NexusClient[ServiceT]: """Create a Nexus client. diff --git a/tests/api/test_grpc_stub.py b/tests/api/test_grpc_stub.py index 642d11dbe..86a90a453 100644 --- a/tests/api/test_grpc_stub.py +++ b/tests/api/test_grpc_stub.py @@ -1,6 +1,7 @@ import re +from collections.abc import Mapping from datetime import timedelta -from typing import Any, Mapping, Union, cast +from typing import Any, Union, cast import pytest from google.protobuf.empty_pb2 import Empty @@ -38,9 +39,9 @@ def assert_time_remaining(context: ServicerContext, expected: int) -> None: class SimpleWorkflowServer(WorkflowServiceServicer): def __init__(self) -> None: super().__init__() - self.last_metadata: Mapping[str, Union[str, bytes]] = {} + self.last_metadata: Mapping[str, str | bytes] = {} - def assert_last_metadata(self, expected: Mapping[str, Union[str, bytes]]) -> None: + def assert_last_metadata(self, expected: Mapping[str, str | bytes]) -> None: for k, v in expected.items(): assert self.last_metadata.get(k) == v diff --git a/tests/bridge/test_runtime.py b/tests/bridge/test_runtime.py index af9c7006d..de6622f04 100644 --- a/tests/bridge/test_runtime.py +++ b/tests/bridge/test_runtime.py @@ -11,7 +11,7 @@ class SomeException(Exception): def test_bridge_runtime_raise_in_thread(): waiting = Event() - exc_in_thread: Optional[BaseException] = None + exc_in_thread: BaseException | None = None def wait_forever(): try: diff --git a/tests/conftest.py b/tests/conftest.py index d45e85e14..d67bdf22d 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -2,7 +2,7 @@ import multiprocessing.context import os import sys -from typing import AsyncGenerator, Iterator +from collections.abc import AsyncGenerator, Iterator import pytest import pytest_asyncio diff --git a/tests/contrib/openai_agents/test_openai.py b/tests/contrib/openai_agents/test_openai.py index 02183d121..381a213cd 100644 --- a/tests/contrib/openai_agents/test_openai.py +++ b/tests/contrib/openai_agents/test_openai.py @@ -3,14 +3,12 @@ import os import sys import uuid +from collections.abc import AsyncIterator, Callable, Sequence from dataclasses import dataclass from datetime import timedelta from typing import ( Any, - AsyncIterator, - Callable, Optional, - Sequence, Union, cast, ) @@ -794,10 +792,10 @@ async def test_agents_as_tools_workflow(client: Client, use_local_model: bool): class AirlineAgentContext(BaseModel): - passenger_name: Optional[str] = None - confirmation_number: Optional[str] = None - seat_number: Optional[str] = None - flight_number: Optional[str] = None + passenger_name: str | None = None + confirmation_number: str | None = None + seat_number: str | None = None + flight_number: str | None = None @function_tool( @@ -1131,16 +1129,16 @@ def __init__( async def get_response( self, - system_instructions: Union[str, None], - input: Union[str, list[TResponseInputItem]], + system_instructions: str | None, + input: str | list[TResponseInputItem], model_settings: ModelSettings, tools: list[Tool], - output_schema: Union[AgentOutputSchemaBase, None], + output_schema: AgentOutputSchemaBase | None, handoffs: list[Handoff], tracing: ModelTracing, - previous_response_id: Optional[str] = None, - conversation_id: Optional[str] = None, - prompt: Optional[ResponsePromptParam] = None, + previous_response_id: str | None = None, + conversation_id: str | None = None, + prompt: ResponsePromptParam | None = None, ) -> ModelResponse: if ( system_instructions @@ -1169,7 +1167,7 @@ class MathHomeworkOutput(BaseModel): async def math_guardrail( context: RunContextWrapper[None], agent: Agent, - input: Union[str, list[TResponseInputItem]], + input: str | list[TResponseInputItem], ) -> GuardrailFunctionOutput: """This is an input guardrail function, which happens to call an agent to check if the input is a math homework question. @@ -1278,7 +1276,7 @@ class MessageOutput(BaseModel): description="Thoughts on how to respond to the user's message" ) response: str = Field(description="The response to the user's message") - user_name: Optional[str] = Field( + user_name: str | None = Field( description="The name of the user who sent the message, if known" ) model_config = ConfigDict(extra="forbid") @@ -1479,7 +1477,7 @@ async def test_exception_handling(client: Client): class CustomModelProvider(ModelProvider): - def get_model(self, model_name: Optional[str]) -> Model: + def get_model(self, model_name: str | None) -> Model: client = AsyncOpenAI(base_url="https://api.openai.com/v1") return OpenAIChatCompletionsModel(model="gpt-4o", openai_client=client) @@ -1512,11 +1510,11 @@ async def test_chat_completions_model(client: Client): class WaitModel(Model): async def get_response( self, - system_instructions: Union[str, None], - input: Union[str, list[TResponseInputItem]], + system_instructions: str | None, + input: str | list[TResponseInputItem], model_settings: ModelSettings, tools: list[Tool], - output_schema: Union[AgentOutputSchemaBase, None], + output_schema: AgentOutputSchemaBase | None, handoffs: list[Handoff], tracing: ModelTracing, **kwargs, @@ -1528,11 +1526,11 @@ async def get_response( def stream_response( self, - system_instructions: Optional[str], - input: Union[str, list[TResponseInputItem]], + system_instructions: str | None, + input: str | list[TResponseInputItem], model_settings: ModelSettings, tools: list[Tool], - output_schema: Optional[AgentOutputSchemaBase], + output_schema: AgentOutputSchemaBase | None, handoffs: list[Handoff], tracing: ModelTracing, **kwargs, @@ -1554,7 +1552,7 @@ async def run(self, prompt: str) -> str: class CheckModelNameProvider(ModelProvider): - def get_model(self, model_name: Optional[str]) -> Model: + def get_model(self, model_name: str | None) -> Model: assert model_name == "test_model" return hello_mock_model() @@ -2035,13 +2033,13 @@ async def test_hosted_mcp_tool(client: Client): class AssertDifferentModelProvider(ModelProvider): - model_names: set[Optional[str]] + model_names: set[str | None] def __init__(self, model: Model): self._model = model self.model_names = set() - def get_model(self, model_name: Union[str, None]) -> Model: + def get_model(self, model_name: str | None) -> Model: self.model_names.add(model_name) return self._model @@ -2136,9 +2134,9 @@ async def test_summary_provider(client: Client): class SummaryProvider(ModelSummaryProvider): def provide( self, - agent: Optional[Agent[Any]], - instructions: Optional[str], - input: Union[str, list[TResponseInputItem]], + agent: Agent[Any] | None, + instructions: str | None, + input: str | list[TResponseInputItem], ) -> str: return "My summary" @@ -2226,7 +2224,7 @@ async def test_output_type(client: Client): @workflow.defn class McpServerWorkflow: @workflow.run - async def run(self, caching: bool, factory_argument: Optional[Any]) -> str: + async def run(self, caching: bool, factory_argument: Any | None) -> str: from agents.mcp import MCPServer server: MCPServer = openai_agents.workflow.stateless_mcp_server( @@ -2246,7 +2244,7 @@ async def run(self, caching: bool, factory_argument: Optional[Any]) -> str: @workflow.defn class McpServerStatefulWorkflow: @workflow.run - async def run(self, timeout: timedelta, factory_argument: Optional[Any]) -> str: + async def run(self, timeout: timedelta, factory_argument: Any | None) -> str: async with openai_agents.workflow.stateful_mcp_server( "HelloServer", config=ActivityConfig( @@ -2308,8 +2306,8 @@ async def cleanup(self): async def list_tools( self, - run_context: Optional[RunContextWrapper[Any]] = None, - agent: Optional[AgentBase] = None, + run_context: RunContextWrapper[Any] | None = None, + agent: AgentBase | None = None, ) -> list[MCPTool]: self.calls.append("list_tools") return [ @@ -2327,7 +2325,7 @@ async def list_tools( ] async def call_tool( - self, tool_name: str, arguments: Optional[dict[str, Any]] + self, tool_name: str, arguments: dict[str, Any] | None ) -> CallToolResult: self.calls.append("call_tool") name = (arguments or {}).get("name") or "John Doe" @@ -2339,7 +2337,7 @@ async def list_prompts(self) -> ListPromptsResult: raise NotImplementedError() async def get_prompt( - self, name: str, arguments: Optional[dict[str, Any]] = None + self, name: str, arguments: dict[str, Any] | None = None ) -> GetPromptResult: raise NotImplementedError() @@ -2366,7 +2364,7 @@ async def test_mcp_server( ) tracking_server = get_tracking_server(name="HelloServer") - server: Union[StatefulMCPServerProvider, StatelessMCPServerProvider] = ( + server: StatefulMCPServerProvider | StatelessMCPServerProvider = ( StatefulMCPServerProvider("HelloServer", lambda _: tracking_server) if stateful else StatelessMCPServerProvider("HelloServer", lambda _: tracking_server) @@ -2451,7 +2449,7 @@ async def test_mcp_server( @pytest.mark.parametrize("stateful", [True, False]) async def test_mcp_server_factory_argument(client: Client, stateful: bool): - def factory(args: Optional[Any]) -> MCPServer: + def factory(args: Any | None) -> MCPServer: print("Invoking factory: ", args) if args is not None: assert args is not None @@ -2459,7 +2457,7 @@ def factory(args: Optional[Any]) -> MCPServer: return get_tracking_server("HelloServer") - server: Union[StatefulMCPServerProvider, StatelessMCPServerProvider] = ( + server: StatefulMCPServerProvider | StatelessMCPServerProvider = ( StatefulMCPServerProvider("HelloServer", factory) if stateful else StatelessMCPServerProvider("HelloServer", factory) diff --git a/tests/contrib/pydantic/activities.py b/tests/contrib/pydantic/activities.py index ad1b86507..4b5a83d5b 100644 --- a/tests/contrib/pydantic/activities.py +++ b/tests/contrib/pydantic/activities.py @@ -8,8 +8,8 @@ @activity.defn async def pydantic_objects_activity( - models: List[PydanticModels], -) -> List[PydanticModels]: + models: list[PydanticModels], +) -> list[PydanticModels]: return models diff --git a/tests/contrib/pydantic/models.py b/tests/contrib/pydantic/models.py index e2fdcfe2c..97e2694db 100644 --- a/tests/contrib/pydantic/models.py +++ b/tests/contrib/pydantic/models.py @@ -1,5 +1,6 @@ import dataclasses import uuid +from collections.abc import Sequence from datetime import date, datetime, time, timedelta, timezone from ipaddress import IPv4Address from pathlib import Path @@ -9,7 +10,6 @@ Dict, Generic, List, - Sequence, Tuple, TypeVar, Union, @@ -114,7 +114,7 @@ class ChildModel(BaseModel): class ParentModel(BaseModel): child: ChildModel - children: List[ChildModel] + children: list[ChildModel] def _check_instance(self) -> None: assert isinstance(self.child, ChildModel) @@ -166,7 +166,7 @@ def make_field_features_object() -> FieldFeaturesModel: class AnnotatedFieldsModel(BaseModel): max_length_str: Annotated[str, Len(max_length=10)] - custom_json: Annotated[Dict[str, Any], WithJsonSchema({"extra": "data"})] + custom_json: Annotated[dict[str, Any], WithJsonSchema({"extra": "data"})] def _check_instance(self) -> None: assert isinstance(self.max_length_str, str) @@ -188,7 +188,7 @@ def make_annotated_fields_object() -> AnnotatedFieldsModel: class GenericModel(BaseModel, Generic[T]): value: T - values: List[T] + values: list[T] def _check_instance(self) -> None: assert isinstance(self.value, str) @@ -206,8 +206,8 @@ def make_generic_string_object() -> GenericModel[str]: class UnionModel(BaseModel): - simple_union_field: Union[str, int] - proxied_union_field: Union[datetime, Path] + simple_union_field: str | int + proxied_union_field: datetime | Path def _check_instance(self) -> None: assert isinstance(self.simple_union_field, str) @@ -231,9 +231,9 @@ class PydanticDatetimeModel(BaseModel): ) annotated_datetime: Annotated[datetime, Field(), WithJsonSchema({"extra": "data"})] annotated_list_of_datetime: Annotated[ - List[datetime], Field(), WithJsonSchema({"extra": "data"}) + list[datetime], Field(), WithJsonSchema({"extra": "data"}) ] - datetime_short_sequence: ShortSequence[List[datetime]] + datetime_short_sequence: ShortSequence[list[datetime]] def _check_instance(self): _assert_datetime_validity(self.datetime_field) @@ -275,9 +275,9 @@ class PydanticDateModel(BaseModel): date_field_with_default: date = Field(default_factory=lambda: date(2000, 1, 2)) annotated_date: Annotated[date, Field(), WithJsonSchema({"extra": "data"})] annotated_list_of_date: Annotated[ - List[date], Field(), WithJsonSchema({"extra": "data"}) + list[date], Field(), WithJsonSchema({"extra": "data"}) ] - date_short_sequence: ShortSequence[List[date]] + date_short_sequence: ShortSequence[list[date]] def _check_instance(self): _assert_date_validity(self.date_field) @@ -317,9 +317,9 @@ class PydanticTimedeltaModel(BaseModel): timedelta, Field(), WithJsonSchema({"extra": "data"}) ] annotated_list_of_timedelta: Annotated[ - List[timedelta], Field(), WithJsonSchema({"extra": "data"}) + list[timedelta], Field(), WithJsonSchema({"extra": "data"}) ] - timedelta_short_sequence: ShortSequence[List[timedelta]] + timedelta_short_sequence: ShortSequence[list[timedelta]] def _check_instance(self): _assert_timedelta_validity(self.timedelta_field) @@ -387,7 +387,7 @@ def _assert_timedelta_validity(td: timedelta): ] -def make_list_of_pydantic_objects() -> List[PydanticModels]: +def make_list_of_pydantic_objects() -> list[PydanticModels]: objects = [ make_standard_types_object(), make_strict_standard_types_object(), @@ -414,12 +414,12 @@ class MyDataClass: data_class_int_field: int -def make_dataclass_objects() -> List[MyDataClass]: +def make_dataclass_objects() -> list[MyDataClass]: return [MyDataClass(data_class_int_field=7)] -ComplexCustomType = Tuple[List[MyDataClass], List[PydanticModels]] -ComplexCustomUnionType = List[Union[MyDataClass, PydanticModels]] +ComplexCustomType = tuple[list[MyDataClass], list[PydanticModels]] +ComplexCustomUnionType = list[Union[MyDataClass, PydanticModels]] class PydanticModelWithStrictField(BaseModel): diff --git a/tests/contrib/pydantic/models_2.py b/tests/contrib/pydantic/models_2.py index 2c9520b32..decec56df 100644 --- a/tests/contrib/pydantic/models_2.py +++ b/tests/contrib/pydantic/models_2.py @@ -2,16 +2,15 @@ import decimal import fractions import re +from collections.abc import Hashable, Sequence from enum import Enum, IntEnum +from re import Pattern from typing import ( Any, Dict, - Hashable, List, NamedTuple, Optional, - Pattern, - Sequence, Set, Tuple, Union, @@ -214,12 +213,12 @@ class Point(NamedTuple): class ComplexTypesModel(BaseModel): - list_field: List[str] - dict_field: Dict[str, int] - set_field: Set[int] - tuple_field: Tuple[str, int] - union_field: Union[str, int] - optional_field: Optional[str] + list_field: list[str] + dict_field: dict[str, int] + set_field: set[int] + tuple_field: tuple[str, int] + union_field: str | int + optional_field: str | None named_tuple_field: Point def _check_instance(self) -> None: diff --git a/tests/contrib/pydantic/workflows.py b/tests/contrib/pydantic/workflows.py index a4d656b20..d67e7db42 100644 --- a/tests/contrib/pydantic/workflows.py +++ b/tests/contrib/pydantic/workflows.py @@ -22,7 +22,7 @@ ) -def clone_objects(objects: List[PydanticModels]) -> List[PydanticModels]: +def clone_objects(objects: list[PydanticModels]) -> list[PydanticModels]: new_objects = [] for o in objects: fields = {} @@ -45,7 +45,7 @@ async def run(self) -> None: @workflow.defn class RoundTripPydanticObjectsWorkflow: @workflow.run - async def run(self, objects: List[PydanticModels]) -> List[PydanticModels]: + async def run(self, objects: list[PydanticModels]) -> list[PydanticModels]: return await workflow.execute_activity( pydantic_objects_activity, objects, @@ -86,7 +86,7 @@ async def run( @workflow.defn class CloneObjectsWorkflow: @workflow.run - async def run(self, objects: List[PydanticModels]) -> List[PydanticModels]: + async def run(self, objects: list[PydanticModels]) -> list[PydanticModels]: return clone_objects(objects) @@ -98,7 +98,7 @@ async def run( input: ComplexCustomUnionType, ) -> ComplexCustomUnionType: data_classes = [] - pydantic_objects: List[PydanticModels] = [] + pydantic_objects: list[PydanticModels] = [] for o in input: if dataclasses.is_dataclass(o): data_classes.append(o) diff --git a/tests/contrib/test_opentelemetry.py b/tests/contrib/test_opentelemetry.py index fb4759be9..0308da2b8 100644 --- a/tests/contrib/test_opentelemetry.py +++ b/tests/contrib/test_opentelemetry.py @@ -6,11 +6,12 @@ import queue import threading import uuid +from collections.abc import Callable, Generator, Iterable from concurrent.futures import ThreadPoolExecutor from contextlib import contextmanager from dataclasses import dataclass from datetime import timedelta -from typing import Callable, Dict, Generator, Iterable, List, Optional, cast +from typing import Dict, List, Optional, cast import opentelemetry.context import pytest @@ -37,7 +38,7 @@ @dataclass class TracingActivityParam: heartbeat: bool = True - fail_until_attempt: Optional[int] = None + fail_until_attempt: int | None = None @activity.defn @@ -50,15 +51,15 @@ async def tracing_activity(param: TracingActivityParam) -> None: @dataclass class TracingWorkflowParam: - actions: List[TracingWorkflowAction] + actions: list[TracingWorkflowAction] @dataclass class TracingWorkflowAction: fail_on_non_replay: bool = False - child_workflow: Optional[TracingWorkflowActionChildWorkflow] = None - activity: Optional[TracingWorkflowActionActivity] = None - continue_as_new: Optional[TracingWorkflowActionContinueAsNew] = None + child_workflow: TracingWorkflowActionChildWorkflow | None = None + activity: TracingWorkflowActionActivity | None = None + continue_as_new: TracingWorkflowActionContinueAsNew | None = None wait_until_signal_count: int = 0 wait_and_do_update: bool = False wait_and_do_start_with_update: bool = False @@ -413,11 +414,11 @@ async def test_opentelemetry_tracing_update_with_start( def dump_spans( spans: Iterable[ReadableSpan], *, - parent_id: Optional[int] = None, + parent_id: int | None = None, with_attributes: bool = True, indent_depth: int = 0, -) -> List[str]: - ret: List[str] = [] +) -> list[str]: + ret: list[str] = [] for span in spans: if (not span.parent and parent_id is None) or ( span.parent and span.parent.span_id == parent_id @@ -427,7 +428,7 @@ def dump_spans( span_str += f" (attributes: {dict(span.attributes or {})})" # Add links if span.links: - span_links: List[str] = [] + span_links: list[str] = [] for link in span.links: for link_span in spans: if ( @@ -555,7 +556,7 @@ async def test_opentelemetry_benign_exception(client: Client): @contextmanager -def baggage_values(values: Dict[str, str]) -> Generator[None, None, None]: +def baggage_values(values: dict[str, str]) -> Generator[None]: ctx = context.get_current() for key, value in values.items(): ctx = baggage.set_baggage(key, value, context=ctx) @@ -580,7 +581,7 @@ def get_baggage_value(key: str) -> str: @activity.defn -async def read_baggage_activity() -> Dict[str, str]: +async def read_baggage_activity() -> dict[str, str]: return { "user_id": get_baggage_value("user.id"), "tenant_id": get_baggage_value("tenant.id"), @@ -590,7 +591,7 @@ async def read_baggage_activity() -> Dict[str, str]: @workflow.defn class ReadBaggageTestWorkflow: @workflow.run - async def run(self) -> Dict[str, str]: + async def run(self) -> dict[str, str]: return await workflow.execute_activity( read_baggage_activity, start_to_close_timeout=timedelta(seconds=10), @@ -623,9 +624,9 @@ async def test_opentelemetry_baggage_propagation_basic( @activity.defn -async def read_baggage_local_activity() -> Dict[str, str]: +async def read_baggage_local_activity() -> dict[str, str]: return cast( - Dict[str, str], + dict[str, str], { "user_id": get_baggage_value("user.id"), "tenant_id": get_baggage_value("tenant.id"), @@ -636,7 +637,7 @@ async def read_baggage_local_activity() -> Dict[str, str]: @workflow.defn class LocalActivityBaggageTestWorkflow: @workflow.run - async def run(self) -> Dict[str, str]: + async def run(self) -> dict[str, str]: return await workflow.execute_local_activity( read_baggage_local_activity, start_to_close_timeout=timedelta(seconds=10), @@ -669,7 +670,7 @@ async def test_opentelemetry_baggage_propagation_local_activity( assert result["tenant_id"] == "local-corp" -retry_attempt_baggage_values: List[str] = [] +retry_attempt_baggage_values: list[str] = [] @activity.defn diff --git a/tests/helpers/__init__.py b/tests/helpers/__init__.py index 4a3850024..09bc61b45 100644 --- a/tests/helpers/__init__.py +++ b/tests/helpers/__init__.py @@ -5,16 +5,14 @@ import socket import time import uuid +from collections.abc import Awaitable, Callable, Sequence from contextlib import closing, contextmanager from dataclasses import dataclass from datetime import datetime, timedelta, timezone from typing import ( Any, - Awaitable, - Callable, List, Optional, - Sequence, Type, TypeVar, Union, @@ -49,12 +47,12 @@ def new_worker( client: Client, - *workflows: Type, + *workflows: type, activities: Sequence[Callable] = [], - task_queue: Optional[str] = None, + task_queue: str | None = None, workflow_runner: WorkflowRunner = SandboxedWorkflowRunner(), max_cached_workflows: int = 1000, - workflow_failure_exception_types: Sequence[Type[BaseException]] = [], + workflow_failure_exception_types: Sequence[type[BaseException]] = [], **kwargs, ) -> Worker: return Worker( @@ -103,7 +101,7 @@ async def check() -> None: async def assert_task_fail_eventually( - handle: WorkflowHandle, *, message_contains: Optional[str] = None + handle: WorkflowHandle, *, message_contains: str | None = None ) -> None: async def check() -> None: async for evt in handle.fetch_history_events(): @@ -139,7 +137,7 @@ async def ensure_search_attributes_present( resp = await client.operator_service.list_search_attributes( ListSearchAttributesRequest(namespace=client.namespace) ) - if not set(key.name for key in keys).issubset(resp.custom_attributes.keys()): + if not {key.name for key in keys}.issubset(resp.custom_attributes.keys()): await client.operator_service.add_search_attributes( AddSearchAttributesRequest( namespace=client.namespace, @@ -153,7 +151,7 @@ async def ensure_search_attributes_present( resp = await client.operator_service.list_search_attributes( ListSearchAttributesRequest(namespace=client.namespace) ) - assert set(key.name for key in keys).issubset(resp.custom_attributes.keys()) + assert {key.name for key in keys}.issubset(resp.custom_attributes.keys()) def find_free_port() -> int: @@ -256,7 +254,7 @@ async def check() -> PendingActivityInfo: async def get_pending_activity_info( handle: WorkflowHandle, activity_id: str, -) -> Optional[PendingActivityInfo]: +) -> PendingActivityInfo | None: """Get pending activity info by ID, or None if not found.""" desc = await handle.describe() for act in desc.raw_description.pending_activities: @@ -318,14 +316,14 @@ async def print_history(handle: WorkflowHandle): @dataclass class InterleavedHistoryEvent: handle: WorkflowHandle - event: Union[HistoryEvent, str] - number: Optional[int] + event: HistoryEvent | str + number: int | None time: datetime async def print_interleaved_histories( handles: list[WorkflowHandle], - extra_events: Optional[list[tuple[WorkflowHandle, str, datetime]]] = None, + extra_events: list[tuple[WorkflowHandle, str, datetime]] | None = None, ) -> None: """ Print the interleaved history events from multiple workflow handles in columns. @@ -436,13 +434,13 @@ def logs_captured(self, *loggers: logging.Logger): l.removeHandler(handler) l.setLevel(prev_levels[i]) - def find_log(self, starts_with: str) -> Optional[logging.LogRecord]: + def find_log(self, starts_with: str) -> logging.LogRecord | None: return self.find(lambda l: l.message.startswith(starts_with)) def find( self, pred: Callable[[logging.LogRecord], bool] - ) -> Optional[logging.LogRecord]: - for record in cast(List[logging.LogRecord], self.log_queue.queue): + ) -> logging.LogRecord | None: + for record in cast(list[logging.LogRecord], self.log_queue.queue): if pred(record): return record return None diff --git a/tests/helpers/external_coroutine.py b/tests/helpers/external_coroutine.py index 511db1ae3..72fa8f25a 100644 --- a/tests/helpers/external_coroutine.py +++ b/tests/helpers/external_coroutine.py @@ -7,12 +7,12 @@ from temporalio import workflow -async def never_completing_coroutine(status: List[str]) -> None: +async def never_completing_coroutine(status: list[str]) -> None: status[0] = "waiting" # external coroutine test await workflow.wait_condition(lambda: False) -async def wait_on_timer(status: List[str]) -> None: +async def wait_on_timer(status: list[str]) -> None: status[0] = "waiting" # multifile test print("Coroutine executed, waiting.") await workflow.wait_condition(lambda: False) diff --git a/tests/helpers/nexus.py b/tests/helpers/nexus.py index 6e8c62e59..63dde9621 100644 --- a/tests/helpers/nexus.py +++ b/tests/helpers/nexus.py @@ -1,6 +1,7 @@ import dataclasses +from collections.abc import Mapping from dataclasses import dataclass -from typing import Any, Mapping, Optional +from typing import Any, Optional from urllib.parse import urlparse import temporalio.api.failure.v1 @@ -51,7 +52,7 @@ class ServiceClient: async def start_operation( self, operation: str, - body: Optional[dict[str, Any]] = None, + body: dict[str, Any] | None = None, headers: Mapping[str, str] = {}, ) -> httpx.Response: """ @@ -107,10 +108,10 @@ class Failure: """ message: str = "" - metadata: Optional[dict[str, str]] = None - details: Optional[dict[str, Any]] = None + metadata: dict[str, str] | None = None + details: dict[str, Any] | None = None - exception_from_details: Optional[BaseException] = dataclasses.field( + exception_from_details: BaseException | None = dataclasses.field( init=False, default=None ) @@ -121,7 +122,7 @@ def __post_init__(self) -> None: ) def _instantiate_exception( - self, error_type: str, details: Optional[dict[str, Any]] + self, error_type: str, details: dict[str, Any] | None ) -> BaseException: proto = { "temporal.api.failure.v1.Failure": temporalio.api.failure.v1.Failure, diff --git a/tests/helpers/worker.py b/tests/helpers/worker.py index e6df0a851..5c6e6898c 100644 --- a/tests/helpers/worker.py +++ b/tests/helpers/worker.py @@ -9,9 +9,10 @@ import asyncio import uuid from abc import ABC, abstractmethod +from collections.abc import Sequence from dataclasses import dataclass from datetime import timedelta -from typing import Any, Optional, Sequence, Tuple +from typing import Any, Optional, Tuple import temporalio.converter from temporalio import workflow @@ -23,32 +24,32 @@ @dataclass class KSWorkflowParams: - actions: Optional[Sequence[KSAction]] = None - action_signal: Optional[str] = None + actions: Sequence[KSAction] | None = None + action_signal: str | None = None @dataclass class KSAction: - result: Optional[KSResultAction] = None - error: Optional[KSErrorAction] = None - continue_as_new: Optional[KSContinueAsNewAction] = None - sleep: Optional[KSSleepAction] = None - query_handler: Optional[KSQueryHandlerAction] = None - signal: Optional[KSSignalAction] = None - execute_activity: Optional[KSExecuteActivityAction] = None + result: KSResultAction | None = None + error: KSErrorAction | None = None + continue_as_new: KSContinueAsNewAction | None = None + sleep: KSSleepAction | None = None + query_handler: KSQueryHandlerAction | None = None + signal: KSSignalAction | None = None + execute_activity: KSExecuteActivityAction | None = None @dataclass class KSResultAction: - value: Optional[Any] = None - run_id: Optional[bool] = None + value: Any | None = None + run_id: bool | None = None @dataclass class KSErrorAction: - message: Optional[str] = None - details: Optional[Any] = None - attempt: Optional[bool] = None + message: str | None = None + details: Any | None = None + attempt: bool | None = None @dataclass @@ -74,18 +75,18 @@ class KSSignalAction: @dataclass class KSExecuteActivityAction: name: str - task_queue: Optional[str] = None - args: Optional[Sequence[Any]] = None - count: Optional[int] = None - index_as_arg: Optional[bool] = None - schedule_to_close_timeout_ms: Optional[int] = None - start_to_close_timeout_ms: Optional[int] = None - schedule_to_start_timeout_ms: Optional[int] = None - cancel_after_ms: Optional[int] = None - wait_for_cancellation: Optional[bool] = None - heartbeat_timeout_ms: Optional[int] = None - retry_max_attempts: Optional[int] = None - non_retryable_error_types: Optional[Sequence[str]] = None + task_queue: str | None = None + args: Sequence[Any] | None = None + count: int | None = None + index_as_arg: bool | None = None + schedule_to_close_timeout_ms: int | None = None + start_to_close_timeout_ms: int | None = None + schedule_to_start_timeout_ms: int | None = None + cancel_after_ms: int | None = None + wait_for_cancellation: bool | None = None + heartbeat_timeout_ms: int | None = None + retry_max_attempts: int | None = None + non_retryable_error_types: Sequence[str] | None = None @workflow.defn(name="kitchen_sink") @@ -110,7 +111,7 @@ async def run(self, params: KSWorkflowParams) -> Any: async def handle_action( self, params: KSWorkflowParams, action: KSAction - ) -> Tuple[bool, Any]: + ) -> tuple[bool, Any]: if action.result: if action.result.run_id: return (True, workflow.info().run_id) @@ -131,7 +132,7 @@ async def handle_action( elif action.signal: signal_event = asyncio.Event() - def signal_handler(arg: Optional[Any] = None) -> None: + def signal_handler(arg: Any | None = None) -> None: signal_event.set() workflow.set_signal_handler(action.signal.name, signal_handler) @@ -205,8 +206,8 @@ async def run_activity(index: int) -> None: def kitchen_sink_retry_policy( - maximum_attempts: Optional[int] = None, - non_retryable_error_types: Optional[Sequence[str]] = None, + maximum_attempts: int | None = None, + non_retryable_error_types: Sequence[str] | None = None, ) -> RetryPolicy: return RetryPolicy( initial_interval=timedelta(milliseconds=1), diff --git a/tests/nexus/test_handler.py b/tests/nexus/test_handler.py index 7ce0149f9..2bb10ae43 100644 --- a/tests/nexus/test_handler.py +++ b/tests/nexus/test_handler.py @@ -18,11 +18,11 @@ import logging import pprint import uuid -from collections.abc import Mapping +from collections.abc import Callable, Mapping from concurrent.futures.thread import ThreadPoolExecutor from dataclasses import dataclass, field from types import MappingProxyType -from typing import Any, Callable, Optional, Union +from typing import Any, Optional, Union import httpx import nexusrpc @@ -297,7 +297,7 @@ async def non_serializable_output( @dataclass class SuccessfulResponse: status_code: int - body_json: Optional[Union[dict[str, Any], Callable[[dict[str, Any]], bool]]] = None + body_json: dict[str, Any] | Callable[[dict[str, Any]], bool] | None = None headers: Mapping[str, str] = field( default_factory=lambda: SUCCESSFUL_RESPONSE_HEADERS ) @@ -306,12 +306,12 @@ class SuccessfulResponse: @dataclass class UnsuccessfulResponse: status_code: int - failure_message: Union[str, Callable[[str], bool]] + failure_message: str | Callable[[str], bool] # Is the Nexus Failure expected to have the details field populated? failure_details: bool = True # Expected value of inverse of non_retryable attribute of exception. retryable_exception: bool = True - body_json: Optional[Callable[[dict[str, Any]], bool]] = None + body_json: Callable[[dict[str, Any]], bool] | None = None headers: Mapping[str, str] = field( default_factory=lambda: UNSUCCESSFUL_RESPONSE_HEADERS ) @@ -323,7 +323,7 @@ class _TestCase: input: Input = Input("") headers: dict[str, str] = {} expected: SuccessfulResponse - expected_without_service_definition: Optional[SuccessfulResponse] = None + expected_without_service_definition: SuccessfulResponse | None = None skip = "" @classmethod @@ -824,8 +824,8 @@ async def test_logger_uses_operation_context(env: WorkflowEnvironment, caplog: A class _InstantiationCase: executor: bool handler: Callable[..., Any] - exception: Optional[type[Exception]] - match: Optional[str] + exception: type[Exception] | None + match: str | None @nexusrpc.service diff --git a/tests/nexus/test_handler_async_operation.py b/tests/nexus/test_handler_async_operation.py index bf8099491..76aef59f6 100644 --- a/tests/nexus/test_handler_async_operation.py +++ b/tests/nexus/test_handler_async_operation.py @@ -104,10 +104,9 @@ def async_operation(self) -> OperationHandler[Input, Output]: ) async def test_async_operation_lifecycle( env: WorkflowEnvironment, - service_handler_cls: Union[ - Type[MyServiceHandlerWithAsyncDefs], - Type[MyServiceHandlerWithNonAsyncDefs], - ], + service_handler_cls: ( + type[MyServiceHandlerWithAsyncDefs] | type[MyServiceHandlerWithNonAsyncDefs] + ), ): if env.supports_time_skipping: pytest.skip("Nexus tests don't work with time-skipping server") diff --git a/tests/nexus/test_handler_interface_implementation.py b/tests/nexus/test_handler_interface_implementation.py index d51d58dca..58a139ad8 100644 --- a/tests/nexus/test_handler_interface_implementation.py +++ b/tests/nexus/test_handler_interface_implementation.py @@ -14,7 +14,7 @@ class _InterfaceImplementationTestCase: Interface: type[Any] Impl: type[Any] - error_message: Optional[str] + error_message: str | None class ValidImpl(_InterfaceImplementationTestCase): diff --git a/tests/nexus/test_handler_operation_definitions.py b/tests/nexus/test_handler_operation_definitions.py index 8e41c1efa..a9e9cb454 100644 --- a/tests/nexus/test_handler_operation_definitions.py +++ b/tests/nexus/test_handler_operation_definitions.py @@ -26,7 +26,7 @@ class Output: @dataclass class _TestCase: - Service: Type[Any] + Service: type[Any] expected_operations: dict[str, nexusrpc.Operation] @@ -90,7 +90,7 @@ async def workflow_run_operation_with_name_override( ) @pytest.mark.asyncio async def test_collected_operation_names( - test_case: Type[_TestCase], + test_case: type[_TestCase], ): service_defn = nexusrpc.get_service_definition(test_case.Service) assert isinstance(service_defn, nexusrpc.ServiceDefinition) diff --git a/tests/nexus/test_use_existing_conflict_policy.py b/tests/nexus/test_use_existing_conflict_policy.py index 03d2894e9..211ed4f5c 100644 --- a/tests/nexus/test_use_existing_conflict_policy.py +++ b/tests/nexus/test_use_existing_conflict_policy.py @@ -25,7 +25,7 @@ class OpInput: @workflow.defn class HandlerWorkflow: def __init__(self) -> None: - self.result: Optional[str] = None + self.result: str | None = None @workflow.run async def run(self) -> str: diff --git a/tests/nexus/test_workflow_caller.py b/tests/nexus/test_workflow_caller.py index 0c0dd988a..b065dc903 100644 --- a/tests/nexus/test_workflow_caller.py +++ b/tests/nexus/test_workflow_caller.py @@ -2,9 +2,10 @@ import asyncio import uuid +from collections.abc import Awaitable, Callable from dataclasses import dataclass from enum import IntEnum -from typing import Any, Awaitable, Callable, Union +from typing import Any, Union import nexusrpc import nexusrpc.handler @@ -141,10 +142,7 @@ async def run( class SyncOrAsyncOperation(OperationHandler[OpInput, OpOutput]): async def start( # type: ignore[override] self, ctx: StartOperationContext, input: OpInput - ) -> Union[ - StartOperationResultSync[OpOutput], - StartOperationResultAsync, - ]: + ) -> StartOperationResultSync[OpOutput] | StartOperationResultAsync: if input.response_type.exception_in_operation_start: raise RPCError( "RPCError INVALID_ARGUMENT in Nexus operation", @@ -291,15 +289,14 @@ async def wait_nexus_operation_start_resolved(self) -> None: @staticmethod def _get_operation( op_input: OpInput, - ) -> Union[ - nexusrpc.Operation[OpInput, OpOutput], - Callable[..., Awaitable[OpOutput]], + ) -> ( + nexusrpc.Operation[OpInput, OpOutput] | Callable[..., Awaitable[OpOutput]] # We are not exposing operation factory methods to users as a way to write nexus # operations, and accordingly the types on NexusClient # start_operation/execute_operation to not permit it. We fake the type by # pretending that this function doesn't return such operations. # Callable[[Any], OperationHandler[OpInput, OpOutput]], - ]: + ): return { # type: ignore[return-value] ( SyncResponse, diff --git a/tests/nexus/test_workflow_caller_cancellation_types.py b/tests/nexus/test_workflow_caller_cancellation_types.py index 0590bb2a6..16cfb8805 100644 --- a/tests/nexus/test_workflow_caller_cancellation_types.py +++ b/tests/nexus/test_workflow_caller_cancellation_types.py @@ -116,7 +116,7 @@ def workflow_op(self) -> nexusrpc.handler.OperationHandler[None, None]: @dataclass class Input: endpoint: str - cancellation_type: Optional[workflow.NexusOperationCancellationType] + cancellation_type: workflow.NexusOperationCancellationType | None @dataclass @@ -134,7 +134,7 @@ def __init__(self, input: Input): endpoint=input.endpoint, ) self.released = False - self.operation_token: Optional[str] = None + self.operation_token: str | None = None self.caller_op_future_resolved: asyncio.Future[datetime] = asyncio.Future() @workflow.signal diff --git a/tests/nexus/test_workflow_caller_cancellation_types_when_cancel_handler_fails.py b/tests/nexus/test_workflow_caller_cancellation_types_when_cancel_handler_fails.py index 12f99a714..c9cb71807 100644 --- a/tests/nexus/test_workflow_caller_cancellation_types_when_cancel_handler_fails.py +++ b/tests/nexus/test_workflow_caller_cancellation_types_when_cancel_handler_fails.py @@ -120,15 +120,15 @@ def workflow_op(self) -> nexusrpc.handler.OperationHandler[None, None]: @dataclass class Input: endpoint: str - cancellation_type: Optional[workflow.NexusOperationCancellationType] + cancellation_type: workflow.NexusOperationCancellationType | None @dataclass class CancellationResult: operation_token: str caller_op_future_resolved: datetime - error_type: Optional[str] = None - error_cause_type: Optional[str] = None + error_type: str | None = None + error_cause_type: str | None = None @workflow.defn(sandboxed=False) @@ -140,7 +140,7 @@ def __init__(self, input: Input): endpoint=input.endpoint, ) self.released = False - self.operation_token: Optional[str] = None + self.operation_token: str | None = None self.caller_op_future_resolved: asyncio.Future[datetime] = asyncio.Future() @workflow.signal diff --git a/tests/nexus/test_workflow_caller_error_chains.py b/tests/nexus/test_workflow_caller_error_chains.py index 3e3c05b0b..4ba9ca6d5 100644 --- a/tests/nexus/test_workflow_caller_error_chains.py +++ b/tests/nexus/test_workflow_caller_error_chains.py @@ -1,8 +1,9 @@ from __future__ import annotations import uuid +from collections.abc import Callable from dataclasses import dataclass -from typing import Any, Callable +from typing import Any import nexusrpc import nexusrpc.handler diff --git a/tests/nexus/test_workflow_run_operation.py b/tests/nexus/test_workflow_run_operation.py index 01850379a..cfbaa91ef 100644 --- a/tests/nexus/test_workflow_run_operation.py +++ b/tests/nexus/test_workflow_run_operation.py @@ -88,7 +88,7 @@ def op(self) -> OperationHandler: ) async def test_workflow_run_operation( env: WorkflowEnvironment, - service_handler_cls: Type[Any], + service_handler_cls: type[Any], ): if env.supports_time_skipping: pytest.skip("Nexus tests don't work with time-skipping server") diff --git a/tests/test_client.py b/tests/test_client.py index 458492ff6..791c59b2d 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -4,8 +4,9 @@ import multiprocessing.context import os import uuid +from collections.abc import Mapping from datetime import datetime, timedelta, timezone -from typing import Any, List, Mapping, Optional, Tuple, Union, cast +from typing import Any, List, Optional, Tuple, Union, cast from unittest import mock import google.protobuf.any_pb2 @@ -310,8 +311,8 @@ async def __call__( req: temporalio.api.workflowservice.v1.StartWorkflowExecutionRequest, *, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.StartWorkflowExecutionResponse: raise self.already_exists_err @@ -661,7 +662,7 @@ async def fetch_count() -> WorkflowExecutionCount: resp = await client.count_workflows( f"TaskQueue = '{worker.task_queue}' GROUP BY ExecutionStatus" ) - cast(List[WorkflowExecutionCountAggregationGroup], resp.groups).sort( + cast(list[WorkflowExecutionCountAggregationGroup], resp.groups).sort( key=lambda g: g.count ) return resp @@ -992,7 +993,7 @@ async def update_desc_get_action_count() -> int: ) expected_ids.append(new_handle.id) - async def list_ids() -> List[str]: + async def list_ids() -> list[str]: return sorted( [ list_desc.id @@ -1222,7 +1223,7 @@ async def test_schedule_workflow_search_attribute_update( # Do update of typed attrs def update_schedule_typed_attrs( input: ScheduleUpdateInput, - ) -> Optional[ScheduleUpdate]: + ) -> ScheduleUpdate | None: assert isinstance( input.description.schedule.action, ScheduleActionStartWorkflow ) @@ -1329,7 +1330,7 @@ async def test_schedule_search_attribute_update( def update_search_attributes( input: ScheduleUpdateInput, - ) -> Optional[ScheduleUpdate]: + ) -> ScheduleUpdate | None: # Make sure the initial search attributes are present assert input.description.search_attributes[key_1.name] == [val_1] assert input.description.search_attributes[key_2.name] == [val_2] @@ -1522,7 +1523,7 @@ async def test_schedule_last_completion_result( ) await handle.trigger() - async def get_schedule_result() -> Tuple[int, Optional[str]]: + async def get_schedule_result() -> tuple[int, str | None]: desc = await handle.describe() length = len(desc.info.recent_actions) if length == 0: diff --git a/tests/test_converter.py b/tests/test_converter.py index a6a292dff..da6fb8d54 100644 --- a/tests/test_converter.py +++ b/tests/test_converter.py @@ -7,6 +7,7 @@ import sys import traceback from collections import deque +from collections.abc import Iterable, Mapping, MutableMapping, Sequence from dataclasses import dataclass from datetime import datetime, timedelta, timezone from enum import Enum, IntEnum @@ -14,14 +15,10 @@ Any, Deque, Dict, - Iterable, List, Literal, - Mapping, - MutableMapping, NewType, Optional, - Sequence, Set, Text, Tuple, @@ -308,9 +305,9 @@ def payload(key, dtype, data, encoding=None): @dataclass class NestedDataClass: foo: str - bar: List[NestedDataClass] = dataclasses.field(default_factory=list) - baz: Optional[NestedDataClass] = None - qux: Optional[UUID] = None + bar: list[NestedDataClass] = dataclasses.field(default_factory=list) + baz: NestedDataClass | None = None + qux: UUID | None = None class MyTypedDict(TypedDict): @@ -328,8 +325,8 @@ class MyTypedDictNotTotal(TypedDict, total=False): class MyPydanticClass(pydantic.BaseModel): foo: str - bar: List[MyPydanticClass] - baz: Optional[UUID] = None + bar: list[MyPydanticClass] + baz: UUID | None = None def test_json_type_hints(): @@ -359,7 +356,7 @@ def fail(hint: Any, value: Any) -> None: ok(float, 5.5) ok(bool, True) ok(str, "foo") - ok(Text, "foo") + ok(str, "foo") ok(bytes, b"foo") fail(int, "1") fail(float, "1") @@ -398,35 +395,34 @@ def fail(hint: Any, value: Any) -> None: ok(Union[int, str], "foo") ok(Union[MyDataClass, NestedDataClass], MyDataClass("foo", 5, SerializableEnum.FOO)) ok(Union[MyDataClass, NestedDataClass], NestedDataClass("foo")) - if sys.version_info >= (3, 10): - ok(int | None, None) - ok(int | None, 5) - fail(int | None, "1") - ok(MyDataClass | NestedDataClass, MyDataClass("foo", 5, SerializableEnum.FOO)) - ok(MyDataClass | NestedDataClass, NestedDataClass("foo")) + ok(int | None, None) + ok(int | None, 5) + fail(int | None, "1") + ok(MyDataClass | NestedDataClass, MyDataClass("foo", 5, SerializableEnum.FOO)) + ok(MyDataClass | NestedDataClass, NestedDataClass("foo")) # NewType ok(NewIntType, 5) # List-like - ok(List, [5]) - ok(List[int], [5]) - ok(List[MyDataClass], [MyDataClass("foo", 5, SerializableEnum.FOO)]) + ok(list, [5]) + ok(list[int], [5]) + ok(list[MyDataClass], [MyDataClass("foo", 5, SerializableEnum.FOO)]) ok(Iterable[int], [5, 6]) - ok(Tuple[int, str], (5, "6")) - ok(Tuple[int, ...], (5, 6, 7)) - ok(Set[int], set([5, 6])) - ok(Set, set([5, 6])) - ok(List, ["foo"]) + ok(tuple[int, str], (5, "6")) + ok(tuple[int, ...], (5, 6, 7)) + ok(set[int], {5, 6}) + ok(set, {5, 6}) + ok(list, ["foo"]) ok(Deque[int], deque([5, 6])) ok(Sequence[int], [5, 6]) - fail(List[int], [1, 2, "3"]) + fail(list[int], [1, 2, "3"]) # Dict-like - ok(Dict[str, MyDataClass], {"foo": MyDataClass("foo", 5, SerializableEnum.FOO)}) - ok(Dict, {"foo": 123}) - ok(Dict[str, Any], {"foo": 123}) - ok(Dict[Any, int], {"foo": 123}) + ok(dict[str, MyDataClass], {"foo": MyDataClass("foo", 5, SerializableEnum.FOO)}) + ok(dict, {"foo": 123}) + ok(dict[str, Any], {"foo": 123}) + ok(dict[Any, int], {"foo": 123}) ok(Mapping, {"foo": 123}) ok(Mapping[str, int], {"foo": 123}) ok(MutableMapping[str, int], {"foo": 123}) @@ -441,36 +437,35 @@ def fail(hint: Any, value: Any) -> None: ok(MyTypedDict, {"foo": "bar", "blah": "meh"}) # Non-string dict keys are supported - ok(Dict[int, str], {1: "1"}) - ok(Dict[float, str], {1.0: "1"}) - ok(Dict[bool, str], {True: "1"}) - ok(Dict[None, str], {None: "1"}) + ok(dict[int, str], {1: "1"}) + ok(dict[float, str], {1.0: "1"}) + ok(dict[bool, str], {True: "1"}) + ok(dict[None, str], {None: "1"}) # Alias ok(MyDataClassAlias, MyDataClass("foo", 5, SerializableEnum.FOO)) # IntEnum ok(SerializableEnum, SerializableEnum.FOO) - ok(List[SerializableEnum], [SerializableEnum.FOO, SerializableEnum.FOO]) + ok(list[SerializableEnum], [SerializableEnum.FOO, SerializableEnum.FOO]) # UUID ok(UUID, uuid4()) - ok(List[UUID], [uuid4(), uuid4()]) + ok(list[UUID], [uuid4(), uuid4()]) # StrEnum is available in 3.11+ if sys.version_info >= (3, 11): # StrEnum ok(SerializableStrEnum, SerializableStrEnum.FOO) ok( - List[SerializableStrEnum], + list[SerializableStrEnum], [SerializableStrEnum.FOO, SerializableStrEnum.FOO], ) # 3.10+ checks - if sys.version_info >= (3, 10): - ok(list[int], [1, 2]) - ok(dict[str, int], {"1": 2}) - ok(tuple[int, str], (1, "2")) + ok(list[int], [1, 2]) + ok(dict[str, int], {"1": 2}) + ok(tuple[int, str], (1, "2")) # Pydantic # TODO(cretz): Fix when https://github.com/pydantic/pydantic/pull/9612 tagged @@ -481,12 +476,12 @@ def fail(hint: Any, value: Any) -> None: foo="foo", bar=[MyPydanticClass(foo="baz", bar=[])], baz=uuid4() ), ) - ok(List[MyPydanticClass], [MyPydanticClass(foo="foo", bar=[])]) - fail(List[MyPydanticClass], [MyPydanticClass(foo="foo", bar=[]), 5]) + ok(list[MyPydanticClass], [MyPydanticClass(foo="foo", bar=[])]) + fail(list[MyPydanticClass], [MyPydanticClass(foo="foo", bar=[]), 5]) # This is an example of appending the stack to every Temporal failure error -def append_temporal_stack(exc: Optional[BaseException]) -> None: +def append_temporal_stack(exc: BaseException | None) -> None: while exc: # Only append if it doesn't appear already there if ( @@ -541,7 +536,7 @@ async def test_exception_format(): # Just serializes in a "payloads" wrapper class SimpleCodec(PayloadCodec): - async def encode(self, payloads: Sequence[Payload]) -> List[Payload]: + async def encode(self, payloads: Sequence[Payload]) -> list[Payload]: wrapper = Payloads(payloads=payloads) return [ Payload( @@ -549,7 +544,7 @@ async def encode(self, payloads: Sequence[Payload]) -> List[Payload]: ) ] - async def decode(self, payloads: Sequence[Payload]) -> List[Payload]: + async def decode(self, payloads: Sequence[Payload]) -> list[Payload]: payloads = list(payloads) if len(payloads) != 1: raise RuntimeError("Expected only a single payload") @@ -633,8 +628,8 @@ def default(self, o: Any) -> Any: class IPv4AddressJSONTypeConverter(JSONTypeConverter): def to_typed_value( - self, hint: Type, value: Any - ) -> Union[Optional[Any], _JSONTypeConverterUnhandled]: + self, hint: type, value: Any + ) -> Any | None | _JSONTypeConverterUnhandled: if inspect.isclass(hint) and issubclass(hint, ipaddress.IPv4Address): return ipaddress.IPv4Address(value) return JSONTypeConverter.Unhandled @@ -663,13 +658,13 @@ async def test_json_type_converter(): await DataConverter.default.decode([payload], [ipaddress.IPv4Address]) with pytest.raises(TypeError): await DataConverter.default.decode( - [list_payload], [List[ipaddress.IPv4Address]] + [list_payload], [list[ipaddress.IPv4Address]] ) # But decodes with custom assert addr == (await custom_conv.decode([payload], [ipaddress.IPv4Address]))[0] assert [addr, addr] == ( - await custom_conv.decode([list_payload], [List[ipaddress.IPv4Address]]) + await custom_conv.decode([list_payload], [list[ipaddress.IPv4Address]]) )[0] diff --git a/tests/test_plugins.py b/tests/test_plugins.py index 90e026c15..ea2cf3a1a 100644 --- a/tests/test_plugins.py +++ b/tests/test_plugins.py @@ -2,8 +2,9 @@ import uuid import warnings from collections import Counter +from collections.abc import AsyncIterator, Awaitable, Callable from contextlib import AbstractAsyncContextManager, asynccontextmanager -from typing import AsyncIterator, Awaitable, Callable, Optional, cast +from typing import Optional, cast import pytest @@ -333,7 +334,7 @@ async def test_simple_plugins(client: Client) -> None: async def test_simple_plugins_callables(client: Client) -> None: - def converter(old: Optional[DataConverter]): + def converter(old: DataConverter | None): if old != temporalio.converter.default(): raise ValueError("Can't override non-default converter") return pydantic_data_converter diff --git a/tests/test_runtime.py b/tests/test_runtime.py index 854bba561..c2829f03d 100644 --- a/tests/test_runtime.py +++ b/tests/test_runtime.py @@ -80,7 +80,7 @@ async def run_workflow(client: Client): async def test_runtime_log_forwarding(): # Create logger with record capture log_queue: queue.Queue[logging.LogRecord] = queue.Queue() - log_queue_list = cast(List[logging.LogRecord], log_queue.queue) + log_queue_list = cast(list[logging.LogRecord], log_queue.queue) logger = logging.getLogger(f"log-{uuid.uuid4()}") logger.addHandler(logging.handlers.QueueHandler(log_queue)) @@ -152,7 +152,7 @@ async def run(self) -> None: async def test_runtime_task_fail_log_forwarding(client: Client): # Client with lo capturing runtime log_queue: queue.Queue[logging.LogRecord] = queue.Queue() - log_queue_list = cast(List[logging.LogRecord], log_queue.queue) + log_queue_list = cast(list[logging.LogRecord], log_queue.queue) logger = logging.getLogger(f"log-{uuid.uuid4()}") logger.addHandler(logging.handlers.QueueHandler(log_queue)) logger.setLevel(logging.WARN) @@ -187,7 +187,7 @@ async def has_log() -> bool: await assert_eq_eventually(True, has_log) # Check record - record = next((l for l in log_queue_list if "Failing workflow task" in l.message)) + record = next(l for l in log_queue_list if "Failing workflow task" in l.message) assert record.levelno == logging.WARNING assert ( record.name == f"{logger.name}-sdk_core::temporalio_sdk_core::worker::workflow" diff --git a/tests/test_serialization_context.py b/tests/test_serialization_context.py index ee7be8684..07d48bdd3 100644 --- a/tests/test_serialization_context.py +++ b/tests/test_serialization_context.py @@ -12,9 +12,10 @@ import json import uuid from collections import defaultdict +from collections.abc import Sequence from dataclasses import dataclass, field from datetime import timedelta -from typing import Any, List, Literal, Optional, Sequence, Type +from typing import Any, List, Literal, Optional, Type import nexusrpc import pytest @@ -75,20 +76,20 @@ class SerializationContextPayloadConverter( EncodingPayloadConverter, WithSerializationContext ): def __init__(self): - self.context: Optional[SerializationContext] = None + self.context: SerializationContext | None = None @property def encoding(self) -> str: return "test-serialization-context" def with_context( - self, context: Optional[SerializationContext] + self, context: SerializationContext | None ) -> SerializationContextPayloadConverter: converter = SerializationContextPayloadConverter() converter.context = context return converter - def to_payload(self, value: Any) -> Optional[temporalio.api.common.v1.Payload]: + def to_payload(self, value: Any) -> temporalio.api.common.v1.Payload | None: if not isinstance(value, TraceData): return None if isinstance(self.context, WorkflowSerializationContext): @@ -115,7 +116,7 @@ def to_payload(self, value: Any) -> Optional[temporalio.api.common.v1.Payload]: def from_payload( self, payload: temporalio.api.common.v1.Payload, - type_hint: Optional[Type] = None, + type_hint: type | None = None, ) -> Any: value = JSONPlainPayloadConverter().from_payload(payload, TraceData) assert isinstance(value, TraceData) @@ -685,7 +686,7 @@ def test_subclassed_async_activity_handle(client: Client): @workflow.defn(sandboxed=False) # so that we can use isinstance class SignalSerializationContextTestWorkflow: def __init__(self) -> None: - self.signal_received: Optional[TraceData] = None + self.signal_received: TraceData | None = None @workflow.run async def run(self) -> TraceData: @@ -833,7 +834,7 @@ class UpdateSerializationContextTestWorkflow: @workflow.init def __init__(self, pass_validation: bool) -> None: self.pass_validation = pass_validation - self.input: Optional[TraceData] = None + self.input: TraceData | None = None @workflow.run async def run(self, pass_validation: bool) -> TraceData: @@ -927,7 +928,7 @@ async def test_update_payload_conversion( @workflow.defn class ExternalWorkflowTarget: def __init__(self) -> None: - self.signal_received: Optional[TraceData] = None + self.signal_received: TraceData | None = None @workflow.run async def run(self) -> TraceData: @@ -1068,10 +1069,10 @@ async def run(self) -> Never: class FailureConverterWithContext(DefaultFailureConverter, WithSerializationContext): def __init__(self): super().__init__(encode_common_attributes=False) - self.context: Optional[SerializationContext] = None + self.context: SerializationContext | None = None def with_context( - self, context: Optional[SerializationContext] + self, context: SerializationContext | None ) -> FailureConverterWithContext: converter = FailureConverterWithContext() converter.context = context @@ -1198,12 +1199,12 @@ async def test_failure_converter_with_context(client: Client): class PayloadCodecWithContext(PayloadCodec, WithSerializationContext): def __init__(self): - self.context: Optional[SerializationContext] = None + self.context: SerializationContext | None = None self.encode_called_with_context = False self.decode_called_with_context = False def with_context( - self, context: Optional[SerializationContext] + self, context: SerializationContext | None ) -> PayloadCodecWithContext: codec = PayloadCodecWithContext() codec.context = context @@ -1211,7 +1212,7 @@ def with_context( async def encode( self, payloads: Sequence[temporalio.api.common.v1.Payload] - ) -> List[temporalio.api.common.v1.Payload]: + ) -> list[temporalio.api.common.v1.Payload]: assert self.context if isinstance(self.context, ActivitySerializationContext): test_traces[self.context.workflow_id].append( @@ -1232,7 +1233,7 @@ async def encode( async def decode( self, payloads: Sequence[temporalio.api.common.v1.Payload] - ) -> List[temporalio.api.common.v1.Payload]: + ) -> list[temporalio.api.common.v1.Payload]: assert self.context if isinstance(self.context, ActivitySerializationContext): test_traces[self.context.workflow_id].append( @@ -1506,10 +1507,10 @@ class PayloadEncryptionCodec(PayloadCodec, WithSerializationContext): """ def __init__(self): - self.context: Optional[SerializationContext] = None + self.context: SerializationContext | None = None def with_context( - self, context: Optional[SerializationContext] + self, context: SerializationContext | None ) -> PayloadEncryptionCodec: codec = PayloadEncryptionCodec() codec.context = context @@ -1517,7 +1518,7 @@ def with_context( async def encode( self, payloads: Sequence[temporalio.api.common.v1.Payload] - ) -> List[temporalio.api.common.v1.Payload]: + ) -> list[temporalio.api.common.v1.Payload]: [payload] = payloads return [ temporalio.api.common.v1.Payload( @@ -1528,7 +1529,7 @@ async def encode( async def decode( self, payloads: Sequence[temporalio.api.common.v1.Payload] - ) -> List[temporalio.api.common.v1.Payload]: + ) -> list[temporalio.api.common.v1.Payload]: [payload] = payloads assert json.loads(payload.data.decode()) == self._get_encryption_key() metadata = dict(payload.metadata) @@ -1684,7 +1685,7 @@ def with_context( async def _assert_context_iff_not_nexus( self, payloads: Sequence[temporalio.api.common.v1.Payload] - ) -> List[temporalio.api.common.v1.Payload]: + ) -> list[temporalio.api.common.v1.Payload]: [payload] = payloads assert bool(self.context) == (payload.data.decode() != '"nexus-data"') return list(payloads) @@ -1750,7 +1751,7 @@ async def test_nexus_payload_codec_operations_lack_context( class PydanticData(BaseModel): value: str - trace: List[str] = [] + trace: list[str] = [] class PydanticJSONConverterWithContext( @@ -1758,16 +1759,16 @@ class PydanticJSONConverterWithContext( ): def __init__(self): super().__init__() - self.context: Optional[SerializationContext] = None + self.context: SerializationContext | None = None def with_context( - self, context: Optional[SerializationContext] + self, context: SerializationContext | None ) -> PydanticJSONConverterWithContext: converter = PydanticJSONConverterWithContext() converter.context = context return converter - def to_payload(self, value: Any) -> Optional[temporalio.api.common.v1.Payload]: + def to_payload(self, value: Any) -> temporalio.api.common.v1.Payload | None: if isinstance(value, PydanticData) and self.context: if isinstance(self.context, WorkflowSerializationContext): value.trace.append(f"wf_{self.context.workflow_id}") @@ -1784,7 +1785,7 @@ def __init__(self): for c in DefaultPayloadConverter.default_encoding_payload_converters ) ) - self.context: Optional[SerializationContext] = None + self.context: SerializationContext | None = None @workflow.defn @@ -1841,10 +1842,10 @@ def encoding(self) -> str: def __init__(self): super().__init__() - self.context: Optional[SerializationContext] = None + self.context: SerializationContext | None = None def with_context( - self, context: Optional[SerializationContext] + self, context: SerializationContext | None ) -> CustomEncodingPayloadConverter: converter = CustomEncodingPayloadConverter() converter.context = context @@ -1862,14 +1863,14 @@ def __init__(self): def to_payloads( self, values: Sequence[Any] - ) -> List[temporalio.api.common.v1.Payload]: + ) -> list[temporalio.api.common.v1.Payload]: raise UserMethodCalledError def from_payloads( self, payloads: Sequence[temporalio.api.common.v1.Payload], - type_hints: Optional[List[Type]] = None, - ) -> List[Any]: + type_hints: list[type] | None = None, + ) -> list[Any]: raise NotImplementedError diff --git a/tests/test_service.py b/tests/test_service.py index 77ffcfa04..40d6c05eb 100644 --- a/tests/test_service.py +++ b/tests/test_service.py @@ -1,8 +1,9 @@ import inspect import os import re +from collections.abc import Callable, Mapping from datetime import timedelta -from typing import Any, Callable, Dict, Mapping, Tuple, Type +from typing import Any, Dict, Tuple, Type import google.protobuf.empty_pb2 import google.protobuf.message @@ -38,9 +39,9 @@ def assert_all_calls_present( new_stub: Callable[[grpc.Channel], Any], custom_req_resp: Mapping[ str, - Tuple[ - Type[google.protobuf.message.Message], - Type[google.protobuf.message.Message], + tuple[ + type[google.protobuf.message.Message], + type[google.protobuf.message.Message], ], ] = {}, ) -> None: @@ -104,16 +105,16 @@ def __init__( package: Any, custom_req_resp: Mapping[ str, - Tuple[ - Type[google.protobuf.message.Message], - Type[google.protobuf.message.Message], + tuple[ + type[google.protobuf.message.Message], + type[google.protobuf.message.Message], ], ], ) -> None: super().__init__() self.package = package self.custom_req_resp = custom_req_resp - self.calls: Dict[str, Tuple[Type, Type]] = {} + self.calls: dict[str, tuple[type, type]] = {} def unary_unary(self, method, request_serializer, response_deserializer): # Last part after slash @@ -132,9 +133,7 @@ def unary_unary(self, method, request_serializer, response_deserializer): def test_version(): # Extract version from pyproject.toml - with open( - os.path.join(os.path.dirname(__file__), "..", "pyproject.toml"), "r" - ) as f: + with open(os.path.join(os.path.dirname(__file__), "..", "pyproject.toml")) as f: pyproject = f.read() version = pyproject[pyproject.find('version = "') + 11 :] version = version[: version.find('"')] diff --git a/tests/test_workflow.py b/tests/test_workflow.py index f62f02b8a..becb0d111 100644 --- a/tests/test_workflow.py +++ b/tests/test_workflow.py @@ -1,6 +1,7 @@ import inspect import itertools -from typing import Any, Callable, Sequence, Set, Type, get_type_hints +from collections.abc import Callable, Sequence +from typing import Any, Set, Type, get_type_hints import pytest @@ -470,8 +471,8 @@ def test_workflow_update_validator_not_update(): def _assert_config_function_parity( function_obj: Callable[..., Any], - config_class: Type[Any], - excluded_params: Set[str], + config_class: type[Any], + excluded_params: set[str], ) -> None: function_name = function_obj.__name__ config_name = config_class.__name__ @@ -481,14 +482,14 @@ def _assert_config_function_parity( config_hints = get_type_hints(config_class) # Get parameter names from function (excluding excluded ones and applying mappings) - expected_config_params = set( - [name for name in function_sig.parameters.keys() if name not in excluded_params] - ) + expected_config_params = { + name for name in function_sig.parameters.keys() if name not in excluded_params + } # Get parameter names from config - actual_config_params = set( - [name for name in config_hints.keys() if name not in excluded_params] - ) + actual_config_params = { + name for name in config_hints.keys() if name not in excluded_params + } # Check for missing and extra parameters missing_in_config = expected_config_params - actual_config_params diff --git a/tests/testing/test_workflow.py b/tests/testing/test_workflow.py index 838ca1d12..1a857a55d 100644 --- a/tests/testing/test_workflow.py +++ b/tests/testing/test_workflow.py @@ -220,7 +220,7 @@ async def test_workflow_env_assert(client: Client): client_config["interceptors"] = [interceptor] client = Client(**client_config) - def assert_proper_error(err: Optional[BaseException]) -> None: + def assert_proper_error(err: BaseException | None) -> None: assert isinstance(err, ApplicationError) # In unsandboxed workflows, this message has extra diff info appended # due to pytest's custom loader that does special assert tricks. But in @@ -319,7 +319,7 @@ async def test_search_attributes_on_dev_server( def assert_timestamp_from_now( - ts: Union[datetime, float], expected_from_now: float, max_delta: float = 30 + ts: datetime | float, expected_from_now: float, max_delta: float = 30 ) -> None: if isinstance(ts, datetime): ts = ts.timestamp() diff --git a/tests/worker/test_activity.py b/tests/worker/test_activity.py index 6ba5045d4..7a9e27f84 100644 --- a/tests/worker/test_activity.py +++ b/tests/worker/test_activity.py @@ -8,13 +8,14 @@ import threading import time import uuid +from collections.abc import Callable, Sequence from concurrent.futures import ThreadPoolExecutor from concurrent.futures.process import BrokenProcessPool from contextvars import ContextVar from dataclasses import dataclass from datetime import datetime, timedelta, timezone from time import sleep -from typing import Any, Callable, List, NoReturn, Optional, Sequence, Type +from typing import Any, List, NoReturn, Optional, Type import pytest @@ -122,7 +123,7 @@ async def test_client_available_in_async_activities( with pytest.raises(RuntimeError, match="Not in activity context"): activity.client() - captured_client: Optional[Client] = None + captured_client: Client | None = None @activity.defn async def capture_client() -> None: @@ -185,7 +186,7 @@ async def test_activity_info( assert str(err.value) == "Not in activity context" # Capture the info from the activity - info: Optional[activity.Info] = None + info: activity.Info | None = None @activity.defn async def capture_info() -> None: @@ -517,7 +518,7 @@ async def test_sync_activity_thread_cancel_exception_shielded( worker: ExternalWorker, shared_state_manager: SharedStateManager, ): - events: List[str] = [] + events: list[str] = [] @activity.defn def wait_cancel() -> None: @@ -703,7 +704,7 @@ async def test_max_concurrent_activities( worker: ExternalWorker, shared_state_manager: SharedStateManager, ): - seen_indexes: List[int] = [] + seen_indexes: list[int] = [] complete_activities_event = asyncio.Event() @activity.defn @@ -741,7 +742,7 @@ class SomeClass1: @dataclass class SomeClass2: foo: str - bar: Optional[SomeClass1] = None + bar: SomeClass1 | None = None async def test_activity_type_hints( @@ -870,7 +871,7 @@ async def some_activity() -> str: @activity.defn def picklable_heartbeat_details_activity() -> str: info = activity.info() - some_list: List[str] = ( + some_list: list[str] = ( next(iter(info.heartbeat_details)) if info.heartbeat_details else [] ) some_list.append(f"attempt: {info.attempt}") @@ -1033,7 +1034,7 @@ async def say_hello(name: str) -> str: activity.logger.base_logger.removeHandler(handler) activity.logger.base_logger.setLevel(prev_level) assert result.result == "Hello, Temporal!" - records: List[logging.LogRecord] = list(handler.queue.queue) # type: ignore + records: list[logging.LogRecord] = list(handler.queue.queue) # type: ignore assert len(records) > 0 assert records[-1].message.startswith( "Called with arg: Temporal ({'activity_id': '" @@ -1240,11 +1241,11 @@ async def test_sync_activity_process_executor_crash( class AsyncActivityWrapper: def __init__(self) -> None: - self._info: Optional[activity.Info] = None + self._info: activity.Info | None = None self._info_set = asyncio.Event() @activity.defn - async def run(self) -> Optional[str]: + async def run(self) -> str | None: self._info = activity.info() self._info_set.set() activity.raise_complete_async() @@ -1571,21 +1572,21 @@ async def _execute_workflow_with_activity( fn: Callable, *args: Any, shared_state_manager: SharedStateManager, - count: Optional[int] = None, - index_as_arg: Optional[bool] = None, - schedule_to_close_timeout_ms: Optional[int] = None, - start_to_close_timeout_ms: Optional[int] = None, - schedule_to_start_timeout_ms: Optional[int] = None, - cancel_after_ms: Optional[int] = None, - wait_for_cancellation: Optional[bool] = None, - heartbeat_timeout_ms: Optional[int] = None, - retry_max_attempts: Optional[int] = None, - non_retryable_error_types: Optional[Sequence[str]] = None, + count: int | None = None, + index_as_arg: bool | None = None, + schedule_to_close_timeout_ms: int | None = None, + start_to_close_timeout_ms: int | None = None, + schedule_to_start_timeout_ms: int | None = None, + cancel_after_ms: int | None = None, + wait_for_cancellation: bool | None = None, + heartbeat_timeout_ms: int | None = None, + retry_max_attempts: int | None = None, + non_retryable_error_types: Sequence[str] | None = None, worker_config: WorkerConfig = {}, - on_complete: Optional[Callable[[], None]] = None, - activity_name_override: Optional[str] = None, - result_type_override: Optional[Type] = None, - additional_activities: List[Callable] = [], + on_complete: Callable[[], None] | None = None, + activity_name_override: str | None = None, + result_type_override: type | None = None, + additional_activities: list[Callable] = [], ) -> _ActivityResult: worker_config["client"] = client worker_config["task_queue"] = str(uuid.uuid4()) diff --git a/tests/worker/test_command_aware_visitor.py b/tests/worker/test_command_aware_visitor.py index 92c67b218..9e4b7a39b 100644 --- a/tests/worker/test_command_aware_visitor.py +++ b/tests/worker/test_command_aware_visitor.py @@ -1,6 +1,7 @@ """Test that CommandAwarePayloadVisitor handles all commands with seq fields that have payloads.""" -from typing import Any, Iterator, Type +from collections.abc import Iterator +from typing import Any, Type from temporalio.bridge._visitor import PayloadVisitor from temporalio.bridge.proto.workflow_activation import workflow_activation_pb2 @@ -75,14 +76,14 @@ def test_command_aware_visitor_has_methods_for_all_seq_protos_with_payloads(): ), "Should have exactly one activation job without payloads (FireTimer)" -def _get_workflow_command_protos_with_seq() -> Iterator[Type[Any]]: +def _get_workflow_command_protos_with_seq() -> Iterator[type[Any]]: """Get concrete classes of all workflow command protos with a seq field.""" for descriptor in workflow_commands_pb2.DESCRIPTOR.message_types_by_name.values(): if "seq" in descriptor.fields_by_name: yield descriptor._concrete_class -def _get_workflow_activation_job_protos_with_seq() -> Iterator[Type[Any]]: +def _get_workflow_activation_job_protos_with_seq() -> Iterator[type[Any]]: """Get concrete classes of all workflow activation job protos with a seq field.""" for descriptor in workflow_activation_pb2.DESCRIPTOR.message_types_by_name.values(): if "seq" in descriptor.fields_by_name: diff --git a/tests/worker/test_interceptor.py b/tests/worker/test_interceptor.py index 1cb6cd25d..7746dce2d 100644 --- a/tests/worker/test_interceptor.py +++ b/tests/worker/test_interceptor.py @@ -1,7 +1,8 @@ import asyncio import uuid +from collections.abc import Callable from datetime import timedelta -from typing import Any, Callable, List, NoReturn, Optional, Tuple, Type +from typing import Any, List, NoReturn, Optional, Tuple, Type import pytest @@ -32,7 +33,7 @@ from temporalio.worker._interceptor import StartNexusOperationInput from tests.helpers.nexus import create_nexus_endpoint, make_nexus_endpoint_name -interceptor_traces: List[Tuple[str, Any]] = [] +interceptor_traces: list[tuple[str, Any]] = [] class TracingWorkerInterceptor(Interceptor): @@ -43,7 +44,7 @@ def intercept_activity( def workflow_interceptor_class( self, input: WorkflowInterceptorClassInput - ) -> Optional[Type[WorkflowInboundInterceptor]]: + ) -> type[WorkflowInboundInterceptor] | None: return TracingWorkflowInboundInterceptor @@ -254,7 +255,7 @@ async def test_worker_interceptor(client: Client, env: WorkflowEnvironment): await handle.result() # Check traces - def pop_trace(name: str, filter: Optional[Callable[[Any], bool]] = None) -> Any: + def pop_trace(name: str, filter: Callable[[Any], bool] | None = None) -> Any: index = next( ( i @@ -318,7 +319,7 @@ def pop_trace(name: str, filter: Optional[Callable[[Any], bool]] = None) -> Any: class WorkflowInstanceAccessInterceptor(Interceptor): def workflow_interceptor_class( self, input: WorkflowInterceptorClassInput - ) -> Optional[Type[WorkflowInboundInterceptor]]: + ) -> type[WorkflowInboundInterceptor] | None: return WorkflowInstanceAccessInboundInterceptor diff --git a/tests/worker/test_replayer.py b/tests/worker/test_replayer.py index e3ea8dcf7..67c1b1d52 100644 --- a/tests/worker/test_replayer.py +++ b/tests/worker/test_replayer.py @@ -293,7 +293,7 @@ async def test_replayer_multiple_from_client( # workflow ID so we can query it using standard visibility. workflow_id = f"workflow-{uuid.uuid4()}" async with new_say_hello_worker(client) as worker: - expected_runs_and_non_det: Dict[str, bool] = {} + expected_runs_and_non_det: dict[str, bool] = {} for i in range(5): should_cause_nondeterminism = i == 1 or i == 3 handle = await client.start_workflow( @@ -415,7 +415,7 @@ async def test_replayer_command_reordering_backward_compatibility() -> None: class WorkerWorkflowResultInterceptor(Interceptor): def workflow_interceptor_class( self, input: WorkflowInterceptorClassInput - ) -> Optional[Type[WorkflowInboundInterceptor]]: + ) -> type[WorkflowInboundInterceptor] | None: return WorkflowResultInterceptor diff --git a/tests/worker/test_update_with_start.py b/tests/worker/test_update_with_start.py index 044307a7b..23f997c08 100644 --- a/tests/worker/test_update_with_start.py +++ b/tests/worker/test_update_with_start.py @@ -2,10 +2,11 @@ import asyncio import uuid +from collections.abc import Mapping from dataclasses import dataclass from datetime import timedelta from enum import Enum, IntEnum -from typing import Any, Mapping, Optional, Union +from typing import Any, Optional, Union from unittest.mock import patch import pytest @@ -814,8 +815,8 @@ async def __call__( req: temporalio.api.workflowservice.v1.ExecuteMultiOperationRequest, *, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> temporalio.api.workflowservice.v1.ExecuteMultiOperationResponse: raise self.empty_details_err diff --git a/tests/worker/test_visitor.py b/tests/worker/test_visitor.py index c59a0248b..4fb820f31 100644 --- a/tests/worker/test_visitor.py +++ b/tests/worker/test_visitor.py @@ -1,4 +1,4 @@ -from typing import MutableSequence +from collections.abc import MutableSequence from google.protobuf.duration_pb2 import Duration diff --git a/tests/worker/test_worker.py b/tests/worker/test_worker.py index 1e336c1c8..9779bc633 100644 --- a/tests/worker/test_worker.py +++ b/tests/worker/test_worker.py @@ -5,8 +5,9 @@ import multiprocessing import multiprocessing.context import uuid +from collections.abc import Awaitable, Callable, Sequence from datetime import timedelta -from typing import Any, Awaitable, Callable, Optional, Sequence +from typing import Any, Optional from urllib.request import urlopen import nexusrpc @@ -170,7 +171,7 @@ async def test_worker_fatal_error_with(client: Client): async def test_worker_fatal_error_callback(client: Client): - callback_err: Optional[BaseException] = None + callback_err: BaseException | None = None async def on_fatal_error(exc: BaseException) -> None: nonlocal callback_err @@ -417,7 +418,7 @@ async def reserve_slot(self, ctx: SlotReserveContext) -> SlotPermit: self.reserves += 1 return MyPermit(self.reserves) - def try_reserve_slot(self, ctx: SlotReserveContext) -> Optional[SlotPermit]: + def try_reserve_slot(self, ctx: SlotReserveContext) -> SlotPermit | None: self.reserve_asserts(ctx) return None @@ -514,7 +515,7 @@ async def reserve_slot(self, ctx: SlotReserveContext) -> SlotPermit: return SlotPermit() raise ValueError("I always throw") - def try_reserve_slot(self, ctx: SlotReserveContext) -> Optional[SlotPermit]: + def try_reserve_slot(self, ctx: SlotReserveContext) -> SlotPermit | None: raise ValueError("I always throw") def mark_slot_used(self, ctx: SlotMarkUsedContext) -> None: @@ -553,7 +554,7 @@ async def reserve_slot(self, ctx: SlotReserveContext) -> SlotPermit: await asyncio.get_event_loop().create_future() raise ValueError("Should be unreachable") - def try_reserve_slot(self, ctx: SlotReserveContext) -> Optional[SlotPermit]: + def try_reserve_slot(self, ctx: SlotReserveContext) -> SlotPermit | None: return None def mark_slot_used(self, ctx: SlotMarkUsedContext) -> None: @@ -1160,7 +1161,7 @@ async def set_ramping_version( def create_worker( client: Client, - on_fatal_error: Optional[Callable[[BaseException], Awaitable[None]]] = None, + on_fatal_error: Callable[[BaseException], Awaitable[None]] | None = None, ) -> Worker: return Worker( client, @@ -1192,8 +1193,8 @@ def __init__(self, worker: Worker, attr: str) -> None: self.poll_fail_queue: asyncio.Queue[Exception] = asyncio.Queue() self.orig_poll_call = getattr(worker._bridge_worker, attr) setattr(worker._bridge_worker, attr, self.patched_poll_call) - self.next_poll_task: Optional[asyncio.Task] = None - self.next_exception_task: Optional[asyncio.Task] = None + self.next_poll_task: asyncio.Task | None = None + self.next_exception_task: asyncio.Task | None = None async def patched_poll_call(self) -> Any: if not self.next_poll_task: diff --git a/tests/worker/test_workflow.py b/tests/worker/test_workflow.py index 4356bc34e..668eabb12 100644 --- a/tests/worker/test_workflow.py +++ b/tests/worker/test_workflow.py @@ -15,19 +15,18 @@ import typing import uuid from abc import ABC, abstractmethod +from collections.abc import Awaitable, Mapping, Sequence from dataclasses import dataclass from datetime import datetime, timedelta, timezone from enum import IntEnum from functools import partial from typing import ( Any, - Awaitable, Dict, List, - Mapping, + Literal, NoReturn, Optional, - Sequence, Tuple, Type, Union, @@ -38,7 +37,7 @@ import pydantic import pytest from google.protobuf.timestamp_pb2 import Timestamp -from typing_extensions import Literal, Protocol, runtime_checkable +from typing_extensions import Protocol, runtime_checkable import temporalio.activity import temporalio.api.sdk.v1 @@ -222,7 +221,7 @@ async def test_workflow_multi_param(client: Client): @workflow.defn class InfoWorkflow: @workflow.run - async def run(self) -> Dict: + async def run(self) -> dict: # Convert to JSON and back so it'll stringify un-JSON-able pieces ret = dataclasses.asdict(workflow.info()) return json.loads(json.dumps(ret, default=str)) @@ -345,7 +344,7 @@ async def test_workflow_history_info( @workflow.defn class SignalAndQueryWorkflow: def __init__(self) -> None: - self._last_event: Optional[str] = None + self._last_event: str | None = None @workflow.run async def run(self) -> None: @@ -422,7 +421,7 @@ async def test_workflow_signal_and_query(client: Client): @workflow.defn class SignalAndQueryHandlersWorkflow: def __init__(self) -> None: - self._last_event: Optional[str] = None + self._last_event: str | None = None @workflow.run async def run(self) -> None: @@ -563,7 +562,7 @@ async def test_workflow_signal_and_query_errors(client: Client): @workflow.defn class SignalAndQueryOldDynamicStyleWorkflow: def __init__(self) -> None: - self._last_event: Optional[str] = None + self._last_event: str | None = None @workflow.run async def run(self) -> None: @@ -604,7 +603,7 @@ async def test_workflow_signal_and_query_old_dynamic_style(client: Client): @workflow.defn class SignalAndQueryHandlersOldDynamicStyleWorkflow: def __init__(self) -> None: - self._last_event: Optional[str] = None + self._last_event: str | None = None @workflow.run async def run(self) -> None: @@ -670,10 +669,10 @@ class BadSignalParam: @workflow.defn class BadSignalParamWorkflow: def __init__(self) -> None: - self._signals: List[BadSignalParam] = [] + self._signals: list[BadSignalParam] = [] @workflow.run - async def run(self) -> List[BadSignalParam]: + async def run(self) -> list[BadSignalParam]: await workflow.wait_condition( lambda: bool(self._signals) and self._signals[-1].some_str == "finish" ) @@ -710,7 +709,7 @@ def __init__(self) -> None: self._received_event2 = False @workflow.run - async def run(self) -> Dict: + async def run(self) -> dict: # Record start times ret = { # "now" timestamp and current event loop monotonic time @@ -780,8 +779,8 @@ async def status() -> str: execution=WorkflowExecution(workflow_id=handle.id), ) ) - first_timestamp: Optional[Timestamp] = None - last_timestamp: Optional[Timestamp] = None + first_timestamp: Timestamp | None = None + last_timestamp: Timestamp | None = None for event in resp.history.events: # Get timestamp from first workflow task started if event.event_type is EventType.EVENT_TYPE_WORKFLOW_TASK_STARTED: @@ -1146,7 +1145,7 @@ async def started() -> bool: class CancelChildWorkflow: def __init__(self) -> None: self._ready = False - self._task: Optional[asyncio.Task[Any]] = None + self._task: asyncio.Task[Any] | None = None @workflow.run async def run(self, use_execute: bool) -> None: @@ -1203,7 +1202,7 @@ async def test_workflow_cancel_child_unstarted(client: Client): @workflow.defn class ReturnSignalWorkflow: def __init__(self) -> None: - self._signal: Optional[str] = None + self._signal: str | None = None @workflow.run async def run(self) -> str: @@ -1306,8 +1305,8 @@ async def test_workflow_signal_external(client: Client): @workflow.defn class MultiCancelWorkflow: @workflow.run - async def run(self) -> List[str]: - events: List[str] = [] + async def run(self) -> list[str]: + events: list[str] = [] async def timer(): nonlocal events @@ -1512,7 +1511,7 @@ async def test_workflow_activity_timeout(client: Client): # Just serializes in a "payloads" wrapper class SimpleCodec(PayloadCodec): - async def encode(self, payloads: Sequence[Payload]) -> List[Payload]: + async def encode(self, payloads: Sequence[Payload]) -> list[Payload]: wrapper = Payloads(payloads=payloads) return [ Payload( @@ -1520,7 +1519,7 @@ async def encode(self, payloads: Sequence[Payload]) -> List[Payload]: ) ] - async def decode(self, payloads: Sequence[Payload]) -> List[Payload]: + async def decode(self, payloads: Sequence[Payload]) -> list[Payload]: payloads = list(payloads) if len(payloads) != 1: raise RuntimeError("Expected only a single payload") @@ -1543,10 +1542,10 @@ async def test_workflow_with_codec(client: Client, env: WorkflowEnvironment): class PassThroughCodec(PayloadCodec): - async def encode(self, payloads: Sequence[Payload]) -> List[Payload]: + async def encode(self, payloads: Sequence[Payload]) -> list[Payload]: return list(payloads) - async def decode(self, payloads: Sequence[Payload]) -> List[Payload]: + async def decode(self, payloads: Sequence[Payload]) -> list[Payload]: return list(payloads) @@ -1589,7 +1588,7 @@ class CustomWorkflowRunner(WorkflowRunner): def __init__(self) -> None: super().__init__() self._unsandboxed = UnsandboxedWorkflowRunner() - self._pairs: List[Tuple[WorkflowActivation, WorkflowActivationCompletion]] = [] + self._pairs: list[tuple[WorkflowActivation, WorkflowActivationCompletion]] = [] def prepare_workflow(self, defn: workflow._Definition) -> None: pass @@ -1613,8 +1612,8 @@ def activate(self, act: WorkflowActivation) -> WorkflowActivationCompletion: def get_serialization_context( self, - command_info: Optional[temporalio.worker._command_aware_visitor.CommandInfo], - ) -> Optional[temporalio.converter.SerializationContext]: + command_info: temporalio.worker._command_aware_visitor.CommandInfo | None, + ) -> temporalio.converter.SerializationContext | None: return self._unsandboxed.get_serialization_context(command_info) @@ -1643,7 +1642,7 @@ async def test_workflow_with_custom_runner(client: Client): @workflow.defn class ContinueAsNewWorkflow: @workflow.run - async def run(self, past_run_ids: List[str]) -> List[str]: + async def run(self, past_run_ids: list[str]) -> list[str]: # Check memo and retry policy assert workflow.memo_value("past_run_id_count") == len(past_run_ids) retry_policy = workflow.info().retry_policy @@ -1674,7 +1673,7 @@ async def test_workflow_continue_as_new(client: Client, env: WorkflowEnvironment async with new_worker(client, ContinueAsNewWorkflow) as worker: handle = await client.start_workflow( ContinueAsNewWorkflow.run, - cast(List[str], []), + cast(list[str], []), id=f"workflow-{uuid.uuid4()}", task_queue=worker.task_queue, memo={"past_run_id_count": 0}, @@ -1689,7 +1688,7 @@ async def test_workflow_continue_as_new(client: Client, env: WorkflowEnvironment def search_attributes_to_serializable( - attrs: Union[SearchAttributes, TypedSearchAttributes], + attrs: SearchAttributes | TypedSearchAttributes, ) -> Mapping[str, Any]: if isinstance(attrs, TypedSearchAttributes): return { @@ -1732,7 +1731,7 @@ def get_search_attributes_typed(self) -> Mapping[str, Any]: @workflow.signal def do_search_attribute_update_untyped(self) -> None: - empty_float_list: List[float] = [] + empty_float_list: list[float] = [] workflow.upsert_search_attributes( { SearchAttributeWorkflow.text_attribute.name: ["text2"], @@ -1816,7 +1815,7 @@ async def test_workflow_search_attributes(client: Client, env_type: str): ), ] ) - updated_attrs_untyped: Dict[str, SearchAttributeValues] = { + updated_attrs_untyped: dict[str, SearchAttributeValues] = { SearchAttributeWorkflow.text_attribute.name: ["text2"], SearchAttributeWorkflow.keyword_attribute.name: ["keyword1"], SearchAttributeWorkflow.keyword_list_attribute.name: [ @@ -1824,13 +1823,13 @@ async def test_workflow_search_attributes(client: Client, env_type: str): "keywordlist4", ], SearchAttributeWorkflow.int_attribute.name: [456], - SearchAttributeWorkflow.float_attribute.name: cast(List[float], []), + SearchAttributeWorkflow.float_attribute.name: cast(list[float], []), SearchAttributeWorkflow.bool_attribute.name: [False], SearchAttributeWorkflow.datetime_attribute.name: [ datetime(2003, 4, 5, 6, 7, 8, tzinfo=timezone(timedelta(hours=9))) ], } - updated_attrs_untyped_from_server: Dict[str, SearchAttributeValues] = { + updated_attrs_untyped_from_server: dict[str, SearchAttributeValues] = { SearchAttributeWorkflow.text_attribute.name: ["text2"], SearchAttributeWorkflow.keyword_attribute.name: ["keyword1"], SearchAttributeWorkflow.keyword_list_attribute.name: [ @@ -2854,8 +2853,8 @@ def __init__(self, *, should_patch: bool = False) -> None: self._waiting_signal = True @workflow.run - async def run(self) -> List[str]: - results: List[str] = [] + async def run(self) -> list[str]: + results: list[str] = [] if self.should_patch and workflow.patched("some-patch"): results.append("pre-patch") self._waiting_signal = True @@ -2880,7 +2879,7 @@ def __init__(self) -> None: super().__init__(should_patch=True) @workflow.run - async def run(self) -> List[str]: + async def run(self) -> list[str]: return await super().run() @@ -3496,7 +3495,7 @@ async def test_workflow_custom_failure_converter(client: Client): while True: assert failure.message == "Encoded failure" assert failure.stack_trace == "" - attrs: Dict[str, Any] = PayloadConverter.default.from_payloads( + attrs: dict[str, Any] = PayloadConverter.default.from_payloads( [failure.encoded_attributes] )[0] assert "message" in attrs @@ -3515,8 +3514,8 @@ class OptionalParam: class OptionalParamWorkflow: @workflow.run async def run( - self, some_param: Optional[OptionalParam] = OptionalParam(some_string="default") - ) -> Optional[OptionalParam]: + self, some_param: OptionalParam | None = OptionalParam(some_string="default") + ) -> OptionalParam | None: assert some_param is None or ( isinstance(some_param, OptionalParam) and some_param.some_string in ["default", "foo"] @@ -3556,7 +3555,7 @@ class ExceptionRaisingPayloadConverter(DefaultPayloadConverter): bad_outbound_str = "bad-outbound-payload-str" bad_inbound_str = "bad-inbound-payload-str" - def to_payloads(self, values: Sequence[Any]) -> List[Payload]: + def to_payloads(self, values: Sequence[Any]) -> list[Payload]: if any( value == ExceptionRaisingPayloadConverter.bad_outbound_str for value in values @@ -3565,8 +3564,8 @@ def to_payloads(self, values: Sequence[Any]) -> List[Payload]: return super().to_payloads(values) def from_payloads( - self, payloads: Sequence[Payload], type_hints: Optional[List] = None - ) -> List[Any]: + self, payloads: Sequence[Payload], type_hints: list | None = None + ) -> list[Any]: # Check if any payloads contain the bad data for payload in payloads: if ( @@ -3725,7 +3724,7 @@ async def test_cache_eviction_tear_down(client: Client): ) as worker: # Put a hook to catch unraisable exceptions old_hook = sys.unraisablehook - hook_calls: List[Any] = [] + hook_calls: list[Any] = [] sys.unraisablehook = hook_calls.append try: handle = await client.start_workflow( @@ -3764,7 +3763,7 @@ class CapturedEvictionException: exception: BaseException -captured_eviction_exceptions: List[CapturedEvictionException] = [] +captured_eviction_exceptions: list[CapturedEvictionException] = [] @workflow.defn(sandboxed=False) @@ -4273,7 +4272,7 @@ async def do_stuff(buffer: MetricBuffer) -> None: @workflow.defn class UpdateHandlersWorkflow: def __init__(self) -> None: - self._last_event: Optional[str] = None + self._last_event: str | None = None @workflow.run async def run(self) -> None: @@ -4980,14 +4979,14 @@ async def run(self, scenario: FailureTypesScenario) -> None: async def test_workflow_failure_types_configured(client: Client): # Asserter for a single scenario async def assert_scenario( - workflow: Type[FailureTypesWorkflowBase], + workflow: type[FailureTypesWorkflowBase], *, expect_task_fail: bool, fail_message_contains: str, - worker_level_failure_exception_type: Optional[Type[Exception]] = None, - workflow_scenario: Optional[FailureTypesScenario] = None, - signal_scenario: Optional[FailureTypesScenario] = None, - update_scenario: Optional[FailureTypesScenario] = None, + worker_level_failure_exception_type: type[Exception] | None = None, + workflow_scenario: FailureTypesScenario | None = None, + signal_scenario: FailureTypesScenario | None = None, + update_scenario: FailureTypesScenario | None = None, ) -> None: logging.debug( "Asserting scenario %s", @@ -5018,7 +5017,7 @@ async def assert_scenario( ) if signal_scenario: await handle.signal(workflow.signal, signal_scenario) - update_handle: Optional[WorkflowUpdateHandle[Any]] = None + update_handle: WorkflowUpdateHandle[Any] | None = None if update_scenario: update_handle = await handle.start_update( workflow.update, @@ -5060,11 +5059,11 @@ async def has_expected_task_fail() -> bool: # Run a scenario async def run_scenario( - workflow: Type[FailureTypesWorkflowBase], + workflow: type[FailureTypesWorkflowBase], scenario: FailureTypesScenario, *, expect_task_fail: bool = False, - worker_level_failure_exception_type: Optional[Type[Exception]] = None, + worker_level_failure_exception_type: type[Exception] | None = None, ) -> None: # Run for workflow, signal, and update fail_message_contains = ( @@ -5284,7 +5283,7 @@ async def return_name_activity(args: Sequence[RawValue]) -> str: @workflow.defn class AsCompletedWorkflow: @workflow.run - async def run(self) -> List[str]: + async def run(self) -> list[str]: # Lazily start 10 different activities and wait for each completed tasks = [ workflow.execute_activity( @@ -5321,7 +5320,7 @@ async def test_workflow_as_completed_utility(client: Client): @workflow.defn class WaitWorkflow: @workflow.run - async def run(self) -> List[str]: + async def run(self) -> list[str]: # Create 10 tasks that return activity names, wait on them, then execute # the activities async def new_activity_name(index: int) -> str: @@ -5360,10 +5359,10 @@ async def test_workflow_wait_utility(client: Client): @workflow.defn class CurrentUpdateWorkflow: def __init__(self) -> None: - self._pending_get_update_id_tasks: List[asyncio.Task[str]] = [] + self._pending_get_update_id_tasks: list[asyncio.Task[str]] = [] @workflow.run - async def run(self) -> List[str]: + async def run(self) -> list[str]: # Confirm no update info assert not workflow.current_update_info() @@ -5561,8 +5560,8 @@ async def _workflow_task_failed(self, workflow_id: str) -> bool: async def _get_workflow_result_and_warning( self, wait_all_handlers_finished: bool, - unfinished_policy: Optional[workflow.HandlerUnfinishedPolicy] = None, - ) -> Tuple[bool, bool]: + unfinished_policy: workflow.HandlerUnfinishedPolicy | None = None, + ) -> tuple[bool, bool]: with pytest.WarningsRecorder() as warnings: wf_result = await self._get_workflow_result( wait_all_handlers_finished, unfinished_policy @@ -5576,8 +5575,8 @@ async def _get_workflow_result_and_warning( async def _get_workflow_result( self, wait_all_handlers_finished: bool, - unfinished_policy: Optional[workflow.HandlerUnfinishedPolicy] = None, - handle_future: Optional[asyncio.Future[WorkflowHandle]] = None, + unfinished_policy: workflow.HandlerUnfinishedPolicy | None = None, + handle_future: asyncio.Future[WorkflowHandle] | None = None, ) -> bool: handle = await self.client.start_workflow( UnfinishedHandlersWarningsWorkflow.run, @@ -5605,7 +5604,7 @@ async def _get_workflow_result( return await handle.result() @property - def _unfinished_handler_warning_cls(self) -> Type: + def _unfinished_handler_warning_cls(self) -> type: return { "update": workflow.UnfinishedUpdateHandlersWarning, "signal": workflow.UnfinishedSignalHandlersWarning, @@ -5858,7 +5857,7 @@ async def _run_workflow_and_get_warning(self) -> bool: return unfinished_handler_warning_emitted @property - def _unfinished_handler_warning_cls(self) -> Type: + def _unfinished_handler_warning_cls(self) -> type: return { "-update-": workflow.UnfinishedUpdateHandlersWarning, "-signal-": workflow.UnfinishedSignalHandlersWarning, @@ -6087,10 +6086,10 @@ async def test_workflow_return_is_honored_when_it_precedes_signal_completion_com async def _do_first_completion_command_is_honored_test( client: Client, main_workflow_returns_before_signal_completions: bool ): - workflow_cls: Union[ - Type[FirstCompletionCommandIsHonoredSignalWaitWorkflow], - Type[FirstCompletionCommandIsHonoredWorkflow], - ] = ( + workflow_cls: ( + type[FirstCompletionCommandIsHonoredSignalWaitWorkflow] + | type[FirstCompletionCommandIsHonoredWorkflow] + ) = ( FirstCompletionCommandIsHonoredSignalWaitWorkflow if main_workflow_returns_before_signal_completions else FirstCompletionCommandIsHonoredWorkflow @@ -6258,7 +6257,7 @@ async def run(self, _: str) -> str: ], ) async def test_update_in_first_wft_sees_workflow_init( - client: Client, client_cls: Type, worker_cls: Type + client: Client, client_cls: type, worker_cls: type ): """ Test how @workflow.init affects what an update in the first WFT sees. @@ -6273,13 +6272,13 @@ async def test_update_in_first_wft_sees_workflow_init( task_queue = "task-queue" update_id = "update-id" wf_handle = await client.start_workflow( - client_cls.run, + getattr(client_cls, "run"), "workflow input value", id=str(uuid.uuid4()), task_queue=task_queue, ) update_task = asyncio.create_task( - wf_handle.execute_update(client_cls.my_update, id=update_id) + wf_handle.execute_update(getattr(client_cls, "my_update"), id=update_id) ) await assert_eq_eventually( True, lambda: workflow_update_exists(client, wf_handle.id, update_id) @@ -6287,7 +6286,7 @@ async def test_update_in_first_wft_sees_workflow_init( # When the worker starts polling it will receive a first WFT containing the # update, in addition to the start_workflow job. async with new_worker(client, worker_cls, task_queue=task_queue): - assert await update_task == worker_cls._expected_update_result + assert await update_task == getattr(worker_cls, "_expected_update_result") assert await wf_handle.result() == "set in run method" @@ -6596,7 +6595,7 @@ async def test_bad_failure_converter(client: Client): task_queue=worker.task_queue, ) - async def task_failed_message() -> Optional[str]: + async def task_failed_message() -> str | None: async for e in handle.fetch_history_events(): if e.HasField("workflow_task_failed_event_attributes"): return e.workflow_task_failed_event_attributes.failure.message @@ -6617,10 +6616,10 @@ class SignalsActivitiesTimersUpdatesTracingWorkflow: """ def __init__(self) -> None: - self.events: List[str] = [] + self.events: list[str] = [] @workflow.run - async def run(self) -> List[str]: + async def run(self) -> list[str]: tt = asyncio.create_task(self.run_timer()) at = asyncio.create_task(self.run_act()) await asyncio.gather(tt, at) @@ -6700,11 +6699,11 @@ async def test_async_loop_ordering(client: Client, env: WorkflowEnvironment): @workflow.defn class ActivityAndSignalsWhileWorkflowDown: def __init__(self) -> None: - self.events: List[str] = [] + self.events: list[str] = [] self.counter = 0 @workflow.run - async def run(self, activity_tq: str) -> List[str]: + async def run(self, activity_tq: str) -> list[str]: act_task = asyncio.create_task(self.run_act(activity_tq)) await workflow.wait_condition(lambda: self.counter >= 2) self.events.append(f"counter-{self.counter}") @@ -6790,16 +6789,16 @@ class LockOrSemaphoreWorkflowConcurrencySummary: @dataclass class UseLockOrSemaphoreWorkflowParameters: n_coroutines: int = 0 - semaphore_initial_value: Optional[int] = None - sleep: Optional[float] = None - timeout: Optional[float] = None + semaphore_initial_value: int | None = None + sleep: float | None = None + timeout: float | None = None @workflow.defn class CoroutinesUseLockOrSemaphoreWorkflow: def __init__(self) -> None: self.params: UseLockOrSemaphoreWorkflowParameters - self.lock_or_semaphore: Union[asyncio.Lock, asyncio.Semaphore] + self.lock_or_semaphore: asyncio.Lock | asyncio.Semaphore self._currently_in_critical_section: set[str] = set() self._ever_in_critical_section: set[str] = set() self._peak_in_critical_section = 0 @@ -6816,7 +6815,7 @@ def init(self, params: UseLockOrSemaphoreWorkflowParameters): @workflow.run async def run( self, - params: Optional[UseLockOrSemaphoreWorkflowParameters], + params: UseLockOrSemaphoreWorkflowParameters | None, ) -> LockOrSemaphoreWorkflowConcurrencySummary: # TODO: Use workflow init method when it exists. assert params @@ -6874,7 +6873,7 @@ def __init__(self) -> None: @workflow.run async def run( self, - params: Optional[UseLockOrSemaphoreWorkflowParameters] = None, + params: UseLockOrSemaphoreWorkflowParameters | None = None, ) -> LockOrSemaphoreWorkflowConcurrencySummary: await workflow.wait_condition(lambda: self.workflow_may_exit) return LockOrSemaphoreWorkflowConcurrencySummary( @@ -7373,9 +7372,7 @@ async def check_priority_activity(should_have_priorty: int) -> str: @workflow.defn class WorkflowUsingPriorities: @workflow.run - async def run( - self, expected_priority: Optional[int], stop_after_check: bool - ) -> str: + async def run(self, expected_priority: int | None, stop_after_check: bool) -> str: assert workflow.info().priority.priority_key == expected_priority if stop_after_check: return "Done!" @@ -7473,7 +7470,7 @@ def unblock(self) -> None: self.blocked = False @workflow.run - async def run(self) -> Optional[temporalio.workflow.RootInfo]: + async def run(self) -> temporalio.workflow.RootInfo | None: await workflow.wait_condition(lambda: not self.blocked) return workflow.info().root @@ -7481,7 +7478,7 @@ async def run(self) -> Optional[temporalio.workflow.RootInfo]: @workflow.defn class ExposeRootWorkflow: @workflow.run - async def run(self, child_wf_id: str) -> Optional[temporalio.workflow.RootInfo]: + async def run(self, child_wf_id: str) -> temporalio.workflow.RootInfo | None: return await workflow.execute_child_workflow( ExposeRootChildWorkflow.run, id=child_wf_id ) @@ -7672,7 +7669,7 @@ async def test_workflow_missing_local_activity_no_activities(client: Client): @activity.defn async def heartbeat_activity( catch_err: bool = True, -) -> Optional[temporalio.activity.ActivityCancellationDetails]: +) -> temporalio.activity.ActivityCancellationDetails | None: while True: try: activity.heartbeat() @@ -7691,7 +7688,7 @@ async def heartbeat_activity( @activity.defn def sync_heartbeat_activity( catch_err: bool = True, -) -> Optional[temporalio.activity.ActivityCancellationDetails]: +) -> temporalio.activity.ActivityCancellationDetails | None: while True: try: activity.heartbeat() @@ -7712,7 +7709,7 @@ class ActivityHeartbeatWorkflow: @workflow.run async def run( self, activity_id: str - ) -> list[Optional[temporalio.activity.ActivityCancellationDetails]]: + ) -> list[temporalio.activity.ActivityCancellationDetails | None]: result = [] result.append( await workflow.execute_activity( @@ -7791,7 +7788,7 @@ class ActivityHeartbeatPauseUnpauseWorkflow: @workflow.run async def run( self, activity_id: str - ) -> list[Optional[temporalio.activity.ActivityCancellationDetails]]: + ) -> list[temporalio.activity.ActivityCancellationDetails | None]: results = [] results.append( await workflow.execute_activity( @@ -8069,7 +8066,7 @@ async def test_in_workflow_sync(client: Client): class SignalInterceptor(temporalio.worker.Interceptor): def workflow_interceptor_class( self, input: temporalio.worker.WorkflowInterceptorClassInput - ) -> Type[SignalInboundInterceptor]: + ) -> type[SignalInboundInterceptor]: return SignalInboundInterceptor @@ -8104,7 +8101,7 @@ def intercept_activity( def workflow_interceptor_class( self, input: temporalio.worker.WorkflowInterceptorClassInput - ) -> Optional[Type[temporalio.worker.WorkflowInboundInterceptor]]: + ) -> type[temporalio.worker.WorkflowInboundInterceptor] | None: return HeaderWorkflowInboundInterceptor @@ -8311,7 +8308,7 @@ def __init__( super().__init__() self.key_id = key_id - async def encode(self, payloads: Sequence[Payload]) -> List[Payload]: + async def encode(self, payloads: Sequence[Payload]) -> list[Payload]: # We blindly encode all payloads with the key and set the metadata # saying which key we used return [ @@ -8325,8 +8322,8 @@ async def encode(self, payloads: Sequence[Payload]) -> List[Payload]: for p in payloads ] - async def decode(self, payloads: Sequence[Payload]) -> List[Payload]: - ret: List[Payload] = [] + async def decode(self, payloads: Sequence[Payload]) -> list[Payload]: + ret: list[Payload] = [] for p in payloads: # Ignore ones w/out our expected encoding if p.metadata.get("encoding", b"").decode() != "binary/encrypted": diff --git a/tests/worker/workflow_sandbox/test_restrictions.py b/tests/worker/workflow_sandbox/test_restrictions.py index 4109f952b..27310c1ed 100644 --- a/tests/worker/workflow_sandbox/test_restrictions.py +++ b/tests/worker/workflow_sandbox/test_restrictions.py @@ -45,12 +45,12 @@ def test_workflow_sandbox_restrictions_add_passthrough_modules(): @dataclass class RestrictableObject: - foo: Optional[RestrictableObject] = None + foo: RestrictableObject | None = None bar: int = 42 baz: ClassVar[int] = 57 qux: ClassVar[RestrictableObject] - some_dict: Optional[Dict] = None + some_dict: dict | None = None RestrictableObject.qux = RestrictableObject(foo=RestrictableObject(bar=70), bar=80) diff --git a/tests/worker/workflow_sandbox/test_runner.py b/tests/worker/workflow_sandbox/test_runner.py index 463f78089..5dc1bd02d 100644 --- a/tests/worker/workflow_sandbox/test_runner.py +++ b/tests/worker/workflow_sandbox/test_runner.py @@ -8,10 +8,11 @@ import sys import time import uuid +from collections.abc import Callable, Sequence from dataclasses import dataclass from datetime import date, datetime, timedelta from enum import IntEnum -from typing import Any, Callable, Dict, List, Optional, Sequence, Set, Type +from typing import Any, Dict, List, Optional, Set, Type import pytest @@ -68,7 +69,7 @@ def __init__(self) -> None: self.append("inited") @workflow.run - async def run(self, params: GlobalStateWorkflowParams) -> Dict[str, List[str]]: + async def run(self, params: GlobalStateWorkflowParams) -> dict[str, list[str]]: self.append("started") if params.fail_on_first_attempt: raise ApplicationError("Failing first attempt") @@ -82,7 +83,7 @@ def append(self, str: str) -> None: stateful_module.module_state.append(str) @workflow.query - def state(self) -> Dict[str, List[str]]: + def state(self) -> dict[str, list[str]]: return {"global": global_state, "module": stateful_module.module_state} @@ -97,7 +98,7 @@ def state(self) -> Dict[str, List[str]]: ) async def test_workflow_sandbox_global_state( client: Client, - sandboxed_passthrough_modules: Set[str], + sandboxed_passthrough_modules: set[str], ): global global_state async with new_worker( @@ -107,7 +108,7 @@ async def test_workflow_sandbox_global_state( ) as worker: # Start several workflows in the sandbox and make sure none of it # clashes - handles: List[WorkflowHandle] = [] + handles: list[WorkflowHandle] = [] for _ in range(10): handles.append( await client.start_workflow( @@ -429,7 +430,7 @@ async def test_workflow_sandbox_known_issues(client: Client): @workflow.defn class BadAsyncioWorkflow: @workflow.run - async def run(self) -> List[str]: + async def run(self) -> list[str]: # Two known bad asyncio task calls, as_completed and wait async def return_value(value: str) -> str: return value @@ -468,11 +469,11 @@ async def test_workflow_sandbox_bad_asyncio(client: Client): def new_worker( client: Client, - *workflows: Type, + *workflows: type, activities: Sequence[Callable] = [], - task_queue: Optional[str] = None, - sandboxed_passthrough_modules: Set[str] = set(), - sandboxed_invalid_module_members: Optional[SandboxMatcher] = None, + task_queue: str | None = None, + sandboxed_passthrough_modules: set[str] = set(), + sandboxed_invalid_module_members: SandboxMatcher | None = None, ) -> Worker: restrictions = SandboxRestrictions.default if sandboxed_passthrough_modules: @@ -507,7 +508,7 @@ async def execute_workflow(self, input: ExecuteWorkflowInput) -> Any: class _TestInterceptor(Interceptor): def workflow_interceptor_class( self, input: WorkflowInterceptorClassInput - ) -> Type[_TestWorkflowInboundInterceptor]: + ) -> type[_TestWorkflowInboundInterceptor]: return _TestWorkflowInboundInterceptor @@ -654,7 +655,7 @@ async def test_workflow_sandbox_import_suppress_warnings(client: Client): def _assert_expected_warnings( - recorder: pytest.WarningsRecorder, expected_warnings: Set[str] + recorder: pytest.WarningsRecorder, expected_warnings: set[str] ): actual_warnings = {str(w.message) for w in recorder} assert expected_warnings <= actual_warnings From e5aa5abdc247f3dd4e9b452658dc81ca1fc0ebb2 Mon Sep 17 00:00:00 2001 From: Tim Conley Date: Wed, 3 Dec 2025 13:55:17 -0800 Subject: [PATCH 02/10] Fix converter test --- tests/test_converter.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/test_converter.py b/tests/test_converter.py index da6fb8d54..9744fcffa 100644 --- a/tests/test_converter.py +++ b/tests/test_converter.py @@ -440,7 +440,12 @@ def fail(hint: Any, value: Any) -> None: ok(dict[int, str], {1: "1"}) ok(dict[float, str], {1.0: "1"}) ok(dict[bool, str], {True: "1"}) - ok(dict[None, str], {None: "1"}) + + # On a 3.10+ dict type, None isn't returned from a key. This is potentially a bug + ok(dict[None, str], {'null': "1"}) + + # Dict has a different value for None keys + ok(Dict[None, str], {None: "1"}) # Alias ok(MyDataClassAlias, MyDataClass("foo", 5, SerializableEnum.FOO)) @@ -462,11 +467,6 @@ def fail(hint: Any, value: Any) -> None: [SerializableStrEnum.FOO, SerializableStrEnum.FOO], ) - # 3.10+ checks - ok(list[int], [1, 2]) - ok(dict[str, int], {"1": 2}) - ok(tuple[int, str], (1, "2")) - # Pydantic # TODO(cretz): Fix when https://github.com/pydantic/pydantic/pull/9612 tagged if sys.version_info <= (3, 12, 3): From abba12a26fbc9a3acca38d738950e3d89f5018d0 Mon Sep 17 00:00:00 2001 From: Tim Conley Date: Wed, 3 Dec 2025 13:59:13 -0800 Subject: [PATCH 03/10] Formatting --- temporalio/worker/_workflow_instance.py | 2 +- tests/test_converter.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/temporalio/worker/_workflow_instance.py b/temporalio/worker/_workflow_instance.py index ce70abc01..1139be042 100644 --- a/temporalio/worker/_workflow_instance.py +++ b/temporalio/worker/_workflow_instance.py @@ -2185,7 +2185,7 @@ def _instantiate_workflow_object(self) -> Any: if not self._workflow_input: raise RuntimeError("Expected workflow input. This is a Python SDK bug.") - if hasattr(self._defn.cls.__init__, "__temporal_workflow_init"): # type:ignore[misc] + if hasattr(self._defn.cls.__init__, "__temporal_workflow_init"): # type:ignore[misc] workflow_instance = self._defn.cls(*self._workflow_input.args) else: workflow_instance = self._defn.cls() diff --git a/tests/test_converter.py b/tests/test_converter.py index 9744fcffa..edfef2ebb 100644 --- a/tests/test_converter.py +++ b/tests/test_converter.py @@ -442,7 +442,7 @@ def fail(hint: Any, value: Any) -> None: ok(dict[bool, str], {True: "1"}) # On a 3.10+ dict type, None isn't returned from a key. This is potentially a bug - ok(dict[None, str], {'null': "1"}) + ok(dict[None, str], {"null": "1"}) # Dict has a different value for None keys ok(Dict[None, str], {None: "1"}) From ec25155cec60b18280389612ede1b77086c7b838 Mon Sep 17 00:00:00 2001 From: Tim Conley Date: Wed, 3 Dec 2025 15:11:04 -0800 Subject: [PATCH 04/10] Change generator --- scripts/gen_bridge_client.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/gen_bridge_client.py b/scripts/gen_bridge_client.py index bdb5f5573..777f4d5ae 100644 --- a/scripts/gen_bridge_client.py +++ b/scripts/gen_bridge_client.py @@ -27,7 +27,7 @@ def generate_python_services( from __future__ import annotations from datetime import timedelta -from typing import Mapping, Optional, Union, TYPE_CHECKING +from typing import Mapping, TYPE_CHECKING import google.protobuf.empty_pb2 $service_imports @@ -110,8 +110,8 @@ async def $method_name( self, req: $request_type, retry: bool = False, - metadata: Mapping[str, Union[str, bytes]] = {}, - timeout: Optional[timedelta] = None, + metadata: Mapping[str, str | bytes] = {}, + timeout: timedelta | None = None, ) -> $response_type: """Invokes the $service_name.$method_name rpc method.""" return await self._client._rpc_call( From 6ee7a5211a1d49120323936aaf317340cd92e761 Mon Sep 17 00:00:00 2001 From: Tim Conley Date: Thu, 4 Dec 2025 08:59:46 -0800 Subject: [PATCH 05/10] Regen protos --- temporalio/bridge/_visitor.py | 3 +-- temporalio/bridge/services_generated.py | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/temporalio/bridge/_visitor.py b/temporalio/bridge/_visitor.py index e0396cd8d..04ec95b3e 100644 --- a/temporalio/bridge/_visitor.py +++ b/temporalio/bridge/_visitor.py @@ -1,7 +1,6 @@ # This file is generated by gen_payload_visitor.py. Changes should be made there. import abc -from collections.abc import MutableSequence -from typing import Any +from typing import Any, MutableSequence from temporalio.api.common.v1.message_pb2 import Payload diff --git a/temporalio/bridge/services_generated.py b/temporalio/bridge/services_generated.py index ea9af6de7..d5d9eeebf 100644 --- a/temporalio/bridge/services_generated.py +++ b/temporalio/bridge/services_generated.py @@ -3,9 +3,8 @@ from __future__ import annotations -from collections.abc import Mapping from datetime import timedelta -from typing import TYPE_CHECKING, Optional, Union +from typing import TYPE_CHECKING, Mapping import google.protobuf.empty_pb2 From fde50c170859bf1ad7b7c7445ced4a743e27cd4d Mon Sep 17 00:00:00 2001 From: Tim Conley Date: Thu, 4 Dec 2025 09:01:14 -0800 Subject: [PATCH 06/10] Regen protos --- scripts/gen_bridge_client.py | 4 +++- temporalio/bridge/services_generated.py | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/scripts/gen_bridge_client.py b/scripts/gen_bridge_client.py index 777f4d5ae..d49cf14cb 100644 --- a/scripts/gen_bridge_client.py +++ b/scripts/gen_bridge_client.py @@ -27,7 +27,9 @@ def generate_python_services( from __future__ import annotations from datetime import timedelta -from typing import Mapping, TYPE_CHECKING +from typing import TYPE_CHECKING +from collections.abc import Mapping + import google.protobuf.empty_pb2 $service_imports diff --git a/temporalio/bridge/services_generated.py b/temporalio/bridge/services_generated.py index d5d9eeebf..34261a18a 100644 --- a/temporalio/bridge/services_generated.py +++ b/temporalio/bridge/services_generated.py @@ -3,8 +3,9 @@ from __future__ import annotations +from collections.abc import Mapping from datetime import timedelta -from typing import TYPE_CHECKING, Mapping +from typing import TYPE_CHECKING import google.protobuf.empty_pb2 From 6c0116ebf6bbc37e925935cb2c51c65f6b897546 Mon Sep 17 00:00:00 2001 From: Tim Conley Date: Thu, 4 Dec 2025 10:09:46 -0800 Subject: [PATCH 07/10] Manually fix/ignore errors --- temporalio/contrib/openai_agents/_trace_interceptor.py | 1 + temporalio/runtime.py | 1 + tests/helpers/fork.py | 4 ++-- tests/nexus/test_handler.py | 4 ++-- tests/nexus/test_workflow_caller.py | 2 +- tests/nexus/test_workflow_caller_cancellation_types.py | 2 +- ...w_caller_cancellation_types_when_cancel_handler_fails.py | 2 +- tests/test_client.py | 4 ++-- tests/worker/test_worker.py | 6 +++--- 9 files changed, 14 insertions(+), 12 deletions(-) diff --git a/temporalio/contrib/openai_agents/_trace_interceptor.py b/temporalio/contrib/openai_agents/_trace_interceptor.py index ffa22cc16..273f3aede 100644 --- a/temporalio/contrib/openai_agents/_trace_interceptor.py +++ b/temporalio/contrib/openai_agents/_trace_interceptor.py @@ -138,6 +138,7 @@ def __init__( payload_converter: The payload converter to use for serializing/deserializing trace context. Defaults to the default Temporal payload converter. """ + super().__init__() self._payload_converter = payload_converter def intercept_client( diff --git a/temporalio/runtime.py b/temporalio/runtime.py index acd9f17df..ae93e5fda 100644 --- a/temporalio/runtime.py +++ b/temporalio/runtime.py @@ -30,6 +30,7 @@ def __init__( ) -> None: self._default_runtime: Runtime | None = None self._prevent_default = False + self._default_created = False def default(self) -> Runtime: if not self._default_runtime: diff --git a/tests/helpers/fork.py b/tests/helpers/fork.py index e6d84652f..f6b6178ac 100644 --- a/tests/helpers/fork.py +++ b/tests/helpers/fork.py @@ -41,7 +41,7 @@ def assertion_error(message: str) -> _ForkTestResult: class _TestFork: - _expected: _ForkTestResult + _expected: _ForkTestResult # type:ignore[reportUninitializedInstanceVariable] async def coro(self) -> Any: raise NotImplementedError() @@ -66,7 +66,7 @@ def run(self, mp_fork_context: multiprocessing.context.BaseContext | None): if not mp_fork_context or not process_factory: pytest.skip("fork context not available") - self._parent_conn, self._child_conn = mp_fork_context.Pipe(duplex=False) + self._parent_conn, self._child_conn = mp_fork_context.Pipe(duplex=False) # type:ignore[reportUninitializedInstanceVariable] # start fork child_process = process_factory(target=self.entry, args=(), daemon=False) child_process.start() diff --git a/tests/nexus/test_handler.py b/tests/nexus/test_handler.py index 2bb10ae43..e3ba639a7 100644 --- a/tests/nexus/test_handler.py +++ b/tests/nexus/test_handler.py @@ -318,11 +318,11 @@ class UnsuccessfulResponse: class _TestCase: - operation: str + operation: str # type:ignore[reportUninitializedInstanceVariable] service_defn: str = "MyService" input: Input = Input("") headers: dict[str, str] = {} - expected: SuccessfulResponse + expected: SuccessfulResponse # type:ignore[reportUninitializedInstanceVariable] expected_without_service_definition: SuccessfulResponse | None = None skip = "" diff --git a/tests/nexus/test_workflow_caller.py b/tests/nexus/test_workflow_caller.py index b065dc903..3d4b4f699 100644 --- a/tests/nexus/test_workflow_caller.py +++ b/tests/nexus/test_workflow_caller.py @@ -237,7 +237,7 @@ def __init__( request_cancel: bool, task_queue: str, ) -> None: - self.nexus_client: workflow.NexusClient[ServiceInterface] = ( + self.nexus_client: workflow.NexusClient[ServiceInterface] = ( # type:ignore[reportAttributeAccessIssue] workflow.create_nexus_client( service={ CallerReference.IMPL_WITH_INTERFACE: ServiceImpl, diff --git a/tests/nexus/test_workflow_caller_cancellation_types.py b/tests/nexus/test_workflow_caller_cancellation_types.py index 16cfb8805..3e2f43e2a 100644 --- a/tests/nexus/test_workflow_caller_cancellation_types.py +++ b/tests/nexus/test_workflow_caller_cancellation_types.py @@ -68,7 +68,7 @@ class Service: class WorkflowOpHandler( temporalio.nexus._operation_handlers.WorkflowRunOperationHandler ): - def __init__(self): + def __init__(self): # type:ignore[reportMissingSuperCall] pass async def start( diff --git a/tests/nexus/test_workflow_caller_cancellation_types_when_cancel_handler_fails.py b/tests/nexus/test_workflow_caller_cancellation_types_when_cancel_handler_fails.py index c9cb71807..3114cb357 100644 --- a/tests/nexus/test_workflow_caller_cancellation_types_when_cancel_handler_fails.py +++ b/tests/nexus/test_workflow_caller_cancellation_types_when_cancel_handler_fails.py @@ -79,7 +79,7 @@ class Service: class WorkflowOpHandler( temporalio.nexus._operation_handlers.WorkflowRunOperationHandler ): - def __init__(self): + def __init__(self): # type:ignore[reportMissingSuperCall] pass async def start( diff --git a/tests/test_client.py b/tests/test_client.py index 791c59b2d..0ce6a4fea 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -1561,7 +1561,7 @@ def test_fork_create_client( self._expected = _ForkTestResult.assertion_error( "Cannot create client across forks" ) - self._env = env + self._env = env # type:ignore[reportUninitializedInstanceVariable] self.run(mp_fork_ctx) @@ -1579,5 +1579,5 @@ def test_fork_use_client( self._expected = _ForkTestResult.assertion_error( "Cannot use client across forks" ) - self._client = client + self._client = client # type:ignore[reportUninitializedInstanceVariable] self.run(mp_fork_ctx) diff --git a/tests/worker/test_worker.py b/tests/worker/test_worker.py index 9779bc633..483a58cbb 100644 --- a/tests/worker/test_worker.py +++ b/tests/worker/test_worker.py @@ -1228,7 +1228,7 @@ def shutdown(self) -> None: class TestForkCreateWorker(_TestFork): async def coro(self): - self._worker = Worker( + self._worker = Worker( # type:ignore[reportUninitializedInstanceVariable] self._client, task_queue=f"task-queue-{uuid.uuid4()}", activities=[never_run_activity], @@ -1242,7 +1242,7 @@ def test_fork_create_worker( self._expected = _ForkTestResult.assertion_error( "Cannot create worker across forks" ) - self._client = client + self._client = client # type:ignore[reportUninitializedInstanceVariable] self.run(mp_fork_ctx) @@ -1256,7 +1256,7 @@ def test_fork_use_worker( self._expected = _ForkTestResult.assertion_error( "Cannot use worker across forks" ) - self._pre_fork_worker = Worker( + self._pre_fork_worker = Worker( # type:ignore[reportUninitializedInstanceVariable] client, task_queue=f"task-queue-{uuid.uuid4()}", activities=[never_run_activity], From 3c292571ba8c5f75dba68470cac967fa7cdb3c29 Mon Sep 17 00:00:00 2001 From: Tim Conley Date: Thu, 4 Dec 2025 12:57:18 -0800 Subject: [PATCH 08/10] Fix basedpyright errors --- pyproject.toml | 2 + scripts/gen_protos.py | 1 - temporalio/activity.py | 7 +- temporalio/client.py | 29 +++--- temporalio/common.py | 26 ++---- temporalio/contrib/openai_agents/__init__.py | 3 - .../openai_agents/_heartbeat_decorator.py | 2 +- .../openai_agents/_invoke_model_activity.py | 30 +++--- temporalio/contrib/openai_agents/_mcp.py | 22 +++-- .../openai_agents/_model_parameters.py | 3 +- .../contrib/openai_agents/_openai_runner.py | 2 +- .../openai_agents/_temporal_model_stub.py | 36 +------- .../openai_agents/_temporal_openai_agents.py | 3 +- .../openai_agents/_temporal_trace_provider.py | 2 +- .../openai_agents/_trace_interceptor.py | 2 +- temporalio/contrib/openai_agents/testing.py | 8 +- temporalio/contrib/openai_agents/workflow.py | 6 +- temporalio/contrib/opentelemetry.py | 3 - temporalio/contrib/pydantic.py | 2 +- temporalio/converter.py | 29 +++--- temporalio/exceptions.py | 3 +- temporalio/nexus/_decorators.py | 2 - temporalio/nexus/_link_conversion.py | 3 +- temporalio/nexus/_operation_context.py | 4 +- temporalio/nexus/_token.py | 2 +- temporalio/nexus/_util.py | 2 - temporalio/plugin.py | 14 ++- temporalio/runtime.py | 2 - temporalio/service.py | 5 +- temporalio/testing/_activity.py | 4 +- temporalio/testing/_workflow.py | 17 ++-- temporalio/types.py | 6 +- temporalio/worker/__init__.py | 2 +- temporalio/worker/_activity.py | 4 +- temporalio/worker/_command_aware_visitor.py | 1 - temporalio/worker/_interceptor.py | 9 +- temporalio/worker/_nexus.py | 14 ++- temporalio/worker/_tuning.py | 23 ++--- temporalio/worker/_workflow.py | 18 +--- temporalio/worker/_workflow_instance.py | 35 +++---- .../worker/workflow_sandbox/_in_sandbox.py | 2 +- temporalio/worker/workflow_sandbox/_runner.py | 2 +- tests/bridge/test_runtime.py | 1 - tests/contrib/openai_agents/test_openai.py | 91 +++++-------------- .../openai_agents/test_openai_tracing.py | 2 +- tests/contrib/pydantic/activities.py | 1 - tests/helpers/__init__.py | 8 +- tests/helpers/external_coroutine.py | 2 - tests/helpers/fork.py | 3 +- tests/helpers/nexus.py | 4 +- tests/helpers/worker.py | 4 +- ...ynamic_creation_of_user_handler_classes.py | 4 +- tests/nexus/test_handler.py | 26 +++--- tests/nexus/test_handler_async_operation.py | 2 +- .../test_handler_interface_implementation.py | 2 +- .../test_handler_operation_definitions.py | 8 +- .../test_use_existing_conflict_policy.py | 1 - tests/nexus/test_workflow_caller.py | 28 +++--- ...test_workflow_caller_cancellation_types.py | 2 +- ...llation_types_when_cancel_handler_fails.py | 2 +- .../test_workflow_caller_error_chains.py | 4 +- tests/nexus/test_workflow_caller_errors.py | 14 +-- tests/nexus/test_workflow_run_operation.py | 2 +- tests/test_client.py | 16 ++-- tests/test_client_type_errors.py | 10 +- tests/test_common.py | 8 +- tests/test_envconfig.py | 2 +- tests/test_plugins.py | 7 +- tests/test_runtime.py | 3 +- tests/test_serialization_context.py | 8 +- tests/test_workflow.py | 51 +++++------ tests/testing/test_workflow.py | 5 +- tests/worker/test_command_aware_visitor.py | 4 +- tests/worker/test_interceptor.py | 4 +- tests/worker/test_replayer.py | 2 +- tests/worker/test_update_with_start.py | 2 +- tests/worker/test_visitor.py | 8 -- tests/worker/test_worker.py | 32 +++---- tests/worker/test_workflow.py | 43 ++++----- .../workflow_sandbox/test_restrictions.py | 2 +- tests/worker/workflow_sandbox/test_runner.py | 8 +- 81 files changed, 315 insertions(+), 503 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 507eb9d58..a39e4e7d6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -198,10 +198,12 @@ reportUnknownVariableType = "none" reportUnnecessaryIsInstance = "none" reportUnnecessaryTypeIgnoreComment = "none" reportUnusedCallResult = "none" +reportUnknownLambdaType = "none" include = ["temporalio", "tests"] exclude = [ "temporalio/api", "temporalio/bridge/proto", + "temporalio/bridge/_visitor.py", "tests/worker/workflow_sandbox/testmodules/proto", "temporalio/bridge/worker.py", "temporalio/worker/_replayer.py", diff --git a/scripts/gen_protos.py b/scripts/gen_protos.py index 131f094f4..c1d5360b5 100644 --- a/scripts/gen_protos.py +++ b/scripts/gen_protos.py @@ -7,7 +7,6 @@ from collections.abc import Mapping from functools import partial from pathlib import Path -from typing import List base_dir = Path(__file__).parent.parent proto_dir = ( diff --git a/temporalio/activity.py b/temporalio/activity.py index 5d7857161..12d64bb77 100644 --- a/temporalio/activity.py +++ b/temporalio/activity.py @@ -22,12 +22,7 @@ from typing import ( TYPE_CHECKING, Any, - List, NoReturn, - Optional, - Tuple, - Type, - Union, overload, ) @@ -593,7 +588,7 @@ def _apply_to_callable( if hasattr(fn, "__temporal_activity_definition"): raise ValueError("Function already contains activity definition") elif not callable(fn): - raise TypeError("Activity is not callable") + raise TypeError("Activity is not callable") # type:ignore[reportUnreachable] # We do not allow keyword only arguments in activities sig = inspect.signature(fn) for param in sig.parameters.values(): diff --git a/temporalio/client.py b/temporalio/client.py index db912e122..f0a495047 100644 --- a/temporalio/client.py +++ b/temporalio/client.py @@ -28,14 +28,7 @@ from typing import ( Any, Concatenate, - Dict, - FrozenSet, Generic, - Optional, - Text, - Tuple, - Type, - Union, cast, overload, ) @@ -205,7 +198,9 @@ async def connect( http_connect_proxy_config=http_connect_proxy_config, ) - def make_lambda(plugin, next): + def make_lambda( + plugin: Plugin, next: Callable[[ConnectConfig], Awaitable[ServiceClient]] + ): return lambda config: plugin.connect_service_client(config, next) next_function = ServiceClient.connect @@ -1335,8 +1330,8 @@ async def create_schedule( | ( temporalio.common.TypedSearchAttributes | temporalio.common.SearchAttributes ) = None, - static_summary: str | None = None, - static_details: str | None = None, + static_summary: str | None = None, # type:ignore[reportUnusedParameter] # https://github.com/temporalio/sdk-python/issues/1238 + static_details: str | None = None, # type:ignore[reportUnusedParameter] rpc_metadata: Mapping[str, str | bytes] = {}, rpc_timeout: timedelta | None = None, ) -> ScheduleHandle: @@ -3405,7 +3400,7 @@ def next_page_token(self) -> bytes | None: """Token for the next page request if any.""" return self._next_page_token - async def fetch_next_page(self, *, page_size: int | None = None) -> None: + async def fetch_next_page(self, *, page_size: int | None = None) -> None: # type:ignore[reportUnusedParameter] # https://github.com/temporalio/sdk-python/issues/1239 """Fetch the next page if any. Args: @@ -4156,7 +4151,7 @@ def __init__( raise ValueError("Cannot schedule dynamic workflow explicitly") workflow = defn.name elif not isinstance(workflow, str): - raise TypeError("Workflow must be a string or callable") + raise TypeError("Workflow must be a string or callable") # type:ignore[reportUnreachable] self.workflow = workflow self.args = temporalio.common._arg_or_args(arg, args) self.id = id @@ -6040,9 +6035,9 @@ async def _populate_start_workflow_execution_request( req.user_metadata.CopyFrom(metadata) if input.start_delay is not None: req.workflow_start_delay.FromTimedelta(input.start_delay) - if input.headers is not None: + if input.headers is not None: # type:ignore[reportUnnecessaryComparison] await self._apply_headers(input.headers, req.header.fields) - if input.priority is not None: + if input.priority is not None: # type:ignore[reportUnnecessaryComparison] req.priority.CopyFrom(input.priority._to_proto()) if input.versioning_override is not None: req.versioning_override.CopyFrom(input.versioning_override._to_proto()) @@ -6138,7 +6133,7 @@ async def query_workflow(self, input: QueryWorkflowInput) -> Any: req.query.query_args.payloads.extend( await data_converter.encode(input.args) ) - if input.headers is not None: + if input.headers is not None: # type:ignore[reportUnnecessaryComparison] await self._apply_headers(input.headers, req.query.header.fields) try: resp = await self._client.workflow_service.query_workflow( @@ -6186,7 +6181,7 @@ async def signal_workflow(self, input: SignalWorkflowInput) -> None: ) if input.args: req.input.payloads.extend(await data_converter.encode(input.args)) - if input.headers is not None: + if input.headers is not None: # type:ignore[reportUnnecessaryComparison] await self._apply_headers(input.headers, req.header.fields) await self._client.workflow_service.signal_workflow_execution( req, retry=True, metadata=input.rpc_metadata, timeout=input.rpc_timeout @@ -6307,7 +6302,7 @@ async def _build_update_workflow_execution_request( req.request.input.args.payloads.extend( await data_converter.encode(input.args) ) - if input.headers is not None: + if input.headers is not None: # type:ignore[reportUnnecessaryComparison] await self._apply_headers(input.headers, req.request.input.header.fields) return req diff --git a/temporalio/common.py b/temporalio/common.py index 810f5851e..641a5e7b7 100644 --- a/temporalio/common.py +++ b/temporalio/common.py @@ -14,14 +14,8 @@ Any, ClassVar, Generic, - List, - Optional, - Text, - Tuple, - Type, TypeAlias, TypeVar, - Union, get_origin, get_type_hints, overload, @@ -198,13 +192,13 @@ def __setstate__(self, state: object) -> None: # We choose to make this a list instead of an sequence so we can catch if people # are not sending lists each time but maybe accidentally sending a string (which # is a sequence) -SearchAttributeValues: TypeAlias = Union[ - list[str], list[int], list[float], list[bool], list[datetime] -] +SearchAttributeValues: TypeAlias = ( + list[str] | list[int] | list[float] | list[bool] | list[datetime] +) SearchAttributes: TypeAlias = Mapping[str, SearchAttributeValues] -SearchAttributeValue: TypeAlias = Union[str, int, float, bool, datetime, Sequence[str]] +SearchAttributeValue: TypeAlias = str | int | float | bool | datetime | Sequence[str] SearchAttributeValueType = TypeVar( "SearchAttributeValueType", str, int, float, bool, datetime, Sequence[str] @@ -492,7 +486,7 @@ def __contains__(self, key: object) -> bool: This uses key equality so the key must be the same name and type. """ - return any(k == key for k, v in self) + return any(k == key for k, _v in self) @overload def get( @@ -544,7 +538,7 @@ def updated(self, *search_attributes: SearchAttributePair) -> TypedSearchAttribu TypedSearchAttributes.empty = TypedSearchAttributes(search_attributes=[]) -def _warn_on_deprecated_search_attributes( +def _warn_on_deprecated_search_attributes( # type:ignore[reportUnusedFunction] attributes: SearchAttributes | Any | None, stack_level: int = 2, ) -> None: @@ -556,7 +550,7 @@ def _warn_on_deprecated_search_attributes( ) -MetricAttributes: TypeAlias = Mapping[str, Union[str, int, float, bool]] +MetricAttributes: TypeAlias = Mapping[str, str | int | float | bool] class MetricMeter(ABC): @@ -1157,7 +1151,7 @@ def _to_proto(self) -> temporalio.api.workflow.v1.VersioningOverride: _arg_unset = object() -def _arg_or_args(arg: Any, args: Sequence[Any]) -> Sequence[Any]: +def _arg_or_args(arg: Any, args: Sequence[Any]) -> Sequence[Any]: # type:ignore[reportUnusedFunction] if arg is not _arg_unset: if args: raise ValueError("Cannot have arg and args") @@ -1165,7 +1159,7 @@ def _arg_or_args(arg: Any, args: Sequence[Any]) -> Sequence[Any]: return args -def _apply_headers( +def _apply_headers( # type:ignore[reportUnusedFunction] source: Mapping[str, temporalio.api.common.v1.Payload] | None, dest: google.protobuf.internal.containers.MessageMap[ str, temporalio.api.common.v1.Payload @@ -1192,7 +1186,7 @@ def _apply_headers( ) -def _type_hints_from_func( +def _type_hints_from_func( # type:ignore[reportUnusedFunction] func: Callable, ) -> tuple[list[type] | None, type | None]: """Extracts the type hints from the function. diff --git a/temporalio/contrib/openai_agents/__init__.py b/temporalio/contrib/openai_agents/__init__.py index d49733e8b..eeefbff8c 100644 --- a/temporalio/contrib/openai_agents/__init__.py +++ b/temporalio/contrib/openai_agents/__init__.py @@ -17,9 +17,6 @@ OpenAIAgentsPlugin, OpenAIPayloadConverter, ) -from temporalio.contrib.openai_agents._trace_interceptor import ( - OpenAIAgentsTracingInterceptor, -) from temporalio.contrib.openai_agents.workflow import AgentsWorkflowError from . import testing, workflow diff --git a/temporalio/contrib/openai_agents/_heartbeat_decorator.py b/temporalio/contrib/openai_agents/_heartbeat_decorator.py index 2fae11d7d..4baff6706 100644 --- a/temporalio/contrib/openai_agents/_heartbeat_decorator.py +++ b/temporalio/contrib/openai_agents/_heartbeat_decorator.py @@ -8,7 +8,7 @@ F = TypeVar("F", bound=Callable[..., Awaitable[Any]]) -def _auto_heartbeater(fn: F) -> F: +def _auto_heartbeater(fn: F) -> F: # type:ignore[reportUnusedClass] # Propagate type hints from the original callable. @wraps(fn) async def wrapper(*args: Any, **kwargs: Any) -> Any: diff --git a/temporalio/contrib/openai_agents/_invoke_model_activity.py b/temporalio/contrib/openai_agents/_invoke_model_activity.py index f03458c32..945a05ec6 100644 --- a/temporalio/contrib/openai_agents/_invoke_model_activity.py +++ b/temporalio/contrib/openai_agents/_invoke_model_activity.py @@ -4,10 +4,9 @@ """ import enum -import json from dataclasses import dataclass from datetime import timedelta -from typing import Any, Optional, Union +from typing import Any from agents import ( AgentOutputSchemaBase, @@ -33,10 +32,9 @@ AsyncOpenAI, ) from openai.types.responses.tool_param import Mcp -from pydantic_core import to_json from typing_extensions import Required, TypedDict -from temporalio import activity, workflow +from temporalio import activity from temporalio.contrib.openai_agents._heartbeat_decorator import _auto_heartbeater from temporalio.exceptions import ApplicationError @@ -75,14 +73,14 @@ class HostedMCPToolInput: tool_config: Mcp -ToolInput = Union[ - FunctionToolInput, - FileSearchTool, - WebSearchTool, - ImageGenerationTool, - CodeInterpreterTool, - HostedMCPToolInput, -] +ToolInput = ( + FunctionToolInput + | FileSearchTool + | WebSearchTool + | ImageGenerationTool + | CodeInterpreterTool + | HostedMCPToolInput +) @dataclass @@ -165,11 +163,13 @@ async def invoke_model_activity(self, input: ActivityModelInput) -> ModelRespons """Activity that invokes a model with the given input.""" model = self._model_provider.get_model(input.get("model_name")) - async def empty_on_invoke_tool(ctx: RunContextWrapper[Any], input: str) -> str: + async def empty_on_invoke_tool( + _ctx: RunContextWrapper[Any], _input: str + ) -> str: return "" async def empty_on_invoke_handoff( - ctx: RunContextWrapper[Any], input: str + _ctx: RunContextWrapper[Any], _input: str ) -> Any: return None @@ -197,7 +197,7 @@ def make_tool(tool: ToolInput) -> Tool: strict_json_schema=tool.strict_json_schema, ) else: - raise UserError(f"Unknown tool type: {tool.name}") + raise UserError(f"Unknown tool type: {tool.name}") # type:ignore[reportUnreachable] tools = [make_tool(x) for x in input.get("tools", [])] handoffs: list[Handoff[Any, Any]] = [ diff --git a/temporalio/contrib/openai_agents/_mcp.py b/temporalio/contrib/openai_agents/_mcp.py index 76d558b82..c9d1f87ea 100644 --- a/temporalio/contrib/openai_agents/_mcp.py +++ b/temporalio/contrib/openai_agents/_mcp.py @@ -1,4 +1,3 @@ -import abc import asyncio import dataclasses import functools @@ -7,7 +6,8 @@ from collections.abc import Callable, Sequence from contextlib import AbstractAsyncContextManager from datetime import timedelta -from typing import Any, Optional, Union, cast +from types import TracebackType +from typing import Any, cast from agents import AgentBase, RunContextWrapper from agents.mcp import MCPServer @@ -23,7 +23,6 @@ from temporalio.exceptions import ( ActivityError, ApplicationError, - CancelledError, is_cancelled_exception, ) from temporalio.worker import PollerBehaviorSimpleMaximum, Worker @@ -56,7 +55,7 @@ class _StatelessGetPromptArguments: factory_argument: Any | None -class _StatelessMCPServerReference(MCPServer): +class _StatelessMCPServerReference(MCPServer): # type:ignore[reportUnusedClass] def __init__( self, server: str, @@ -163,7 +162,7 @@ def __init__( def _create_server(self, factory_argument: Any | None) -> MCPServer: if self._server_accepts_arguments: - return cast(Callable[[Optional[Any]], MCPServer], self._server_factory)( + return cast(Callable[[Any | None], MCPServer], self._server_factory)( factory_argument ) else: @@ -241,9 +240,9 @@ async def get_prompt_deprecated( ) -def _handle_worker_failure(func): +def _handle_worker_failure(func: Callable) -> Callable: @functools.wraps(func) - async def wrapper(*args, **kwargs): + async def wrapper(*args: Any, **kwargs: Any): try: return await func(*args, **kwargs) except ActivityError as e: @@ -289,7 +288,7 @@ class _StatefulServerSessionArguments: factory_argument: Any | None -class _StatefulMCPServerReference(MCPServer, AbstractAsyncContextManager): +class _StatefulMCPServerReference(MCPServer, AbstractAsyncContextManager): # type:ignore[reportUnusedClass] def __init__( self, server: str, @@ -336,7 +335,12 @@ async def __aenter__(self): await self.connect() return self - async def __aexit__(self, exc_type, exc_value, traceback): + async def __aexit__( + self, + exc_type: type[BaseException] | None, + exc_value: BaseException | None, + traceback: TracebackType | None, + ) -> None: await self.cleanup() @_handle_worker_failure diff --git a/temporalio/contrib/openai_agents/_model_parameters.py b/temporalio/contrib/openai_agents/_model_parameters.py index 3cab91c27..55827e0d5 100644 --- a/temporalio/contrib/openai_agents/_model_parameters.py +++ b/temporalio/contrib/openai_agents/_model_parameters.py @@ -1,10 +1,9 @@ """Parameters for configuring Temporal activity execution for model calls.""" from abc import ABC, abstractmethod -from collections.abc import Callable from dataclasses import dataclass from datetime import timedelta -from typing import Any, Optional, Union +from typing import Any from agents import Agent, TResponseInputItem diff --git a/temporalio/contrib/openai_agents/_openai_runner.py b/temporalio/contrib/openai_agents/_openai_runner.py index a8065d207..eeec62799 100644 --- a/temporalio/contrib/openai_agents/_openai_runner.py +++ b/temporalio/contrib/openai_agents/_openai_runner.py @@ -1,6 +1,6 @@ import dataclasses import typing -from typing import Any, Optional, Union +from typing import Any from agents import ( Agent, diff --git a/temporalio/contrib/openai_agents/_temporal_model_stub.py b/temporalio/contrib/openai_agents/_temporal_model_stub.py index f84488541..f55821309 100644 --- a/temporalio/contrib/openai_agents/_temporal_model_stub.py +++ b/temporalio/contrib/openai_agents/_temporal_model_stub.py @@ -1,7 +1,6 @@ from __future__ import annotations import logging -from typing import Optional from temporalio import workflow from temporalio.contrib.openai_agents._model_parameters import ModelActivityParameters @@ -9,7 +8,7 @@ logger = logging.getLogger(__name__) from collections.abc import AsyncIterator -from typing import Any, Union, cast +from typing import Any from agents import ( Agent, @@ -44,7 +43,7 @@ ) -class _TemporalModelStub(Model): +class _TemporalModelStub(Model): # type:ignore[reportUnusedClass] """A stub that allows invoking models as Temporal activities.""" def __init__( @@ -197,34 +196,3 @@ def stream_response( prompt: ResponsePromptParam | None, ) -> AsyncIterator[TResponseStreamEvent]: raise NotImplementedError("Temporal model doesn't support streams yet") - - -def _extract_summary(input: str | list[TResponseInputItem]) -> str: - ### Activity summary shown in the UI - try: - max_size = 100 - if isinstance(input, str): - return input[:max_size] - elif isinstance(input, list): - # Find all message inputs, which are reasonably summarizable - messages: list[TResponseInputItem] = [ - item for item in input if item.get("type", "message") == "message" - ] - if not messages: - return "" - - content: Any = messages[-1].get("content", "") - - # In the case of multiple contents, take the last one - if isinstance(content, list): - if not content: - return "" - content = content[-1] - - # Take the text field from the content if present - if isinstance(content, dict) and content.get("text") is not None: - content = content.get("text") - return str(content)[:max_size] - except Exception as e: - logger.error(f"Error getting summary: {e}") - return "" diff --git a/temporalio/contrib/openai_agents/_temporal_openai_agents.py b/temporalio/contrib/openai_agents/_temporal_openai_agents.py index 41ae419f7..c1ace7a55 100644 --- a/temporalio/contrib/openai_agents/_temporal_openai_agents.py +++ b/temporalio/contrib/openai_agents/_temporal_openai_agents.py @@ -5,7 +5,6 @@ from collections.abc import AsyncIterator, Callable, Sequence from contextlib import asynccontextmanager, contextmanager from datetime import timedelta -from typing import Optional, Union from agents import ModelProvider, set_trace_provider from agents.run import get_default_agent_runner, set_default_agent_runner @@ -179,7 +178,7 @@ def __init__( model_params: ModelActivityParameters | None = None, model_provider: ModelProvider | None = None, mcp_server_providers: Sequence[ - Union["StatelessMCPServerProvider", "StatefulMCPServerProvider"] + "StatelessMCPServerProvider | StatefulMCPServerProvider" ] = (), register_activities: bool = True, ) -> None: diff --git a/temporalio/contrib/openai_agents/_temporal_trace_provider.py b/temporalio/contrib/openai_agents/_temporal_trace_provider.py index 37fe33eca..8ea6cadcb 100644 --- a/temporalio/contrib/openai_agents/_temporal_trace_provider.py +++ b/temporalio/contrib/openai_agents/_temporal_trace_provider.py @@ -2,7 +2,7 @@ import uuid from types import TracebackType -from typing import Any, Optional, cast +from typing import Any, cast from agents import SpanData, Trace, TracingProcessor from agents.tracing import ( diff --git a/temporalio/contrib/openai_agents/_trace_interceptor.py b/temporalio/contrib/openai_agents/_trace_interceptor.py index 273f3aede..d099ae09b 100644 --- a/temporalio/contrib/openai_agents/_trace_interceptor.py +++ b/temporalio/contrib/openai_agents/_trace_interceptor.py @@ -6,7 +6,7 @@ import uuid from collections.abc import Mapping from contextlib import contextmanager -from typing import Any, Optional, Protocol, Type +from typing import Any, Protocol from agents import CustomSpanData, custom_span, get_current_span, trace from agents.tracing import ( diff --git a/temporalio/contrib/openai_agents/testing.py b/temporalio/contrib/openai_agents/testing.py index 4acab196a..c4fea60cb 100644 --- a/temporalio/contrib/openai_agents/testing.py +++ b/temporalio/contrib/openai_agents/testing.py @@ -1,7 +1,7 @@ """Testing utilities for OpenAI agents.""" from collections.abc import AsyncIterator, Callable, Sequence -from typing import Optional, Union +from typing import Any from agents import ( AgentOutputSchemaBase, @@ -161,7 +161,7 @@ async def get_response( output_schema: AgentOutputSchemaBase | None, handoffs: list[Handoff], tracing: ModelTracing, - **kwargs, + **kwargs: Any, ) -> ModelResponse: """Get a response from the mocked model, by calling the callable passed to the constructor.""" return self.fn() @@ -175,7 +175,7 @@ def stream_response( output_schema: AgentOutputSchemaBase | None, handoffs: list[Handoff], tracing: ModelTracing, - **kwargs, + **kwargs: Any, ) -> AsyncIterator[TResponseStreamEvent]: """Get a streamed response from the model. Unimplemented.""" raise NotImplementedError() @@ -268,7 +268,7 @@ async def __aenter__(self) -> "AgentEnvironment": return self - async def __aexit__(self, *args) -> None: + async def __aexit__(self, *args: Any) -> None: """Exit the async context manager.""" # No cleanup needed currently pass diff --git a/temporalio/contrib/openai_agents/workflow.py b/temporalio/contrib/openai_agents/workflow.py index e4738e274..2819a2d7b 100644 --- a/temporalio/contrib/openai_agents/workflow.py +++ b/temporalio/contrib/openai_agents/workflow.py @@ -7,7 +7,7 @@ from collections.abc import Callable from contextlib import AbstractAsyncContextManager from datetime import timedelta -from typing import Any, Optional, Type +from typing import Any import nexusrpc from agents import ( @@ -201,7 +201,7 @@ def nexus_operation_as_tool( >>> # Use tool with an OpenAI agent """ - def operation_callable(input): + def operation_callable(_input: Any): raise NotImplementedError("This function definition is used as a type only") operation_callable.__annotations__ = { @@ -212,7 +212,7 @@ def operation_callable(input): schema = function_schema(operation_callable) - async def run_operation(ctx: RunContextWrapper[Any], input: str) -> Any: + async def run_operation(_ctx: RunContextWrapper[Any], input: str) -> Any: try: json_data = json.loads(input) except Exception as e: diff --git a/temporalio/contrib/opentelemetry.py b/temporalio/contrib/opentelemetry.py index b1a0d6a06..25d263495 100644 --- a/temporalio/contrib/opentelemetry.py +++ b/temporalio/contrib/opentelemetry.py @@ -7,10 +7,7 @@ from dataclasses import dataclass from typing import ( Any, - Dict, NoReturn, - Optional, - Type, TypeAlias, cast, ) diff --git a/temporalio/contrib/pydantic.py b/temporalio/contrib/pydantic.py index 5de19f180..c5f2deb41 100644 --- a/temporalio/contrib/pydantic.py +++ b/temporalio/contrib/pydantic.py @@ -14,7 +14,7 @@ """ from dataclasses import dataclass -from typing import Any, Optional, Type +from typing import Any from pydantic import TypeAdapter from pydantic_core import SchemaSerializer, to_json diff --git a/temporalio/converter.py b/temporalio/converter.py index 8af1e1dc6..e084f38bd 100644 --- a/temporalio/converter.py +++ b/temporalio/converter.py @@ -10,6 +10,7 @@ import json import sys import traceback +import typing import uuid import warnings from abc import ABC, abstractmethod @@ -22,20 +23,13 @@ from typing import ( Any, ClassVar, - Dict, - List, Literal, NewType, - Optional, - Tuple, - Type, TypeVar, - Union, get_type_hints, overload, ) -import google.protobuf.duration_pb2 import google.protobuf.json_format import google.protobuf.message import google.protobuf.symbol_database @@ -46,7 +40,6 @@ import temporalio.api.common.v1 import temporalio.api.enums.v1 import temporalio.api.failure.v1 -import temporalio.api.sdk.v1 import temporalio.common import temporalio.exceptions import temporalio.types @@ -56,7 +49,7 @@ from dateutil import parser # type: ignore # StrEnum is available in 3.11+ if sys.version_info >= (3, 11): - from enum import StrEnum + from enum import StrEnum # type: ignore[reportUnreachable] from types import UnionType @@ -151,7 +144,7 @@ class WithSerializationContext(ABC): to_payload/from_payload, etc) to use the context. """ - def with_context(self, context: SerializationContext) -> Self: + def with_context(self, context: SerializationContext) -> Self: # type: ignore[reportUnusedParameter] """Return a copy of this object configured to use the given context. Args: @@ -549,7 +542,7 @@ def to_payload(self, value: Any) -> temporalio.api.common.v1.Payload | None: """See base class.""" if ( isinstance(value, google.protobuf.message.Message) - and value.DESCRIPTOR is not None + and value.DESCRIPTOR is not None # type:ignore[reportUnnecessaryComparison] ): # We have to convert to dict then to JSON because MessageToJson does # not have a compact option removing spaces and newlines @@ -599,7 +592,7 @@ def to_payload(self, value: Any) -> temporalio.api.common.v1.Payload | None: """See base class.""" if ( isinstance(value, google.protobuf.message.Message) - and value.DESCRIPTOR is not None + and value.DESCRIPTOR is not None # type:ignore[reportUnnecessaryComparison] ): return temporalio.api.common.v1.Payload( metadata={ @@ -1476,7 +1469,7 @@ def encode_search_attribute_values( vals: List of values to convert. """ if not isinstance(vals, list): - raise TypeError("Search attribute values must be lists") + raise TypeError("Search attribute values must be lists") # type:ignore[reportUnreachable] # Confirm all types are the same val_type: type | None = None # Convert dates to strings @@ -1502,7 +1495,7 @@ def encode_search_attribute_values( return default().payload_converter.to_payloads([safe_vals])[0] -def _encode_maybe_typed_search_attributes( +def _encode_maybe_typed_search_attributes( # type:ignore[reportUnusedFunction] non_typed_attributes: temporalio.common.SearchAttributes | None, typed_attributes: temporalio.common.TypedSearchAttributes | None, api: temporalio.api.common.v1.SearchAttributes, @@ -1524,7 +1517,7 @@ def _get_iso_datetime_parser() -> Callable[[str], datetime]: A callable to parse date strings into datetimes. """ if sys.version_info >= (3, 11): - return datetime.fromisoformat # noqa + return datetime.fromisoformat # type:ignore[reportUnreachable] # noqa else: # Isolate import for py > 3.11, as dependency only installed for < 3.11 return parser.isoparse @@ -1607,7 +1600,7 @@ def decode_typed_search_attributes( return temporalio.common.TypedSearchAttributes(pairs) -def _decode_search_attribute_value( +def _decode_search_attribute_value( # type:ignore[reportUnusedFunction] payload: temporalio.api.common.v1.Payload, ) -> temporalio.common.SearchAttributeValue: val = default().payload_converter.from_payload(payload) @@ -1698,7 +1691,7 @@ def value_to_type( raise TypeError(f"Value {value} not in literal values {type_args}") return value - is_union = origin is Union + is_union = origin is typing.Union # type:ignore[reportDeprecated] is_union = is_union or isinstance(origin, UnionType) # Union @@ -1837,7 +1830,7 @@ def value_to_type( # StrEnum, available in 3.11+ if sys.version_info >= (3, 11): - if inspect.isclass(hint) and issubclass(hint, StrEnum): + if inspect.isclass(hint) and issubclass(hint, StrEnum): # type:ignore[reportUnreachable] if not isinstance(value, str): raise TypeError( f"Cannot convert to enum {hint}, value not a string, value is {type(value)}" diff --git a/temporalio/exceptions.py b/temporalio/exceptions.py index 61c04166d..f8f8ca20c 100644 --- a/temporalio/exceptions.py +++ b/temporalio/exceptions.py @@ -4,9 +4,8 @@ from collections.abc import Sequence from datetime import timedelta from enum import IntEnum -from typing import Any, Optional, Tuple +from typing import Any -import temporalio.api.common.v1 import temporalio.api.enums.v1 import temporalio.api.failure.v1 diff --git a/temporalio/nexus/_decorators.py b/temporalio/nexus/_decorators.py index dfdecc89c..795bf3383 100644 --- a/temporalio/nexus/_decorators.py +++ b/temporalio/nexus/_decorators.py @@ -2,9 +2,7 @@ from collections.abc import Awaitable, Callable from typing import ( - Optional, TypeVar, - Union, overload, ) diff --git a/temporalio/nexus/_link_conversion.py b/temporalio/nexus/_link_conversion.py index b2a219f96..a47c002a9 100644 --- a/temporalio/nexus/_link_conversion.py +++ b/temporalio/nexus/_link_conversion.py @@ -6,7 +6,6 @@ from typing import ( TYPE_CHECKING, Any, - Optional, ) import nexusrpc @@ -74,6 +73,8 @@ def workflow_event_to_nexus_link( query_params = _request_id_reference_to_query_params( workflow_event.request_id_ref ) + case _: + pass # urllib will omit '//' from the url if netloc is empty so we add the scheme manually url = f"{scheme}://{urllib.parse.urlunparse(('', '', path, '', query_params, ''))}" diff --git a/temporalio/nexus/_operation_context.py b/temporalio/nexus/_operation_context.py index 79e35c95c..432edd32b 100644 --- a/temporalio/nexus/_operation_context.py +++ b/temporalio/nexus/_operation_context.py @@ -18,8 +18,6 @@ TYPE_CHECKING, Any, Concatenate, - Optional, - Union, overload, ) @@ -120,7 +118,7 @@ def _nexus_backing_workflow_start_context() -> Generator[None]: _temporal_nexus_backing_workflow_start_context.reset(token) -def _in_nexus_backing_workflow_start_context() -> bool: +def _in_nexus_backing_workflow_start_context() -> bool: # type:ignore[reportUnusedClass] return _temporal_nexus_backing_workflow_start_context.get(False) diff --git a/temporalio/nexus/_token.py b/temporalio/nexus/_token.py index a19d26d05..51e668baa 100644 --- a/temporalio/nexus/_token.py +++ b/temporalio/nexus/_token.py @@ -3,7 +3,7 @@ import base64 import json from dataclasses import dataclass -from typing import TYPE_CHECKING, Any, Generic, Literal, Optional +from typing import TYPE_CHECKING, Any, Generic, Literal from nexusrpc import OutputT diff --git a/temporalio/nexus/_util.py b/temporalio/nexus/_util.py index 843aa50d3..c241677eb 100644 --- a/temporalio/nexus/_util.py +++ b/temporalio/nexus/_util.py @@ -7,8 +7,6 @@ from collections.abc import Awaitable, Callable from typing import ( Any, - Optional, - Type, TypeVar, ) diff --git a/temporalio/plugin.py b/temporalio/plugin.py index 9202bc1f3..db917e337 100644 --- a/temporalio/plugin.py +++ b/temporalio/plugin.py @@ -8,10 +8,8 @@ from contextlib import AbstractAsyncContextManager, asynccontextmanager from typing import ( Any, - Optional, - Type, + TypeAlias, TypeVar, - Union, cast, ) @@ -31,7 +29,7 @@ T = TypeVar("T") -PluginParameter = Union[None, T, Callable[[Optional[T]], T]] +PluginParameter: TypeAlias = None | T | Callable[[T | None], T] class SimplePlugin(temporalio.client.Plugin, temporalio.worker.Plugin): @@ -234,7 +232,7 @@ def _resolve_parameter(existing: T | None, parameter: PluginParameter[T]) -> T | if parameter is None: return existing elif callable(parameter): - return cast(Callable[[Optional[T]], Optional[T]], parameter)(existing) + return cast(Callable[[T | None], T | None], parameter)(existing) else: return parameter @@ -245,8 +243,8 @@ def _resolve_append_parameter( if parameter is None: return existing elif callable(parameter): - return cast( - Callable[[Optional[Sequence[T]]], Optional[Sequence[T]]], parameter - )(existing) + return cast(Callable[[Sequence[T] | None], Sequence[T] | None], parameter)( + existing + ) else: return list(existing or []) + list(parameter) diff --git a/temporalio/runtime.py b/temporalio/runtime.py index ae93e5fda..2cdcf16a6 100644 --- a/temporalio/runtime.py +++ b/temporalio/runtime.py @@ -12,9 +12,7 @@ ClassVar, Generic, NewType, - Optional, TypeVar, - Union, ) from typing_extensions import Protocol, Self diff --git a/temporalio/service.py b/temporalio/service.py index bde62e429..71c309ea7 100644 --- a/temporalio/service.py +++ b/temporalio/service.py @@ -12,7 +12,7 @@ from dataclasses import dataclass, field from datetime import timedelta from enum import IntEnum -from typing import ClassVar, Optional, Tuple, Type, TypeVar, Union +from typing import ClassVar, TypeVar import google.protobuf.message @@ -22,6 +22,7 @@ import temporalio.bridge.services_generated import temporalio.exceptions import temporalio.runtime +from temporalio.bridge.client import RPCError as BridgeRPCError __version__ = "1.20.0" @@ -379,7 +380,7 @@ async def _rpc_call( if LOG_PROTOS: logger.debug("Service %s response from %s: %s", service, rpc, resp) return resp - except temporalio.bridge.client.RPCError as err: + except BridgeRPCError as err: # Intentionally swallowing the cause instead of using "from" status, message, details = err.args raise RPCError(message, RPCStatusCode(status), details) diff --git a/temporalio/testing/_activity.py b/temporalio/testing/_activity.py index 99150381c..0098a91e1 100644 --- a/temporalio/testing/_activity.py +++ b/temporalio/testing/_activity.py @@ -8,7 +8,7 @@ from collections.abc import Callable from contextlib import contextmanager from datetime import datetime, timedelta, timezone -from typing import Any, Optional, Set, TypeVar +from typing import Any, TypeVar from typing_extensions import ParamSpec @@ -182,7 +182,7 @@ def __init__( ) self.task: asyncio.Task | None = None - def run(self, *args, **kwargs) -> Any: + def run(self, *args: Any, **kwargs: Any) -> Any: if self.cancel_thread_raiser: thread_id = threading.current_thread().ident if thread_id is not None: diff --git a/temporalio/testing/_workflow.py b/temporalio/testing/_workflow.py index e651876e9..62da91b6e 100644 --- a/temporalio/testing/_workflow.py +++ b/temporalio/testing/_workflow.py @@ -9,10 +9,6 @@ from datetime import datetime, timedelta, timezone from typing import ( Any, - List, - Optional, - Type, - Union, cast, ) @@ -27,7 +23,6 @@ import temporalio.exceptions import temporalio.runtime import temporalio.service -import temporalio.types import temporalio.worker logger = logging.getLogger(__name__) @@ -79,10 +74,10 @@ async def start_local( plugins: Sequence[temporalio.client.Plugin] = [], default_workflow_query_reject_condition: None | (temporalio.common.QueryRejectCondition) = None, - retry_config: temporalio.client.RetryConfig | None = None, + retry_config: temporalio.service.RetryConfig | None = None, rpc_metadata: Mapping[str, str | bytes] = {}, identity: str | None = None, - tls: bool | temporalio.client.TLSConfig = False, + tls: bool | temporalio.service.TLSConfig = False, ip: str = "127.0.0.1", port: int | None = None, download_dest_dir: str | None = None, @@ -224,7 +219,7 @@ async def start_local( try: await server.shutdown() except: - logger.warn( + logger.warning( "Failed stopping local server on client connection failure", exc_info=True, ) @@ -239,7 +234,7 @@ async def start_time_skipping( plugins: Sequence[temporalio.client.Plugin] = [], default_workflow_query_reject_condition: None | (temporalio.common.QueryRejectCondition) = None, - retry_config: temporalio.client.RetryConfig | None = None, + retry_config: temporalio.service.RetryConfig | None = None, rpc_metadata: Mapping[str, str | bytes] = {}, identity: str | None = None, port: int | None = None, @@ -344,7 +339,7 @@ async def start_time_skipping( try: await server.shutdown() except: - logger.warn( + logger.warning( "Failed stopping test server on client connection failure", exc_info=True, ) @@ -362,7 +357,7 @@ async def __aenter__(self) -> WorkflowEnvironment: """Noop for ``async with`` support.""" return self - async def __aexit__(self, *args) -> None: + async def __aexit__(self, *args: Any) -> None: """For ``async with`` support to just call :py:meth:`shutdown`.""" await self.shutdown() diff --git a/temporalio/types.py b/temporalio/types.py index c8d7824e3..4b217ea23 100644 --- a/temporalio/types.py +++ b/temporalio/types.py @@ -1,7 +1,7 @@ """Advanced types.""" from collections.abc import Awaitable, Callable -from typing import Any, Type, TypeVar, Union +from typing import Any, TypeVar from typing_extensions import ParamSpec, Protocol @@ -15,11 +15,11 @@ CallableAsyncType = TypeVar("CallableAsyncType", bound=Callable[..., Awaitable[Any]]) CallableSyncOrAsyncType = TypeVar( "CallableSyncOrAsyncType", - bound=Callable[..., Union[Any, Awaitable[Any]]], + bound=Callable[..., Any | Awaitable[Any]], ) CallableSyncOrAsyncReturnNoneType = TypeVar( "CallableSyncOrAsyncReturnNoneType", - bound=Callable[..., Union[None, Awaitable[None]]], + bound=Callable[..., None | Awaitable[None]], ) MultiParamSpec = ParamSpec("MultiParamSpec") diff --git a/temporalio/worker/__init__.py b/temporalio/worker/__init__.py index 1d7b2558e..e8e600dc3 100644 --- a/temporalio/worker/__init__.py +++ b/temporalio/worker/__init__.py @@ -1,5 +1,6 @@ """Worker for processing Temporal workflows and/or activities.""" +from ..common import WorkerDeploymentVersion from ._activity import SharedHeartbeatSender, SharedStateManager from ._interceptor import ( ActivityInboundInterceptor, @@ -52,7 +53,6 @@ Worker, WorkerConfig, WorkerDeploymentConfig, - WorkerDeploymentVersion, ) from ._workflow_instance import ( UnsandboxedWorkflowRunner, diff --git a/temporalio/worker/_activity.py b/temporalio/worker/_activity.py index f74ee7872..93249fad5 100644 --- a/temporalio/worker/_activity.py +++ b/temporalio/worker/_activity.py @@ -21,8 +21,6 @@ from typing import ( Any, NoReturn, - Optional, - Union, ) import google.protobuf.duration_pb2 @@ -627,7 +625,7 @@ async def _execute_activity( impl.init(_ActivityOutboundImpl(self, running_activity.info)) return await impl.execute_activity(input) - def assert_activity_valid(self, activity) -> None: + def assert_activity_valid(self, activity: str) -> None: if self._dynamic_activity: return activity_def = self._activities.get(activity) diff --git a/temporalio/worker/_command_aware_visitor.py b/temporalio/worker/_command_aware_visitor.py index 2301f6ed6..2d7f3990b 100644 --- a/temporalio/worker/_command_aware_visitor.py +++ b/temporalio/worker/_command_aware_visitor.py @@ -4,7 +4,6 @@ from collections.abc import Iterator from contextlib import contextmanager from dataclasses import dataclass -from typing import Optional from temporalio.api.enums.v1.command_type_pb2 import CommandType from temporalio.bridge._visitor import PayloadVisitor, VisitorFunctions diff --git a/temporalio/worker/_interceptor.py b/temporalio/worker/_interceptor.py index c8d84e861..d6afdc759 100644 --- a/temporalio/worker/_interceptor.py +++ b/temporalio/worker/_interceptor.py @@ -9,14 +9,10 @@ from typing import ( Any, Generic, - List, NoReturn, - Optional, - Type, - Union, ) -import nexusrpc.handler +import nexusrpc from nexusrpc import InputT, OutputT import temporalio.activity @@ -49,7 +45,8 @@ def intercept_activity( return next def workflow_interceptor_class( - self, input: WorkflowInterceptorClassInput + self, + input: WorkflowInterceptorClassInput, # type:ignore[reportUnusedParameter] ) -> type[WorkflowInboundInterceptor] | None: """Class that will be instantiated and used to intercept workflows. diff --git a/temporalio/worker/_nexus.py b/temporalio/worker/_nexus.py index 75afa090e..b5764531e 100644 --- a/temporalio/worker/_nexus.py +++ b/temporalio/worker/_nexus.py @@ -11,9 +11,6 @@ from typing import ( Any, NoReturn, - Optional, - Type, - Union, ) import google.protobuf.json_format @@ -31,6 +28,7 @@ import temporalio.common import temporalio.converter import temporalio.nexus +from temporalio.bridge.worker import PollShutdownError from temporalio.exceptions import ( ApplicationError, WorkflowAlreadyStartedError, @@ -53,7 +51,7 @@ def cancel(self, reason: str): self.task.cancel() -class _NexusWorker: +class _NexusWorker: # type:ignore[reportUnusedClass] def __init__( self, *, @@ -149,7 +147,7 @@ async def raise_from_exception_queue() -> NoReturn: else: raise NotImplementedError(f"Invalid Nexus task: {nexus_task}") - except temporalio.bridge.worker.PollShutdownError: + except PollShutdownError: exception_task.cancel() return @@ -167,7 +165,7 @@ async def drain_poll_queue(self) -> None: ) completion.error.failure.message = "Worker shutting down" await self._bridge_worker().complete_nexus_task(completion) - except temporalio.bridge.worker.PollShutdownError: + except PollShutdownError: return # Only call this after run()/drain_poll_queue() have returned. This will not @@ -442,14 +440,14 @@ class _DummyPayloadSerializer: data_converter: temporalio.converter.DataConverter payload: temporalio.api.common.v1.Payload - async def serialize(self, value: Any) -> nexusrpc.Content: + async def serialize(self, value: Any) -> nexusrpc.Content: # type:ignore[reportUnusedParameter] raise NotImplementedError( "The serialize method of the Serializer is not used by handlers" ) async def deserialize( self, - content: nexusrpc.Content, + content: nexusrpc.Content, # type:ignore[reportUnusedParameter] as_type: type[Any] | None = None, ) -> Any: try: diff --git a/temporalio/worker/_tuning.py b/temporalio/worker/_tuning.py index 4843fee98..644f07aab 100644 --- a/temporalio/worker/_tuning.py +++ b/temporalio/worker/_tuning.py @@ -6,11 +6,10 @@ from collections.abc import Callable from dataclasses import dataclass from datetime import timedelta -from typing import Any, Literal, Optional, Protocol, TypeAlias, Union, runtime_checkable - -from typing_extensions import Self +from typing import Any, Literal, Protocol, TypeAlias, runtime_checkable import temporalio.bridge.worker +from temporalio.bridge.worker import BridgeCustomSlotSupplier from temporalio.common import WorkerDeploymentVersion _DEFAULT_RESOURCE_SLOTS_MAX = 500 @@ -131,9 +130,9 @@ class NexusSlotInfo(Protocol): operation: str -SlotInfo: TypeAlias = Union[ - WorkflowSlotInfo, ActivitySlotInfo, LocalActivitySlotInfo, NexusSlotInfo -] +SlotInfo: TypeAlias = ( + WorkflowSlotInfo | ActivitySlotInfo | LocalActivitySlotInfo | NexusSlotInfo +) # WARNING: This must match Rust worker::SlotMarkUsedCtx @@ -222,9 +221,9 @@ def release_slot(self, ctx: SlotReleaseContext) -> None: ... -SlotSupplier: TypeAlias = Union[ - FixedSizeSlotSupplier, ResourceBasedSlotSupplier, CustomSlotSupplier -] +SlotSupplier: TypeAlias = ( + FixedSizeSlotSupplier | ResourceBasedSlotSupplier | CustomSlotSupplier +) class _BridgeSlotSupplierWrapper: @@ -301,11 +300,9 @@ def _to_bridge_slot_supplier( ), ) elif isinstance(slot_supplier, CustomSlotSupplier): - return temporalio.bridge.worker.BridgeCustomSlotSupplier( - _BridgeSlotSupplierWrapper(slot_supplier) - ) + return BridgeCustomSlotSupplier(_BridgeSlotSupplierWrapper(slot_supplier)) else: - raise TypeError(f"Unknown slot supplier type: {slot_supplier}") + raise TypeError(f"Unknown slot supplier type: {slot_supplier}") # type:ignore[reportUnreachable] class WorkerTuner(ABC): diff --git a/temporalio/worker/_workflow.py b/temporalio/worker/_workflow.py index b5aa57fc2..468605ed1 100644 --- a/temporalio/worker/_workflow.py +++ b/temporalio/worker/_workflow.py @@ -12,27 +12,17 @@ from dataclasses import dataclass from datetime import timezone from types import TracebackType -from typing import ( - Dict, - List, - Optional, - Set, - Type, -) -import temporalio.activity import temporalio.api.common.v1 -import temporalio.bridge._visitor -import temporalio.bridge.client import temporalio.bridge.proto.workflow_activation import temporalio.bridge.proto.workflow_completion import temporalio.bridge.runtime import temporalio.bridge.worker -import temporalio.client import temporalio.common import temporalio.converter import temporalio.exceptions import temporalio.workflow +from temporalio.bridge.worker import PollShutdownError from . import _command_aware_visitor from ._interceptor import ( @@ -53,7 +43,7 @@ LOG_PROTOS = False -class _WorkflowWorker: +class _WorkflowWorker: # type:ignore[reportUnusedClass] def __init__( self, *, @@ -186,7 +176,7 @@ async def run(self) -> None: # when done. task = asyncio.create_task(self._handle_activation(act)) setattr(task, "__temporal_task_tag", task_tag) - except temporalio.bridge.worker.PollShutdownError: + except PollShutdownError: pass except Exception as err: raise RuntimeError("Workflow worker failed") from err @@ -224,7 +214,7 @@ async def drain_poll_queue(self) -> None: ) completion.failed.failure.message = "Worker shutting down" await self._bridge_worker().complete_workflow_activation(completion) - except temporalio.bridge.worker.PollShutdownError: + except PollShutdownError: return async def _handle_activation( diff --git a/temporalio/worker/_workflow_instance.py b/temporalio/worker/_workflow_instance.py index 1139be042..10fd594fd 100644 --- a/temporalio/worker/_workflow_instance.py +++ b/temporalio/worker/_workflow_instance.py @@ -14,6 +14,7 @@ import traceback import warnings from abc import ABC, abstractmethod +from collections import deque from collections.abc import ( Awaitable, Callable, @@ -31,22 +32,14 @@ from enum import IntEnum from typing import ( Any, - Deque, - Dict, Generic, - List, NoReturn, - Optional, - Set, - Tuple, - Type, TypeAlias, TypeVar, - Union, cast, ) -import nexusrpc.handler +import nexusrpc from nexusrpc import InputT, OutputT from typing_extensions import Self, TypedDict, TypeVarTuple, Unpack @@ -124,7 +117,8 @@ def create_instance(self, det: WorkflowInstanceDetails) -> WorkflowInstance: raise NotImplementedError def set_worker_level_failure_exception_types( - self, types: Sequence[type[BaseException]] + self, + types: Sequence[type[BaseException]], # type:ignore[reportUnusedParameter] ) -> None: """Set worker-level failure exception types that will be used to validate in the sandbox when calling ``prepare_workflow``. @@ -260,7 +254,7 @@ def __init__(self, det: WorkflowInstanceDetails) -> None: # Lazily loaded self._untyped_converted_memo: MutableMapping[str, Any] | None = None # Handles which are ready to run on the next event loop iteration - self._ready: Deque[asyncio.Handle] = collections.deque() + self._ready: deque[asyncio.Handle] = collections.deque() self._conditions: list[tuple[Callable[[], bool], asyncio.Future]] = [] # Keyed by seq self._pending_timers: dict[int, _TimerHandle] = {} @@ -511,7 +505,9 @@ def activate( ) self._current_completion.failed.failure.application_failure_info.SetInParent() - def is_completion(command): + def is_completion( + command: temporalio.bridge.proto.workflow_commands.workflow_commands_pb2.WorkflowCommand, + ): return ( command.HasField("complete_workflow_execution") or command.HasField("continue_as_new_workflow_execution") @@ -571,7 +567,7 @@ def _apply( raise RuntimeError(f"Unrecognized job: {job.WhichOneof('variant')}") def _apply_cancel_workflow( - self, job: temporalio.bridge.proto.workflow_activation.CancelWorkflow + self, _job: temporalio.bridge.proto.workflow_activation.CancelWorkflow ) -> None: self._cancel_requested = True # TODO(cretz): Details or cancel message or whatever? @@ -772,7 +768,7 @@ def _apply_notify_has_patch( self._patches_notified.add(job.patch_id) def _apply_remove_from_cache( - self, job: temporalio.bridge.proto.workflow_activation.RemoveFromCache + self, _job: temporalio.bridge.proto.workflow_activation.RemoveFromCache ) -> None: self._deleting = True self._cancel_requested = True @@ -1040,7 +1036,7 @@ def _apply_signal_workflow( self._process_signal_job(signal_defn, job) def _apply_initialize_workflow( - self, job: temporalio.bridge.proto.workflow_activation.InitializeWorkflow + self, _job: temporalio.bridge.proto.workflow_activation.InitializeWorkflow ) -> None: # Async call to run on the scheduler thread. This will be wrapped in # another function which applies exception handling. @@ -1135,7 +1131,7 @@ def workflow_continue_as_new( name = defn.name arg_types = defn.arg_types elif workflow is not None: - raise TypeError("Workflow must be None, a string, or callable") + raise TypeError("Workflow must be None, a string, or callable") # type:ignore[reportUnreachable] self._outbound.continue_as_new( ContinueAsNewInput( @@ -1152,8 +1148,6 @@ def workflow_continue_as_new( versioning_intent=versioning_intent, ) ) - # TODO(cretz): Why can't MyPy infer the above never returns? - raise RuntimeError("Unreachable") def workflow_extern_functions(self) -> Mapping[str, Callable]: return self._extern_functions @@ -2308,7 +2302,7 @@ def _process_signal_job( job.signal_name, defn.unfinished_policy ) - def done_callback(f): + def done_callback(_f: Any): self._in_progress_signals.pop(id, None) task = self.create_task( @@ -2943,9 +2937,6 @@ def cancel(self, msg: Any | None = None) -> bool: # the cancel (i.e. cancelled before started) if not self._started and not self.done(): self._apply_cancel_command(self._instance._add_command()) - # Message not supported in older versions - if sys.version_info < (3, 9): - return super().cancel() return super().cancel(msg) def _resolve_success(self, result: Any) -> None: diff --git a/temporalio/worker/workflow_sandbox/_in_sandbox.py b/temporalio/worker/workflow_sandbox/_in_sandbox.py index 3756749ca..eea8f6940 100644 --- a/temporalio/worker/workflow_sandbox/_in_sandbox.py +++ b/temporalio/worker/workflow_sandbox/_in_sandbox.py @@ -6,7 +6,7 @@ import dataclasses import logging -from typing import Any, Optional, Type +from typing import Any import temporalio.bridge.proto.workflow_activation import temporalio.bridge.proto.workflow_completion diff --git a/temporalio/worker/workflow_sandbox/_runner.py b/temporalio/worker/workflow_sandbox/_runner.py index 35023f141..31514e33b 100644 --- a/temporalio/worker/workflow_sandbox/_runner.py +++ b/temporalio/worker/workflow_sandbox/_runner.py @@ -10,7 +10,7 @@ from collections.abc import Sequence from dataclasses import dataclass, field from datetime import datetime, timedelta, timezone -from typing import Any, Optional, Type +from typing import Any import temporalio.bridge.proto.workflow_activation import temporalio.bridge.proto.workflow_completion diff --git a/tests/bridge/test_runtime.py b/tests/bridge/test_runtime.py index de6622f04..2a1c48834 100644 --- a/tests/bridge/test_runtime.py +++ b/tests/bridge/test_runtime.py @@ -1,6 +1,5 @@ from threading import Event, Thread from time import sleep -from typing import Optional from temporalio.bridge.runtime import Runtime diff --git a/tests/contrib/openai_agents/test_openai.py b/tests/contrib/openai_agents/test_openai.py index 381a213cd..327d71120 100644 --- a/tests/contrib/openai_agents/test_openai.py +++ b/tests/contrib/openai_agents/test_openai.py @@ -8,8 +8,6 @@ from datetime import timedelta from typing import ( Any, - Optional, - Union, cast, ) @@ -57,25 +55,17 @@ HandoffOutputItem, ToolCallItem, ToolCallOutputItem, - TResponseOutputItem, TResponseStreamEvent, ) from agents.mcp import MCPServer, MCPServerStdio from openai import APIStatusError, AsyncOpenAI, BaseModel from openai.types.responses import ( - EasyInputMessageParam, ResponseCodeInterpreterToolCall, ResponseFileSearchToolCall, - ResponseFunctionToolCall, - ResponseFunctionToolCallParam, ResponseFunctionWebSearch, - ResponseInputTextParam, - ResponseOutputMessage, - ResponseOutputText, ) from openai.types.responses.response_file_search_tool_call import Result from openai.types.responses.response_function_web_search import ActionSearch -from openai.types.responses.response_input_item_param import Message from openai.types.responses.response_output_item import ( ImageGenerationCall, McpApprovalRequest, @@ -96,7 +86,6 @@ from temporalio.contrib.openai_agents._model_parameters import ModelSummaryProvider from temporalio.contrib.openai_agents._openai_runner import _convert_agent from temporalio.contrib.openai_agents._temporal_model_stub import ( - _extract_summary, _TemporalModelStub, ) from temporalio.contrib.openai_agents.testing import ( @@ -174,7 +163,7 @@ async def get_weather(city: str) -> Weather: @activity.defn -async def get_weather_country(city: str, country: str) -> Weather: +async def get_weather_country(city: str, _country: str) -> Weather: """ Get the weather for a given city in a country. """ @@ -224,7 +213,7 @@ class WeatherService: class WeatherServiceHandler: @nexusrpc.handler.sync_operation async def get_weather_nexus_operation( - self, ctx: nexusrpc.handler.StartOperationContext, input: WeatherInput + self, _ctx: nexusrpc.handler.StartOperationContext, input: WeatherInput ) -> Weather: return Weather( city=input.city, temperature_range="14-20C", conditions="Sunny with wind." @@ -429,7 +418,7 @@ async def test_tool_workflow(client: Client, use_local_model: bool): @activity.defn -async def get_weather_failure(city: str) -> Weather: +async def get_weather_failure(_city: str) -> Weather: """ Get the weather for a given city. """ @@ -468,7 +457,7 @@ async def test_tool_failure_workflow(client: Client): execution_timeout=timedelta(seconds=2), ) with pytest.raises(WorkflowFailureError) as e: - result = await workflow_handle.result() + await workflow_handle.result() cause = e.value.cause assert isinstance(cause, ApplicationError) assert "Workflow failure exception in Agents Framework" in cause.message @@ -938,7 +927,7 @@ def __init__(self, input_items: list[TResponseInputItem] = []): self.input_items = input_items @workflow.run - async def run(self, input_items: list[TResponseInputItem] = []): + async def run(self, _input_items: list[TResponseInputItem] = []): await workflow.wait_condition(lambda: False) workflow.continue_as_new(self.input_items) @@ -1166,7 +1155,7 @@ class MathHomeworkOutput(BaseModel): @input_guardrail async def math_guardrail( context: RunContextWrapper[None], - agent: Agent, + _agent: Agent, input: str | list[TResponseInputItem], ) -> GuardrailFunctionOutput: """This is an input guardrail function, which happens to call an agent to check if the input @@ -1284,7 +1273,7 @@ class MessageOutput(BaseModel): @output_guardrail async def sensitive_data_check( - context: RunContextWrapper, agent: Agent, output: MessageOutput + _context: RunContextWrapper, _agent: Agent, output: MessageOutput ) -> GuardrailFunctionOutput: phone_number_in_response = "650" in output.response phone_number_in_reasoning = "650" in output.reasoning @@ -1416,7 +1405,7 @@ async def test_response_serialization(): usage=Usage(), response_id="", ) - encoded = await pydantic_data_converter.encode([model_response]) + await pydantic_data_converter.encode([model_response]) async def assert_status_retry_behavior(status: int, client: Client, should_retry: bool): @@ -1451,7 +1440,7 @@ def status_error(status: int): task_queue=worker.task_queue, execution_timeout=timedelta(seconds=10), ) - with pytest.raises(WorkflowFailureError) as e: + with pytest.raises(WorkflowFailureError): await workflow_handle.result() found = False @@ -1517,7 +1506,7 @@ async def get_response( output_schema: AgentOutputSchemaBase | None, handoffs: list[Handoff], tracing: ModelTracing, - **kwargs, + **kwargs, # type:ignore[reportMissingParameterType] ) -> ModelResponse: activity.logger.info("Waiting") await asyncio.sleep(1.0) @@ -1533,7 +1522,7 @@ def stream_response( output_schema: AgentOutputSchemaBase | None, handoffs: list[Handoff], tracing: ModelTracing, - **kwargs, + **kwargs, # type:ignore[reportMissingParameterType] ) -> AsyncIterator[TResponseStreamEvent]: raise NotImplementedError() @@ -1606,40 +1595,6 @@ async def test_heartbeat(client: Client, env: WorkflowEnvironment): await workflow_handle.result() -def test_summary_extraction(): - input: list[TResponseInputItem] = [ - EasyInputMessageParam( - content="First message", - role="user", - ) - ] - - assert _extract_summary(input) == "First message" - - input.append( - Message( - content=[ - ResponseInputTextParam( - text="Second message", - type="input_text", - ) - ], - role="user", - ) - ) - assert _extract_summary(input) == "Second message" - - input.append( - ResponseFunctionToolCallParam( - arguments="", - call_id="", - name="", - type="function_call", - ) - ) - assert _extract_summary(input) == "Second message" - - @workflow.defn class SessionWorkflow: @workflow.run @@ -1685,11 +1640,11 @@ async def check(): await assert_eventually(check) -async def test_lite_llm(client: Client, env: WorkflowEnvironment): +async def test_lite_llm(client: Client): if not os.environ.get("OPENAI_API_KEY"): pytest.skip("No openai API key") if sys.version_info >= (3, 14): - pytest.skip("Lite LLM does not yet support Python 3.14") + pytest.skip("Lite LLM does not yet support Python 3.14") # type:ignore[reportUnreachable] from agents.extensions.models.litellm_provider import LitellmProvider @@ -1766,7 +1721,7 @@ async def run(self, question: str) -> str: @pytest.mark.parametrize("use_local_model", [True, False]) -async def test_file_search_tool(client: Client, use_local_model): +async def test_file_search_tool(client: Client, use_local_model: bool): if not use_local_model and not os.environ.get("OPENAI_API_KEY"): pytest.skip("No openai API key") @@ -1840,7 +1795,7 @@ async def run(self, question: str) -> str: # Can't currently validate against real server, we aren't verified for image generation @pytest.mark.parametrize("use_local_model", [True]) -async def test_image_generation_tool(client: Client, use_local_model): +async def test_image_generation_tool(client: Client, use_local_model: bool): if not use_local_model and not os.environ.get("OPENAI_API_KEY"): pytest.skip("No openai API key") @@ -1864,7 +1819,7 @@ async def test_image_generation_tool(client: Client, use_local_model): task_queue=worker.task_queue, execution_timeout=timedelta(seconds=30), ) - result = await workflow_handle.result() + await workflow_handle.result() def code_interpreter_mock_model(): @@ -2099,7 +2054,7 @@ async def test_multiple_models(client: Client): task_queue=worker.task_queue, execution_timeout=timedelta(seconds=10), ) - result = await workflow_handle.result() + await workflow_handle.result() assert provider.model_names == {None, "gpt-4o-mini"} @@ -2124,7 +2079,7 @@ async def test_run_config_models(client: Client): task_queue=worker.task_queue, execution_timeout=timedelta(seconds=10), ) - result = await workflow_handle.result() + await workflow_handle.result() # Only the model from the runconfig override is used assert provider.model_names == {"gpt-4o"} @@ -2160,7 +2115,7 @@ def provide( task_queue=worker.task_queue, execution_timeout=timedelta(seconds=10), ) - result = await workflow_handle.result() + await workflow_handle.result() async for e in workflow_handle.fetch_history_events(): if e.HasField("activity_task_scheduled_event_attributes"): assert e.user_metadata.summary.data == b'"My summary"' @@ -2477,7 +2432,7 @@ def factory(args: Any | None) -> MCPServer: client, McpServerStatefulWorkflow, McpServerWorkflow ) as worker: if stateful: - result = await client.execute_workflow( + await client.execute_workflow( McpServerStatefulWorkflow.run, args=[timedelta(seconds=30), headers], id=f"mcp-server-{uuid.uuid4()}", @@ -2485,7 +2440,7 @@ def factory(args: Any | None) -> MCPServer: execution_timeout=timedelta(seconds=30), ) else: - result = await client.execute_workflow( + await client.execute_workflow( McpServerWorkflow.run, args=[False, headers], id=f"mcp-server-{uuid.uuid4()}", @@ -2624,9 +2579,7 @@ async def test_split_workers(client: Client): new_config["plugins"] = [activity_plugin] activity_client = Client(**new_config) # Activity Worker - async with new_worker( - activity_client, task_queue=worker.task_queue - ) as activity_worker: + async with new_worker(activity_client, task_queue=worker.task_queue): result = await activity_client.execute_workflow( HelloWorldAgent.run, "Tell me about recursion in programming.", diff --git a/tests/contrib/openai_agents/test_openai_tracing.py b/tests/contrib/openai_agents/test_openai_tracing.py index f0a98c2b6..39d1cc6f0 100644 --- a/tests/contrib/openai_agents/test_openai_tracing.py +++ b/tests/contrib/openai_agents/test_openai_tracing.py @@ -60,7 +60,7 @@ async def test_tracing(client: Client): task_queue=worker.task_queue, execution_timeout=timedelta(seconds=120), ) - result = await workflow_handle.result() + await workflow_handle.result() # There is one closed root trace assert len(processor.trace_events) == 2 diff --git a/tests/contrib/pydantic/activities.py b/tests/contrib/pydantic/activities.py index 4b5a83d5b..7cd4abd30 100644 --- a/tests/contrib/pydantic/activities.py +++ b/tests/contrib/pydantic/activities.py @@ -1,5 +1,4 @@ from datetime import datetime -from typing import List from uuid import UUID from temporalio import activity diff --git a/tests/helpers/__init__.py b/tests/helpers/__init__.py index 09bc61b45..e407b7d1d 100644 --- a/tests/helpers/__init__.py +++ b/tests/helpers/__init__.py @@ -11,11 +11,7 @@ from datetime import datetime, timedelta, timezone from typing import ( Any, - List, - Optional, - Type, TypeVar, - Union, cast, ) @@ -53,7 +49,7 @@ def new_worker( workflow_runner: WorkflowRunner = SandboxedWorkflowRunner(), max_cached_workflows: int = 1000, workflow_failure_exception_types: Sequence[type[BaseException]] = [], - **kwargs, + **kwargs, # type:ignore[reportMissingParameterType] ) -> Worker: return Worker( client, @@ -187,7 +183,7 @@ async def admitted_update_task( handle: WorkflowHandle, update_method: UpdateMethodMultiParam, id: str, - **kwargs, + **kwargs, # type:ignore[reportMissingParameterType] ) -> asyncio.Task: """ Return an asyncio.Task for an update after waiting for it to be admitted. diff --git a/tests/helpers/external_coroutine.py b/tests/helpers/external_coroutine.py index 72fa8f25a..9af6e85ec 100644 --- a/tests/helpers/external_coroutine.py +++ b/tests/helpers/external_coroutine.py @@ -2,8 +2,6 @@ File used in conjunction with external_stack_trace.py to test filenames in multi-file workflows. """ -from typing import List - from temporalio import workflow diff --git a/tests/helpers/fork.py b/tests/helpers/fork.py index f6b6178ac..d465a4808 100644 --- a/tests/helpers/fork.py +++ b/tests/helpers/fork.py @@ -3,7 +3,6 @@ import asyncio import multiprocessing import multiprocessing.context -import sys from dataclasses import dataclass from typing import Any @@ -40,7 +39,7 @@ def assertion_error(message: str) -> _ForkTestResult: ) -class _TestFork: +class _TestFork: # type:ignore[reportUnusedClass] _expected: _ForkTestResult # type:ignore[reportUninitializedInstanceVariable] async def coro(self) -> Any: diff --git a/tests/helpers/nexus.py b/tests/helpers/nexus.py index 63dde9621..904b4422a 100644 --- a/tests/helpers/nexus.py +++ b/tests/helpers/nexus.py @@ -1,7 +1,7 @@ import dataclasses from collections.abc import Mapping from dataclasses import dataclass -from typing import Any, Optional +from typing import Any from urllib.parse import urlparse import temporalio.api.failure.v1 @@ -122,7 +122,7 @@ def __post_init__(self) -> None: ) def _instantiate_exception( - self, error_type: str, details: dict[str, Any] | None + self, error_type: str, _details: dict[str, Any] | None ) -> BaseException: proto = { "temporal.api.failure.v1.Failure": temporalio.api.failure.v1.Failure, diff --git a/tests/helpers/worker.py b/tests/helpers/worker.py index 5c6e6898c..b21be3b36 100644 --- a/tests/helpers/worker.py +++ b/tests/helpers/worker.py @@ -12,7 +12,7 @@ from collections.abc import Sequence from dataclasses import dataclass from datetime import timedelta -from typing import Any, Optional, Tuple +from typing import Any import temporalio.converter from temporalio import workflow @@ -132,7 +132,7 @@ async def handle_action( elif action.signal: signal_event = asyncio.Event() - def signal_handler(arg: Any | None = None) -> None: + def signal_handler(_arg: Any | None = None) -> None: signal_event.set() workflow.set_signal_handler(action.signal.name, signal_handler) diff --git a/tests/nexus/test_dynamic_creation_of_user_handler_classes.py b/tests/nexus/test_dynamic_creation_of_user_handler_classes.py index bc4eacd27..95ff1c986 100644 --- a/tests/nexus/test_dynamic_creation_of_user_handler_classes.py +++ b/tests/nexus/test_dynamic_creation_of_user_handler_classes.py @@ -110,8 +110,8 @@ def make_incrementer_user_service_definition_and_service_handler_classes( # @sync_operation async def _increment_op( - self, - ctx: nexusrpc.handler.StartOperationContext, + _self, # type:ignore[reportMissingParameterType] + _ctx: nexusrpc.handler.StartOperationContext, input: int, ) -> int: return input + 1 diff --git a/tests/nexus/test_handler.py b/tests/nexus/test_handler.py index e3ba639a7..407e61caf 100644 --- a/tests/nexus/test_handler.py +++ b/tests/nexus/test_handler.py @@ -22,7 +22,7 @@ from concurrent.futures.thread import ThreadPoolExecutor from dataclasses import dataclass, field from types import MappingProxyType -from typing import Any, Optional, Union +from typing import Any import httpx import nexusrpc @@ -146,13 +146,13 @@ async def echo_renamed(self, ctx: StartOperationContext, input: Input) -> Output return await self.echo(ctx, input) @sync_operation - async def hang(self, ctx: StartOperationContext, input: Input) -> Output: + async def hang(self, _ctx: StartOperationContext, _input: Input) -> Output: await asyncio.Future() return Output(value="won't reach here") @sync_operation async def non_retryable_application_error( - self, ctx: StartOperationContext, input: Input + self, _ctx: StartOperationContext, _input: Input ) -> Output: raise ApplicationError( "non-retryable application error", @@ -164,7 +164,7 @@ async def non_retryable_application_error( @sync_operation async def retryable_application_error( - self, ctx: StartOperationContext, input: Input + self, _ctx: StartOperationContext, _input: Input ) -> Output: raise ApplicationError( "retryable application error", @@ -175,7 +175,7 @@ async def retryable_application_error( @sync_operation async def handler_error_internal( - self, ctx: StartOperationContext, input: Input + self, _ctx: StartOperationContext, _input: Input ) -> Output: raise HandlerError( message="deliberate internal handler error", @@ -185,7 +185,7 @@ async def handler_error_internal( @sync_operation async def operation_error_failed( - self, ctx: StartOperationContext, input: Input + self, _ctx: StartOperationContext, _input: Input ) -> Output: raise OperationError( message="deliberate operation error", @@ -202,7 +202,7 @@ async def check_operation_timeout_header( ) @sync_operation - async def log(self, ctx: StartOperationContext, input: Input) -> Output: + async def log(self, _ctx: StartOperationContext, input: Input) -> Output: nexus.logger.info( "Logging from start method", extra={"input_value": input.value} ) @@ -222,7 +222,7 @@ async def workflow_run_operation_happy_path( @sync_operation async def sync_operation_with_non_async_def( - self, ctx: StartOperationContext, input: Input + self, _ctx: StartOperationContext, input: Input ) -> Output: return Output( value=f"from start method on {self.__class__.__name__}: {input.value}" @@ -267,13 +267,13 @@ def operation_returning_unwrapped_result_at_runtime_error( @sync_operation async def idempotency_check( - self, ctx: StartOperationContext, input: None + self, ctx: StartOperationContext, _input: None ) -> Output: return Output(value=f"request_id: {ctx.request_id}") @sync_operation async def non_serializable_output( - self, ctx: StartOperationContext, input: Input + self, _ctx: StartOperationContext, _input: Input ) -> NonSerializableOutput: return NonSerializableOutput() @@ -677,7 +677,7 @@ class MyServiceWithOperationsWithoutTypeAnnotations: class MyServiceHandlerWithOperationsWithoutTypeAnnotations: @sync_operation - async def sync_operation_without_type_annotations(self, ctx, input): + async def sync_operation_without_type_annotations(self, ctx, input): # type:ignore[reportMissingParameterType] # Despite the lack of type annotations, the input type from the op definition in # the service definition is used to deserialize the input. return Output( @@ -685,7 +685,7 @@ async def sync_operation_without_type_annotations(self, ctx, input): ) @workflow_run_operation - async def workflow_run_operation_without_type_annotations(self, ctx, input): + async def workflow_run_operation_without_type_annotations(self, ctx, input): # type:ignore[reportMissingParameterType] return await ctx.start_workflow( WorkflowWithoutTypeAnnotations.run, input, @@ -847,7 +847,7 @@ def echo(self, ctx: StartOperationContext, input: Input) -> Output: @service_handler(service=EchoService) class DefaultCancelHandler: @sync_operation - async def echo(self, ctx: StartOperationContext, input: Input) -> Output: + async def echo(self, _ctx: StartOperationContext, input: Input) -> Output: return Output( value=f"from start method on {self.__class__.__name__}: {input.value}" ) diff --git a/tests/nexus/test_handler_async_operation.py b/tests/nexus/test_handler_async_operation.py index 76aef59f6..d25c8a072 100644 --- a/tests/nexus/test_handler_async_operation.py +++ b/tests/nexus/test_handler_async_operation.py @@ -10,7 +10,7 @@ import uuid from collections.abc import Coroutine from dataclasses import dataclass, field -from typing import Any, Type, Union +from typing import Any import pytest from nexusrpc.handler import ( diff --git a/tests/nexus/test_handler_interface_implementation.py b/tests/nexus/test_handler_interface_implementation.py index 58a139ad8..35289e188 100644 --- a/tests/nexus/test_handler_interface_implementation.py +++ b/tests/nexus/test_handler_interface_implementation.py @@ -1,5 +1,5 @@ from dataclasses import dataclass -from typing import Any, Optional +from typing import Any import nexusrpc import nexusrpc.handler diff --git a/tests/nexus/test_handler_operation_definitions.py b/tests/nexus/test_handler_operation_definitions.py index a9e9cb454..e975a8fc8 100644 --- a/tests/nexus/test_handler_operation_definitions.py +++ b/tests/nexus/test_handler_operation_definitions.py @@ -4,7 +4,7 @@ """ from dataclasses import dataclass -from typing import Any, Type +from typing import Any import nexusrpc.handler import pytest @@ -35,7 +35,7 @@ class NotCalled(_TestCase): class Service: @workflow_run_operation async def my_workflow_run_operation_handler( - self, ctx: WorkflowRunOperationContext, input: Input + self, _ctx: WorkflowRunOperationContext, _input: Input ) -> nexus.WorkflowHandle[Output]: raise NotImplementedError @@ -54,7 +54,7 @@ class CalledWithoutArgs(_TestCase): class Service: @workflow_run_operation async def my_workflow_run_operation_handler( - self, ctx: WorkflowRunOperationContext, input: Input + self, _ctx: WorkflowRunOperationContext, _input: Input ) -> nexus.WorkflowHandle[Output]: raise NotImplementedError @@ -66,7 +66,7 @@ class CalledWithNameOverride(_TestCase): class Service: @workflow_run_operation(name="operation-name") async def workflow_run_operation_with_name_override( - self, ctx: WorkflowRunOperationContext, input: Input + self, _ctx: WorkflowRunOperationContext, _input: Input ) -> nexus.WorkflowHandle[Output]: raise NotImplementedError diff --git a/tests/nexus/test_use_existing_conflict_policy.py b/tests/nexus/test_use_existing_conflict_policy.py index 211ed4f5c..ecefa4b05 100644 --- a/tests/nexus/test_use_existing_conflict_policy.py +++ b/tests/nexus/test_use_existing_conflict_policy.py @@ -3,7 +3,6 @@ import asyncio import uuid from dataclasses import dataclass -from typing import Optional import pytest from nexusrpc.handler import service_handler diff --git a/tests/nexus/test_workflow_caller.py b/tests/nexus/test_workflow_caller.py index 3d4b4f699..c09c6999d 100644 --- a/tests/nexus/test_workflow_caller.py +++ b/tests/nexus/test_workflow_caller.py @@ -5,7 +5,7 @@ from collections.abc import Awaitable, Callable from dataclasses import dataclass from enum import IntEnum -from typing import Any, Union +from typing import Any import nexusrpc import nexusrpc.handler @@ -80,7 +80,7 @@ class AsyncResponse: # The order of the two types in this union is critical since the data converter matches # eagerly, ignoring unknown fields, and so would identify an AsyncResponse as a # SyncResponse if SyncResponse came first. -ResponseType = Union[AsyncResponse, SyncResponse] +ResponseType = AsyncResponse | SyncResponse # ----------------------------------------------------------------------------- # Service interface @@ -179,7 +179,7 @@ def sync_or_async_operation( @sync_operation async def sync_operation( - self, ctx: StartOperationContext, input: OpInput + self, _ctx: StartOperationContext, input: OpInput ) -> OpOutput: assert isinstance(input.response_type, SyncResponse) if input.response_type.exception_in_operation_start: @@ -234,7 +234,7 @@ class CallerWorkflow: def __init__( self, input: CallerWfInput, - request_cancel: bool, + _request_cancel: bool, task_queue: str, ) -> None: self.nexus_client: workflow.NexusClient[ServiceInterface] = ( # type:ignore[reportAttributeAccessIssue] @@ -254,7 +254,7 @@ async def run( self, input: CallerWfInput, request_cancel: bool, - task_queue: str, + _task_queue: str, ) -> CallerWfOutput: op_input = input.op_input try: @@ -375,7 +375,7 @@ def __init__( @workflow.run async def run( - self, input: CallerWfInput, request_cancel: bool, task_queue: str + self, input: CallerWfInput, _request_cancel: bool, _task_queue: str ) -> CallerWfOutput: op_input = input.op_input if op_input.response_type.op_definition_type == OpDefinitionType.LONGHAND: @@ -750,7 +750,7 @@ async def test_untyped_caller( task_queue=task_queue, workflow_failure_exception_types=[Exception], ): - if response_type == SyncResponse: + if type(response_type) == SyncResponse: response_type = SyncResponse( op_definition_type=op_definition_type, use_async_def=True, @@ -823,7 +823,7 @@ class ServiceInterfaceWithNameOverride: class ServiceImplInterfaceWithNeitherInterfaceNorNameOverride: @sync_operation async def op( - self, ctx: StartOperationContext, input: None + self, _ctx: StartOperationContext, _input: None ) -> ServiceClassNameOutput: return ServiceClassNameOutput(self.__class__.__name__) @@ -832,7 +832,7 @@ async def op( class ServiceImplInterfaceWithoutNameOverride: @sync_operation async def op( - self, ctx: StartOperationContext, input: None + self, _ctx: StartOperationContext, _input: None ) -> ServiceClassNameOutput: return ServiceClassNameOutput(self.__class__.__name__) @@ -841,7 +841,7 @@ async def op( class ServiceImplInterfaceWithNameOverride: @sync_operation async def op( - self, ctx: StartOperationContext, input: None + self, _ctx: StartOperationContext, _input: None ) -> ServiceClassNameOutput: return ServiceClassNameOutput(self.__class__.__name__) @@ -850,7 +850,7 @@ async def op( class ServiceImplWithNameOverride: @sync_operation async def op( - self, ctx: StartOperationContext, input: None + self, _ctx: StartOperationContext, _input: None ) -> ServiceClassNameOutput: return ServiceClassNameOutput(self.__class__.__name__) @@ -994,7 +994,7 @@ async def run(self, input: str) -> str: class ServiceImplWithOperationsThatExecuteWorkflowBeforeStartingBackingWorkflow: @workflow_run_operation async def my_workflow_run_operation( - self, ctx: WorkflowRunOperationContext, input: None + self, ctx: WorkflowRunOperationContext, _input: None ) -> nexus.WorkflowHandle[str]: result_1 = await nexus.client().execute_workflow( EchoWorkflow.run, @@ -1015,7 +1015,7 @@ async def my_workflow_run_operation( @workflow.defn class WorkflowCallingNexusOperationThatExecutesWorkflowBeforeStartingBackingWorkflow: @workflow.run - async def run(self, input: str, task_queue: str) -> str: + async def run(self, _input: str, task_queue: str) -> str: nexus_client = workflow.create_nexus_client( service=ServiceImplWithOperationsThatExecuteWorkflowBeforeStartingBackingWorkflow, endpoint=make_nexus_endpoint_name(task_queue), @@ -1059,7 +1059,7 @@ async def test_workflow_run_operation_can_execute_workflow_before_starting_backi @service_handler class SimpleSyncService: @sync_operation - async def sync_op(self, ctx: StartOperationContext, input: str) -> str: + async def sync_op(self, _ctx: StartOperationContext, input: str) -> str: return input diff --git a/tests/nexus/test_workflow_caller_cancellation_types.py b/tests/nexus/test_workflow_caller_cancellation_types.py index 3e2f43e2a..fd5aa84a7 100644 --- a/tests/nexus/test_workflow_caller_cancellation_types.py +++ b/tests/nexus/test_workflow_caller_cancellation_types.py @@ -2,7 +2,7 @@ import uuid from dataclasses import dataclass, field from datetime import datetime, timezone -from typing import Any, Optional +from typing import Any import nexusrpc import nexusrpc.handler._decorators diff --git a/tests/nexus/test_workflow_caller_cancellation_types_when_cancel_handler_fails.py b/tests/nexus/test_workflow_caller_cancellation_types_when_cancel_handler_fails.py index 3114cb357..37aa986ed 100644 --- a/tests/nexus/test_workflow_caller_cancellation_types_when_cancel_handler_fails.py +++ b/tests/nexus/test_workflow_caller_cancellation_types_when_cancel_handler_fails.py @@ -6,7 +6,7 @@ import uuid from dataclasses import dataclass, field from datetime import datetime, timezone -from typing import Any, Optional +from typing import Any import nexusrpc import nexusrpc.handler._decorators diff --git a/tests/nexus/test_workflow_caller_error_chains.py b/tests/nexus/test_workflow_caller_error_chains.py index 4ba9ca6d5..07a575d60 100644 --- a/tests/nexus/test_workflow_caller_error_chains.py +++ b/tests/nexus/test_workflow_caller_error_chains.py @@ -33,7 +33,7 @@ class ErrorConversionTestCase: action_in_nexus_operation: Callable[..., Any] expected_exception_chain_in_workflow: list[tuple[type[Exception], dict[str, Any]]] - def __init_subclass__(cls, **kwargs): + def __init_subclass__(cls, **kwargs): # type:ignore[reportMissingParameterType] super().__init_subclass__(**kwargs) assert cls.__name__ not in error_conversion_test_cases error_conversion_test_cases[cls.__name__] = cls @@ -353,7 +353,7 @@ class ErrorTestInput: @nexusrpc.handler.service_handler class ErrorTestService: @sync_operation - async def op(self, ctx: StartOperationContext, input: ErrorTestInput) -> None: + async def op(self, _ctx: StartOperationContext, input: ErrorTestInput) -> None: error_conversion_test_cases[input.name].action_in_nexus_operation() diff --git a/tests/nexus/test_workflow_caller_errors.py b/tests/nexus/test_workflow_caller_errors.py index 0fc32ba5b..4872de9ca 100644 --- a/tests/nexus/test_workflow_caller_errors.py +++ b/tests/nexus/test_workflow_caller_errors.py @@ -61,14 +61,14 @@ async def run(self) -> None: class ErrorTestService: @nexusrpc.handler.sync_operation def retried_due_to_exception( - self, ctx: nexusrpc.handler.StartOperationContext, input: ErrorTestInput + self, _ctx: nexusrpc.handler.StartOperationContext, input: ErrorTestInput ) -> None: operation_invocation_counts[input.id] += 1 raise Exception @nexusrpc.handler.sync_operation def retried_due_to_retryable_application_error( - self, ctx: nexusrpc.handler.StartOperationContext, input: ErrorTestInput + self, _ctx: nexusrpc.handler.StartOperationContext, input: ErrorTestInput ) -> None: operation_invocation_counts[input.id] += 1 raise ApplicationError( @@ -79,7 +79,7 @@ def retried_due_to_retryable_application_error( @nexusrpc.handler.sync_operation def retried_due_to_resource_exhausted_handler_error( - self, ctx: nexusrpc.handler.StartOperationContext, input: ErrorTestInput + self, _ctx: nexusrpc.handler.StartOperationContext, input: ErrorTestInput ) -> None: operation_invocation_counts[input.id] += 1 raise nexusrpc.HandlerError( @@ -89,7 +89,7 @@ def retried_due_to_resource_exhausted_handler_error( @nexusrpc.handler.sync_operation def retried_due_to_internal_handler_error( - self, ctx: nexusrpc.handler.StartOperationContext, input: ErrorTestInput + self, _ctx: nexusrpc.handler.StartOperationContext, input: ErrorTestInput ) -> None: operation_invocation_counts[input.id] += 1 raise nexusrpc.HandlerError( @@ -99,7 +99,7 @@ def retried_due_to_internal_handler_error( @nexusrpc.handler.sync_operation async def fails_due_to_workflow_already_started( - self, ctx: nexusrpc.handler.StartOperationContext, input: ErrorTestInput + self, _ctx: nexusrpc.handler.StartOperationContext, input: ErrorTestInput ) -> None: operation_invocation_counts[input.id] += 1 for _ in range(2): @@ -240,7 +240,7 @@ async def test_nexus_operation_fails_without_retry_as_handler_error( class StartTimeoutTestService: @sync_operation async def expect_timeout_cancellation_async( - self, ctx: StartOperationContext, input: None + self, ctx: StartOperationContext, _input: None ) -> None: try: await asyncio.wait_for(ctx.task_cancellation.wait_until_cancelled(), 1) @@ -249,7 +249,7 @@ async def expect_timeout_cancellation_async( @sync_operation def expect_timeout_cancellation_sync( - self, ctx: StartOperationContext, input: None + self, ctx: StartOperationContext, _input: None ) -> None: global _start_operation_sync_complete cancelled = ctx.task_cancellation.wait_until_cancelled_sync(1) diff --git a/tests/nexus/test_workflow_run_operation.py b/tests/nexus/test_workflow_run_operation.py index cfbaa91ef..7d284412c 100644 --- a/tests/nexus/test_workflow_run_operation.py +++ b/tests/nexus/test_workflow_run_operation.py @@ -1,7 +1,7 @@ import re import uuid from dataclasses import dataclass -from typing import Any, Type +from typing import Any import nexusrpc import pytest diff --git a/tests/test_client.py b/tests/test_client.py index 0ce6a4fea..833c97fb0 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -6,7 +6,7 @@ import uuid from collections.abc import Mapping from datetime import datetime, timedelta, timezone -from typing import Any, List, Optional, Tuple, Union, cast +from typing import Any, cast from unittest import mock import google.protobuf.any_pb2 @@ -46,8 +46,6 @@ Interceptor, OutboundInterceptor, QueryWorkflowInput, - RPCError, - RPCStatusCode, Schedule, ScheduleActionExecutionStartWorkflow, ScheduleActionStartWorkflow, @@ -86,6 +84,10 @@ ) from temporalio.converter import DataConverter from temporalio.exceptions import WorkflowAlreadyStartedError +from temporalio.service import ( + RPCError, + RPCStatusCode, +) from temporalio.testing import WorkflowEnvironment from tests.helpers import ( assert_eq_eventually, @@ -378,7 +380,7 @@ async def test_query(client: Client, worker: ExternalWorker): await handle.result() assert "some query arg" == await handle.query("some query", "some query arg") # Try a query not on the workflow - with pytest.raises(WorkflowQueryFailedError) as err: + with pytest.raises(WorkflowQueryFailedError): await handle.query("does not exist") @@ -899,7 +901,7 @@ def update_schedule_simple(input: ScheduleUpdateInput) -> ScheduleUpdate: # Update but error with pytest.raises(RuntimeError) as err: - def update_fail(input: ScheduleUpdateInput) -> ScheduleUpdate: + def update_fail(_input: ScheduleUpdateInput) -> ScheduleUpdate: raise RuntimeError("Oh no") await handle.update(update_fail) @@ -919,7 +921,7 @@ def update_fail(input: ScheduleUpdateInput) -> ScheduleUpdate: ) assert isinstance(new_schedule.action, ScheduleActionStartWorkflow) - async def update_schedule_basic(input: ScheduleUpdateInput) -> ScheduleUpdate: + async def update_schedule_basic(_input: ScheduleUpdateInput) -> ScheduleUpdate: return ScheduleUpdate(new_schedule) await handle.update(update_schedule_basic) @@ -1163,7 +1165,7 @@ async def test_schedule_backfill( async def test_schedule_create_limited_actions_validation( - client: Client, worker: ExternalWorker, env: WorkflowEnvironment + client: Client, worker: ExternalWorker ): sched = Schedule( action=ScheduleActionStartWorkflow( diff --git a/tests/test_client_type_errors.py b/tests/test_client_type_errors.py index d0f3b6de5..adf3fcd3c 100644 --- a/tests/test_client_type_errors.py +++ b/tests/test_client_type_errors.py @@ -79,7 +79,7 @@ async def run(self, _: WorkflowInput) -> WorkflowOutput: return WorkflowOutput() -async def _start_and_execute_workflow_code_for_type_checking_test(): +async def _start_and_execute_workflow_code_for_type_checking_test(): # type:ignore[reportUnusedFunction] client = Client(service_client=Mock(spec=ServiceClient)) # Good @@ -117,7 +117,7 @@ async def _start_and_execute_workflow_code_for_type_checking_test(): ) -async def _signal_workflow_code_for_type_checking_test(): +async def _signal_workflow_code_for_type_checking_test(): # type:ignore[reportUnusedFunction] client = Client(service_client=Mock(spec=ServiceClient)) handle: WorkflowHandle[TestWorkflow, WorkflowOutput] = await client.start_workflow( TestWorkflow.run, WorkflowInput(), id="wid", task_queue="tq" @@ -134,7 +134,7 @@ async def _signal_workflow_code_for_type_checking_test(): await handle.signal(TestWorkflow2.signal, SignalInput()) # type: ignore -async def _query_workflow_code_for_type_checking_test(): +async def _query_workflow_code_for_type_checking_test(): # type:ignore[reportUnusedFunction] client = Client(service_client=Mock(spec=ServiceClient)) handle: WorkflowHandle[TestWorkflow, WorkflowOutput] = await client.start_workflow( TestWorkflow.run, WorkflowInput(), id="wid", task_queue="tq" @@ -152,7 +152,7 @@ async def _query_workflow_code_for_type_checking_test(): await handle.query(TestWorkflow2.query, QueryInput()) # type: ignore -async def _update_workflow_code_for_type_checking_test(): +async def _update_workflow_code_for_type_checking_test(): # type:ignore[reportUnusedFunction] client = Client(service_client=Mock(spec=ServiceClient)) handle: WorkflowHandle[TestWorkflow, WorkflowOutput] = await client.start_workflow( TestWorkflow.run, WorkflowInput(), id="wid", task_queue="tq" @@ -186,7 +186,7 @@ async def _update_workflow_code_for_type_checking_test(): await handle.execute_update(TestWorkflow2.update, UpdateInput()) # type: ignore -async def _update_with_start_workflow_code_for_type_checking_test(): +async def _update_with_start_workflow_code_for_type_checking_test(): # type:ignore[reportUnusedFunction] client = Client(service_client=Mock(spec=ServiceClient)) # Good diff --git a/tests/test_common.py b/tests/test_common.py index 5df4767c4..84dfc09b9 100644 --- a/tests/test_common.py +++ b/tests/test_common.py @@ -38,19 +38,19 @@ def test_retry_policy_validate(): RetryPolicy(maximum_attempts=-1)._validate() -def some_hinted_func(foo: str) -> DefinedLater: +def some_hinted_func(_foo: str) -> DefinedLater: return DefinedLater() -async def some_hinted_func_async(foo: str) -> DefinedLater: +async def some_hinted_func_async(_foo: str) -> DefinedLater: return DefinedLater() class MyCallableClass: - def __call__(self, foo: str) -> DefinedLater: + def __call__(self, _foo: str) -> DefinedLater: raise NotImplementedError - def some_method(self, foo: str) -> DefinedLater: + def some_method(self, _foo: str) -> DefinedLater: raise NotImplementedError diff --git a/tests/test_envconfig.py b/tests/test_envconfig.py index 9bd385fce..c1a7e32ab 100644 --- a/tests/test_envconfig.py +++ b/tests/test_envconfig.py @@ -258,7 +258,7 @@ def test_load_profiles_from_data_all(): assert connect_config.get("target_host") == "custom-address" -def test_load_profiles_no_env_override(tmp_path: Path, monkeypatch): +def test_load_profiles_no_env_override(tmp_path: Path, monkeypatch): # type: ignore[reportMissingParameterType] """Confirm that load_profiles does not apply env overrides.""" config_file = tmp_path / "config.toml" config_file.write_text(TOML_CONFIG_BASE) diff --git a/tests/test_plugins.py b/tests/test_plugins.py index ea2cf3a1a..399d16c7e 100644 --- a/tests/test_plugins.py +++ b/tests/test_plugins.py @@ -1,10 +1,9 @@ import dataclasses import uuid import warnings -from collections import Counter from collections.abc import AsyncIterator, Awaitable, Callable from contextlib import AbstractAsyncContextManager, asynccontextmanager -from typing import Optional, cast +from typing import cast import pytest @@ -182,7 +181,7 @@ async def test_worker_duplicated_plugin(client: Client) -> None: client = Client(**new_config) with warnings.catch_warnings(record=True) as warning_list: - worker = Worker( + Worker( client, task_queue="queue" + str(uuid.uuid4()), activities=[never_run_activity], @@ -194,7 +193,7 @@ async def test_worker_duplicated_plugin(client: Client) -> None: async def test_worker_sandbox_restrictions(client: Client) -> None: - with warnings.catch_warnings(record=True) as warning_list: + with warnings.catch_warnings(record=True): worker = Worker( client, task_queue="queue" + str(uuid.uuid4()), diff --git a/tests/test_runtime.py b/tests/test_runtime.py index c2829f03d..bc21d7d6c 100644 --- a/tests/test_runtime.py +++ b/tests/test_runtime.py @@ -4,7 +4,7 @@ import re import uuid from datetime import timedelta -from typing import List, cast +from typing import cast from urllib.request import urlopen import pytest @@ -25,7 +25,6 @@ assert_eq_eventually, assert_eventually, find_free_port, - worker_versioning_enabled, ) diff --git a/tests/test_serialization_context.py b/tests/test_serialization_context.py index 07d48bdd3..4e217861b 100644 --- a/tests/test_serialization_context.py +++ b/tests/test_serialization_context.py @@ -15,7 +15,7 @@ from collections.abc import Sequence from dataclasses import dataclass, field from datetime import timedelta -from typing import Any, List, Literal, Optional, Type +from typing import Any, Literal import nexusrpc import pytest @@ -837,7 +837,7 @@ def __init__(self, pass_validation: bool) -> None: self.input: TraceData | None = None @workflow.run - async def run(self, pass_validation: bool) -> TraceData: + async def run(self, _pass_validation: bool) -> TraceData: await workflow.wait_condition(lambda: self.input is not None) assert self.input return self.input @@ -1583,7 +1583,7 @@ def __init__(self): self.received_update = False @workflow.run - async def run(self, data: str) -> str: + async def run(self, _data: str) -> str: await workflow.wait_condition( lambda: (self.received_signal and self.received_update) ) @@ -1705,7 +1705,7 @@ async def operation( @workflow.defn class NexusOperationTestWorkflow: @workflow.run - async def run(self, data: str) -> None: + async def run(self, _data: str) -> None: nexus_client = workflow.create_nexus_client( service=NexusOperationTestServiceHandler, endpoint=make_nexus_endpoint_name(workflow.info().task_queue), diff --git a/tests/test_workflow.py b/tests/test_workflow.py index becb0d111..c2ea21005 100644 --- a/tests/test_workflow.py +++ b/tests/test_workflow.py @@ -1,7 +1,7 @@ import inspect import itertools from collections.abc import Callable, Sequence -from typing import Any, Set, Type, get_type_hints +from typing import Any, get_type_hints import pytest @@ -11,7 +11,7 @@ class GoodDefnBase: @workflow.run - async def run(self, name: str) -> str: + async def run(self, _name: str) -> str: raise NotImplementedError @workflow.signal @@ -30,7 +30,7 @@ def base_update(self): @workflow.defn(name="workflow-custom") class GoodDefn(GoodDefnBase): @workflow.run - async def run(self, name: str) -> str: + async def run(self, _name: str) -> str: raise NotImplementedError @workflow.signal @@ -42,7 +42,7 @@ def signal2(self): pass @workflow.signal(dynamic=True, description="boo") - def signal3(self, name: str, args: Sequence[RawValue]): + def signal3(self, _name: str, _args: Sequence[RawValue]): pass @workflow.query @@ -54,7 +54,7 @@ def query2(self): pass @workflow.query(dynamic=True, description="dqd") - def query3(self, name: str, args: Sequence[RawValue]): + def query3(self, _name: str, _args: Sequence[RawValue]): pass @workflow.update @@ -66,7 +66,7 @@ def update2(self): pass @workflow.update(dynamic=True, description="dud") - def update3(self, name: str, args: Sequence[RawValue]): + def update3(self, _name: str, _args: Sequence[RawValue]): pass @@ -138,7 +138,7 @@ def test_workflow_defn_good(): @workflow.defn(versioning_behavior=VersioningBehavior.PINNED) class VersioningBehaviorDefn: @workflow.run - async def run(self, name: str) -> str: + async def run(self, _name: str) -> str: raise NotImplementedError @@ -183,11 +183,11 @@ def signal2(self): pass @workflow.signal(dynamic=True) - def signal3(self, name: str, args: Sequence[RawValue]): + def signal3(self, _name: str, _args: Sequence[RawValue]): pass @workflow.signal(dynamic=True) - def signal4(self, name: str, args: Sequence[RawValue]): + def signal4(self, _name: str, _args: Sequence[RawValue]): pass # Intentionally missing decorator @@ -203,11 +203,11 @@ def query2(self): pass @workflow.query(dynamic=True) - def query3(self, name: str, args: Sequence[RawValue]): + def query3(self, _name: str, _args: Sequence[RawValue]): pass @workflow.query(dynamic=True) - def query4(self, name: str, args: Sequence[RawValue]): + def query4(self, _name: str, _args: Sequence[RawValue]): pass # Intentionally missing decorator @@ -215,11 +215,11 @@ def base_query(self): pass @workflow.update - def update1(self, arg1: str): + def update1(self, _arg1: str): pass @workflow.update(name="update1") - def update2(self, arg1: str): + def update2(self, _arg1: str): pass # Intentionally missing decorator @@ -271,7 +271,7 @@ def test_workflow_defn_local_class(): with pytest.raises(ValueError) as err: @workflow.defn - class LocalClass: + class LocalClass: # type:ignore[reportUnusedClass] @workflow.run async def run(self): pass @@ -387,31 +387,31 @@ def a1(self, a): # type: ignore[reportMissingParameterType] def a2(self, b): # type: ignore[reportMissingParameterType] pass - def b1(self, a: int): + def b1(self, _a: int): pass - def b2(self, b: int) -> str: + def b2(self, _b: int) -> str: return "" - def c1(self, a1: int, a2: str) -> str: + def c1(self, _a1: int, _a2: str) -> str: return "" - def c2(self, b1: int, b2: str) -> int: + def c2(self, _b1: int, _b2: str) -> int: return 0 - def d1(self, a1, a2: str) -> None: # type: ignore[reportMissingParameterType] + def d1(self, _a1, _a2: str) -> None: # type: ignore[reportMissingParameterType] pass - def d2(self, b1, b2: str) -> str: # type: ignore[reportMissingParameterType] + def d2(self, _b1, _b2: str) -> str: # type: ignore[reportMissingParameterType] return "" - def e1(self, a1, a2: str = "") -> None: # type: ignore[reportMissingParameterType] + def e1(self, _a1, _a2: str = "") -> None: # type: ignore[reportMissingParameterType] return None - def e2(self, b1, b2: str = "") -> str: # type: ignore[reportMissingParameterType] + def e2(self, _b1, _b2: str = "") -> str: # type: ignore[reportMissingParameterType] return "" - def f1(self, a1, a2: str = "a") -> None: # type: ignore[reportMissingParameterType] + def f1(self, _a1, _a2: str = "a") -> None: # type: ignore[reportMissingParameterType] return None @@ -447,12 +447,12 @@ def test_workflow_init_not__init__(): class BadUpdateValidator: @workflow.update - def my_update(self, a: str): + def my_update(self, _a: str): pass # assert-type-error-pyright: "Argument of type .+ cannot be assigned to parameter" @my_update.validator # type: ignore - def my_validator(self, a: int): + def my_validator(self, _a: int): pass @workflow.run @@ -474,7 +474,6 @@ def _assert_config_function_parity( config_class: type[Any], excluded_params: set[str], ) -> None: - function_name = function_obj.__name__ config_name = config_class.__name__ # Get the signature and type hints diff --git a/tests/testing/test_workflow.py b/tests/testing/test_workflow.py index 1a857a55d..b0082d1cd 100644 --- a/tests/testing/test_workflow.py +++ b/tests/testing/test_workflow.py @@ -1,10 +1,9 @@ import asyncio import platform -import sys import uuid from datetime import datetime, timedelta, timezone from time import monotonic -from typing import Any, Optional, Union +from typing import Any import pytest @@ -13,7 +12,6 @@ Client, Interceptor, OutboundInterceptor, - RPCError, StartWorkflowInput, WorkflowFailureError, WorkflowHandle, @@ -30,6 +28,7 @@ TimeoutError, TimeoutType, ) +from temporalio.service import RPCError from temporalio.testing import WorkflowEnvironment from tests import DEV_SERVER_DOWNLOAD_VERSION from tests.helpers import new_worker diff --git a/tests/worker/test_command_aware_visitor.py b/tests/worker/test_command_aware_visitor.py index 9e4b7a39b..b8488689e 100644 --- a/tests/worker/test_command_aware_visitor.py +++ b/tests/worker/test_command_aware_visitor.py @@ -1,7 +1,7 @@ """Test that CommandAwarePayloadVisitor handles all commands with seq fields that have payloads.""" from collections.abc import Iterator -from typing import Any, Type +from typing import Any from temporalio.bridge._visitor import PayloadVisitor from temporalio.bridge.proto.workflow_activation import workflow_activation_pb2 @@ -15,8 +15,6 @@ def test_command_aware_visitor_has_methods_for_all_seq_protos_with_payloads(): We only override methods when the base class has a visitor method (i.e., there are payloads to visit). Commands without payloads don't need overrides since there's nothing to visit. """ - visitor = CommandAwarePayloadVisitor() - # Find all protos with seq command_protos = list(_get_workflow_command_protos_with_seq()) job_protos = list(_get_workflow_activation_job_protos_with_seq()) diff --git a/tests/worker/test_interceptor.py b/tests/worker/test_interceptor.py index 7746dce2d..602503c6c 100644 --- a/tests/worker/test_interceptor.py +++ b/tests/worker/test_interceptor.py @@ -2,7 +2,7 @@ import uuid from collections.abc import Callable from datetime import timedelta -from typing import Any, List, NoReturn, Optional, Tuple, Type +from typing import Any, NoReturn import pytest @@ -201,7 +201,7 @@ def query(self, param: str) -> str: return f"query: {param}" @workflow.signal - def signal(self, param: str) -> None: + def signal(self, _param: str) -> None: self.finish.set() @workflow.update diff --git a/tests/worker/test_replayer.py b/tests/worker/test_replayer.py index 67c1b1d52..22d771556 100644 --- a/tests/worker/test_replayer.py +++ b/tests/worker/test_replayer.py @@ -6,7 +6,7 @@ from dataclasses import dataclass from datetime import timedelta from pathlib import Path -from typing import Any, Dict, Optional, Type +from typing import Any import pytest diff --git a/tests/worker/test_update_with_start.py b/tests/worker/test_update_with_start.py index 23f997c08..4ed625960 100644 --- a/tests/worker/test_update_with_start.py +++ b/tests/worker/test_update_with_start.py @@ -6,7 +6,7 @@ from dataclasses import dataclass from datetime import timedelta from enum import Enum, IntEnum -from typing import Any, Optional, Union +from typing import Any from unittest.mock import patch import pytest diff --git a/tests/worker/test_visitor.py b/tests/worker/test_visitor.py index 4fb820f31..41e6ccad9 100644 --- a/tests/worker/test_visitor.py +++ b/tests/worker/test_visitor.py @@ -99,14 +99,6 @@ async def test_workflow_activation(): ] ) - async def visitor(payload: Payload) -> Payload: - # Mark visited by prefixing data - new_payload = Payload() - new_payload.metadata.update(payload.metadata) - new_payload.metadata["visited"] = b"True" - new_payload.data = payload.data - return new_payload - act = original.__deepcopy__() await PayloadVisitor().visit(Visitor(), act) assert act.jobs[0].initialize_workflow.arguments[0].metadata["visited"] diff --git a/tests/worker/test_worker.py b/tests/worker/test_worker.py index 483a58cbb..b1b65112d 100644 --- a/tests/worker/test_worker.py +++ b/tests/worker/test_worker.py @@ -7,7 +7,7 @@ import uuid from collections.abc import Awaitable, Callable, Sequence from datetime import timedelta -from typing import Any, Optional +from typing import Any from urllib.request import urlopen import nexusrpc @@ -20,16 +20,13 @@ from temporalio.api.workflowservice.v1 import ( DescribeWorkerDeploymentRequest, DescribeWorkerDeploymentResponse, - ListWorkersRequest, SetWorkerDeploymentCurrentVersionRequest, SetWorkerDeploymentCurrentVersionResponse, SetWorkerDeploymentRampingVersionRequest, SetWorkerDeploymentRampingVersionResponse, ) from temporalio.client import ( - BuildIdOpAddNewDefault, Client, - TaskReachabilityType, ) from temporalio.common import PinnedVersioningOverride, RawValue, VersioningBehavior from temporalio.runtime import ( @@ -64,7 +61,6 @@ assert_eventually, find_free_port, new_worker, - worker_versioning_enabled, ) from tests.helpers.fork import _ForkTestResult, _TestFork from tests.helpers.nexus import create_nexus_endpoint, make_nexus_endpoint_name @@ -239,7 +235,7 @@ async def test_worker_validate_fail(client: Client, env: WorkflowEnvironment): assert str(err.value).startswith("Worker validation failed") -async def test_can_run_resource_based_worker(client: Client, env: WorkflowEnvironment): +async def test_can_run_resource_based_worker(client: Client): tuner = WorkerTuner.create_resource_based( target_memory_usage=0.5, target_cpu_usage=0.5, @@ -262,7 +258,7 @@ async def test_can_run_resource_based_worker(client: Client, env: WorkflowEnviro await wf1.result() -async def test_can_run_composite_tuner_worker(client: Client, env: WorkflowEnvironment): +async def test_can_run_composite_tuner_worker(client: Client): resource_based_options = ResourceBasedTunerConfig(0.5, 0.5) tuner = WorkerTuner.create_composite( workflow_supplier=FixedSizeSlotSupplier(5), @@ -299,9 +295,7 @@ async def test_can_run_composite_tuner_worker(client: Client, env: WorkflowEnvir await wf1.result() -async def test_cant_specify_max_concurrent_and_tuner( - client: Client, env: WorkflowEnvironment -): +async def test_cant_specify_max_concurrent_and_tuner(client: Client): tuner = WorkerTuner.create_resource_based( target_memory_usage=0.5, target_cpu_usage=0.5, @@ -320,7 +314,7 @@ async def test_cant_specify_max_concurrent_and_tuner( assert "when also specifying tuner" in str(err.value) -async def test_warns_when_workers_too_low(client: Client, env: WorkflowEnvironment): +async def test_warns_when_workers_too_low(client: Client): tuner = WorkerTuner.create_resource_based( target_memory_usage=0.5, target_cpu_usage=0.5, @@ -503,7 +497,7 @@ async def run(self) -> str: return "hi" -async def test_throwing_slot_supplier(client: Client, env: WorkflowEnvironment): +async def test_throwing_slot_supplier(client: Client): """Ensures a (mostly) broken slot supplier doesn't hose everything up""" class ThrowingSlotSupplier(CustomSlotSupplier): @@ -546,7 +540,7 @@ def release_slot(self, ctx: SlotReleaseContext) -> None: await wf1.result() -async def test_blocking_slot_supplier(client: Client, env: WorkflowEnvironment): +async def test_blocking_slot_supplier(client: Client): class BlockingSlotSupplier(CustomSlotSupplier): marked_used = False @@ -828,7 +822,7 @@ async def check_results(): @workflow.defn(dynamic=True, versioning_behavior=VersioningBehavior.PINNED) class DynamicWorkflowVersioningOnDefn: @workflow.run - async def run(self, args: Sequence[RawValue]) -> str: + async def run(self, _args: Sequence[RawValue]) -> str: return "dynamic" @@ -841,7 +835,7 @@ def dynamic_config(self) -> DynamicWorkflowConfig: ) @workflow.run - async def run(self, args: Sequence[RawValue]) -> str: + async def run(self, _args: Sequence[RawValue]) -> str: return "dynamic" @@ -922,12 +916,12 @@ async def run(self) -> str: @workflow.defn(dynamic=True) class NoVersioningAnnotationDynamicWorkflow: @workflow.run - async def run(self, args: Sequence[RawValue]) -> str: + async def run(self, _args: Sequence[RawValue]) -> str: return "whee" async def test_workflows_must_have_versioning_behavior_when_feature_turned_on( - client: Client, env: WorkflowEnvironment + client: Client, ): with pytest.raises(ValueError) as exc_info: Worker( @@ -1051,9 +1045,7 @@ async def test_workflows_can_use_versioning_override( ) -async def test_can_run_autoscaling_polling_worker( - client: Client, env: WorkflowEnvironment -): +async def test_can_run_autoscaling_polling_worker(client: Client): # Create new runtime with Prom server prom_addr = f"127.0.0.1:{find_free_port()}" runtime = Runtime( diff --git a/tests/worker/test_workflow.py b/tests/worker/test_workflow.py index 668eabb12..d1d663562 100644 --- a/tests/worker/test_workflow.py +++ b/tests/worker/test_workflow.py @@ -1,3 +1,4 @@ +# pyright: reportUnreachable=false from __future__ import annotations import asyncio @@ -22,14 +23,8 @@ from functools import partial from typing import ( Any, - Dict, - List, Literal, NoReturn, - Optional, - Tuple, - Type, - Union, cast, ) from urllib.request import urlopen @@ -62,8 +57,6 @@ AsyncActivityCancelledError, Client, CreateScheduleInput, - RPCError, - RPCStatusCode, ScheduleActionStartWorkflow, ScheduleHandle, SignalWorkflowInput, @@ -115,7 +108,7 @@ Runtime, TelemetryConfig, ) -from temporalio.service import __version__ +from temporalio.service import RPCError, RPCStatusCode, __version__ from temporalio.testing import WorkflowEnvironment from temporalio.worker import ( ExecuteWorkflowInput, @@ -1195,7 +1188,7 @@ async def test_workflow_cancel_child_started(client: Client, use_execute: bool): @pytest.mark.skip(reason="unable to easily prevent child start currently") -async def test_workflow_cancel_child_unstarted(client: Client): +async def test_workflow_cancel_child_unstarted(_client: Client): raise NotImplementedError @@ -1530,7 +1523,7 @@ async def decode(self, payloads: Sequence[Payload]) -> list[Payload]: return list(wrapper.payloads) -async def test_workflow_with_codec(client: Client, env: WorkflowEnvironment): +async def test_workflow_with_codec(client: Client): # Make client with this codec and run a couple of existing tests config = client.config() config["data_converter"] = DataConverter(payload_codec=SimpleCodec()) @@ -1995,7 +1988,7 @@ def last_signal(self) -> str: return self._last_signal -async def test_workflow_logging(client: Client, env: WorkflowEnvironment): +async def test_workflow_logging(client: Client): workflow.logger.full_workflow_info_on_extra = True with LogCapturer().logs_captured( workflow.logger.base_logger, activity.logger.base_logger @@ -5163,7 +5156,7 @@ class Foo(pydantic.BaseModel): @workflow.defn(failure_exception_types=[pydantic.ValidationError]) class FailOnBadPydanticInputWorkflow: @workflow.run - async def run(self, params: Foo) -> None: + async def run(self, _params: Foo) -> None: pass @@ -5183,7 +5176,7 @@ async def test_workflow_fail_on_bad_pydantic_input(client: Client): @workflow.defn(failure_exception_types=[Exception]) class FailOnBadInputWorkflow: @workflow.run - async def run(self, param: str) -> None: + async def run(self, _param: str) -> None: pass @@ -5276,7 +5269,7 @@ async def test_workflow_replace_worker_client_diff_runtimes_fail(client: Client) @activity.defn(dynamic=True) -async def return_name_activity(args: Sequence[RawValue]) -> str: +async def return_name_activity(_args: Sequence[RawValue]) -> str: return activity.info().activity_type @@ -5635,13 +5628,13 @@ async def run( if handler_dynamism == "-dynamic-": async def my_late_registered_dynamic_update( - name: str, args: Sequence[RawValue] + _name: str, _args: Sequence[RawValue] ) -> str: await workflow.wait_condition(lambda: self.handlers_may_finish) return "my-late-registered-dynamic-update-result" async def my_late_registered_dynamic_signal( - name: str, args: Sequence[RawValue] + _name: str, _args: Sequence[RawValue] ) -> None: await workflow.wait_condition(lambda: self.handlers_may_finish) @@ -5696,12 +5689,12 @@ async def my_signal(self) -> None: await workflow.wait_condition(lambda: self.handlers_may_finish) @workflow.update(dynamic=True) - async def my_dynamic_update(self, name: str, args: Sequence[RawValue]) -> str: + async def my_dynamic_update(self, _name: str, _args: Sequence[RawValue]) -> str: await workflow.wait_condition(lambda: self.handlers_may_finish) return "my-dynamic-update-result" @workflow.signal(dynamic=True) - async def my_dynamic_signal(self, name: str, args: Sequence[RawValue]) -> None: + async def my_dynamic_signal(self, _name: str, _args: Sequence[RawValue]) -> None: await workflow.wait_condition(lambda: self.handlers_may_finish) @@ -5999,7 +5992,6 @@ async def my_update(self) -> str: async def test_update_completion_is_honored_when_after_workflow_return_2( client: Client, - env: WorkflowEnvironment, ): async with Worker( client, @@ -7529,7 +7521,7 @@ def dynamic_config(self) -> temporalio.workflow.DynamicWorkflowConfig: raise Exception("Dynamic config failure") @workflow.run - async def run(self, args: Sequence[RawValue]) -> None: + async def run(self, _args: Sequence[RawValue]) -> None: raise RuntimeError("Should never actually run") @@ -8299,7 +8291,7 @@ async def test_previous_run_failure(client: Client): assert result == "Done" -class EncryptionCodec(PayloadCodec): +class FakeEncryptionCodec(PayloadCodec): def __init__( self, key_id: str = "test-key-id", @@ -8340,7 +8332,6 @@ async def decode(self, payloads: Sequence[Payload]) -> list[Payload]: return ret def encrypt(self, data: bytes) -> bytes: - nonce = os.urandom(12) return data def decrypt(self, data: bytes) -> bytes: @@ -8379,7 +8370,7 @@ async def test_search_attribute_codec(client: Client, env_type: str): config = client.config() config["data_converter"] = dataclasses.replace( - temporalio.converter.default(), payload_codec=EncryptionCodec() + temporalio.converter.default(), payload_codec=FakeEncryptionCodec() ) client = Client(**config) @@ -8390,7 +8381,7 @@ async def test_search_attribute_codec(client: Client, env_type: str): SearchAttributeCodecChildWorkflow, ) as worker: # Run workflow - result = await client.execute_workflow( + await client.execute_workflow( SearchAttributeCodecParentWorkflow.run, "Temporal", id="encryption-workflow-id", @@ -8440,7 +8431,7 @@ async def test_activity_failure_with_encoded_payload_is_decoded_in_workflow( ): config = client.config() config["data_converter"] = dataclasses.replace( - temporalio.converter.default(), payload_codec=EncryptionCodec() + temporalio.converter.default(), payload_codec=FakeEncryptionCodec() ) client = Client(**config) diff --git a/tests/worker/workflow_sandbox/test_restrictions.py b/tests/worker/workflow_sandbox/test_restrictions.py index 27310c1ed..5e0beb1db 100644 --- a/tests/worker/workflow_sandbox/test_restrictions.py +++ b/tests/worker/workflow_sandbox/test_restrictions.py @@ -3,7 +3,7 @@ import pathlib import sys from dataclasses import dataclass -from typing import ClassVar, Dict, Optional +from typing import ClassVar import pytest diff --git a/tests/worker/workflow_sandbox/test_runner.py b/tests/worker/workflow_sandbox/test_runner.py index 5dc1bd02d..b5c7e9476 100644 --- a/tests/worker/workflow_sandbox/test_runner.py +++ b/tests/worker/workflow_sandbox/test_runner.py @@ -12,7 +12,7 @@ from dataclasses import dataclass from datetime import date, datetime, timedelta from enum import IntEnum -from typing import Any, Dict, List, Optional, Set, Type +from typing import Any import pytest @@ -500,7 +500,7 @@ async def execute_workflow(self, input: ExecuteWorkflowInput) -> Any: with workflow.unsafe.sandbox_import_notification_policy( workflow.SandboxImportNotificationPolicy.WARN_ON_UNINTENTIONAL_PASSTHROUGH ): - import tests.worker.workflow_sandbox.testmodules.lazy_module_interceptor # noqa: F401 + import tests.worker.workflow_sandbox.testmodules.lazy_module_interceptor # type:ignore[reportUnusedImport] # noqa: F401 return await super().execute_workflow(input) @@ -517,7 +517,7 @@ class LazyImportWorkflow: @workflow.run async def run(self) -> None: try: - import tests.worker.workflow_sandbox.testmodules.lazy_module # noqa: F401 + import tests.worker.workflow_sandbox.testmodules.lazy_module # type:ignore[reportUnusedImport] # noqa: F401 except UnintentionalPassthroughError as err: raise ApplicationError( str(err), type="UnintentionalPassthroughError" @@ -626,7 +626,7 @@ async def run(self) -> None: SandboxImportNotificationPolicy.SILENT ): try: - import tests.worker.workflow_sandbox.testmodules.lazy_module # noqa: F401 + import tests.worker.workflow_sandbox.testmodules.lazy_module # type:ignore[reportUnusedImport] # noqa: F401 except UserWarning: raise ApplicationError("No warnings were expected") From 4fe9c8130427b06a44677a9e60ecc9e7cbbcc488 Mon Sep 17 00:00:00 2001 From: Tim Conley Date: Thu, 4 Dec 2025 12:59:47 -0800 Subject: [PATCH 09/10] Add basedpyright to poe lint --- pyproject.toml | 2 ++ uv.lock | 30 ++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index a39e4e7d6..c7449d2d0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,6 +38,7 @@ Documentation = "https://docs.temporal.io/docs/python" [dependency-groups] dev = [ + "basedpyright==1.34.0", "cibuildwheel>=2.22.0,<3", "grpcio-tools>=1.48.2,<2", "mypy==1.18.2", @@ -96,6 +97,7 @@ lint-docs = "uv run pydocstyle --ignore-decorators=overload" lint-types = [ { cmd = "uv run pyright" }, { cmd = "uv run mypy --namespace-packages --check-untyped-defs ." }, + { cmd = "uv run basedpyright" } ] run-bench = "uv run python scripts/run_bench.py" test = "uv run pytest" diff --git a/uv.lock b/uv.lock index 6ac333e4b..7668cd0a7 100644 --- a/uv.lock +++ b/uv.lock @@ -208,6 +208,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b9/fa/123043af240e49752f1c4bd24da5053b6bd00cad78c2be53c0d1e8b975bc/backports.tarfile-1.2.0-py3-none-any.whl", hash = "sha256:77e284d754527b01fb1e6fa8a1afe577858ebe4e9dad8919e34c862cb399bc34", size = 30181, upload-time = "2024-05-28T17:01:53.112Z" }, ] +[[package]] +name = "basedpyright" +version = "1.34.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nodejs-wheel-binaries" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a3/77/ded02ba2b400807b291fa2b9d29ac7f473e86a45d1f5212d8276e9029107/basedpyright-1.34.0.tar.gz", hash = "sha256:7ae3b06f644fac15fdd14a00d0d1f12f92a8205ae1609aabd5a0799b1a68be1d", size = 22803348, upload-time = "2025-11-19T14:48:16.38Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2a/9e/ced31964ed49f06be6197bd530958b6ddca9a079a8d7ee0ee7429cae9e27/basedpyright-1.34.0-py3-none-any.whl", hash = "sha256:e76015c1ebb671d2c6d7fef8a12bc0f1b9d15d74e17847b7b95a3a66e187c70f", size = 11865958, upload-time = "2025-11-19T14:48:13.724Z" }, +] + [[package]] name = "bashlex" version = "0.18" @@ -1812,6 +1824,22 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314, upload-time = "2024-06-04T18:44:08.352Z" }, ] +[[package]] +name = "nodejs-wheel-binaries" +version = "24.11.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e4/89/da307731fdbb05a5f640b26de5b8ac0dc463fef059162accfc89e32f73bc/nodejs_wheel_binaries-24.11.1.tar.gz", hash = "sha256:413dfffeadfb91edb4d8256545dea797c237bba9b3faefea973cde92d96bb922", size = 8059, upload-time = "2025-11-18T18:21:58.207Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e4/5f/be5a4112e678143d4c15264d918f9a2dc086905c6426eb44515cf391a958/nodejs_wheel_binaries-24.11.1-py2.py3-none-macosx_13_0_arm64.whl", hash = "sha256:0e14874c3579def458245cdbc3239e37610702b0aa0975c1dc55e2cb80e42102", size = 55114309, upload-time = "2025-11-18T18:21:21.697Z" }, + { url = "https://files.pythonhosted.org/packages/fa/1c/2e9d6af2ea32b65928c42b3e5baa7a306870711d93c3536cb25fc090a80d/nodejs_wheel_binaries-24.11.1-py2.py3-none-macosx_13_0_x86_64.whl", hash = "sha256:c2741525c9874b69b3e5a6d6c9179a6fe484ea0c3d5e7b7c01121c8e5d78b7e2", size = 55285957, upload-time = "2025-11-18T18:21:27.177Z" }, + { url = "https://files.pythonhosted.org/packages/d0/79/35696d7ba41b1bd35ef8682f13d46ba38c826c59e58b86b267458eb53d87/nodejs_wheel_binaries-24.11.1-py2.py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:5ef598101b0fb1c2bf643abb76dfbf6f76f1686198ed17ae46009049ee83c546", size = 59645875, upload-time = "2025-11-18T18:21:33.004Z" }, + { url = "https://files.pythonhosted.org/packages/b4/98/2a9694adee0af72bc602a046b0632a0c89e26586090c558b1c9199b187cc/nodejs_wheel_binaries-24.11.1-py2.py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:cde41d5e4705266688a8d8071debf4f8a6fcea264c61292782672ee75a6905f9", size = 60140941, upload-time = "2025-11-18T18:21:37.228Z" }, + { url = "https://files.pythonhosted.org/packages/d0/d6/573e5e2cba9d934f5f89d0beab00c3315e2e6604eb4df0fcd1d80c5a07a8/nodejs_wheel_binaries-24.11.1-py2.py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:78bc5bb889313b565df8969bb7423849a9c7fc218bf735ff0ce176b56b3e96f0", size = 61644243, upload-time = "2025-11-18T18:21:43.325Z" }, + { url = "https://files.pythonhosted.org/packages/c7/e6/643234d5e94067df8ce8d7bba10f3804106668f7a1050aeb10fdd226ead4/nodejs_wheel_binaries-24.11.1-py2.py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:c79a7e43869ccecab1cae8183778249cceb14ca2de67b5650b223385682c6239", size = 62225657, upload-time = "2025-11-18T18:21:47.708Z" }, + { url = "https://files.pythonhosted.org/packages/4d/1c/2fb05127102a80225cab7a75c0e9edf88a0a1b79f912e1e36c7c1aaa8f4e/nodejs_wheel_binaries-24.11.1-py2.py3-none-win_amd64.whl", hash = "sha256:10197b1c9c04d79403501766f76508b0dac101ab34371ef8a46fcf51773497d0", size = 41322308, upload-time = "2025-11-18T18:21:51.347Z" }, + { url = "https://files.pythonhosted.org/packages/ad/b7/bc0cdbc2cc3a66fcac82c79912e135a0110b37b790a14c477f18e18d90cd/nodejs_wheel_binaries-24.11.1-py2.py3-none-win_arm64.whl", hash = "sha256:376b9ea1c4bc1207878975dfeb604f7aa5668c260c6154dcd2af9d42f7734116", size = 39026497, upload-time = "2025-11-18T18:21:54.634Z" }, +] + [[package]] name = "openai" version = "1.109.1" @@ -2993,6 +3021,7 @@ pydantic = [ [package.dev-dependencies] dev = [ + { name = "basedpyright" }, { name = "cibuildwheel" }, { name = "googleapis-common-protos" }, { name = "grpcio-tools" }, @@ -3035,6 +3064,7 @@ provides-extras = ["grpc", "opentelemetry", "pydantic", "openai-agents"] [package.metadata.requires-dev] dev = [ + { name = "basedpyright", specifier = "==1.34.0" }, { name = "cibuildwheel", specifier = ">=2.22.0,<3" }, { name = "googleapis-common-protos", specifier = "==1.70.0" }, { name = "grpcio-tools", specifier = ">=1.48.2,<2" }, From 1d5ff8fd4fae9d801e1d24a414469d30b3cdb797 Mon Sep 17 00:00:00 2001 From: Tim Conley Date: Tue, 9 Dec 2025 09:42:10 -0800 Subject: [PATCH 10/10] Update with newly included files --- temporalio/bridge/client.py | 6 +- temporalio/bridge/metric.py | 1 - temporalio/bridge/runtime.py | 2 +- temporalio/bridge/testing.py | 1 - temporalio/bridge/worker.py | 31 ++--- temporalio/envconfig.py | 14 +-- temporalio/worker/_replayer.py | 5 +- temporalio/worker/_worker.py | 17 +-- temporalio/worker/_workflow.py | 10 +- .../worker/workflow_sandbox/_importer.py | 17 +-- .../worker/workflow_sandbox/_restrictions.py | 23 ++-- temporalio/workflow.py | 106 +++++++----------- tests/api/test_grpc_stub.py | 2 +- tests/conftest.py | 16 +-- tests/contrib/pydantic/models.py | 36 +++--- tests/contrib/pydantic/models_2.py | 6 - tests/contrib/pydantic/test_pydantic.py | 6 +- tests/contrib/pydantic/workflows.py | 5 +- tests/contrib/test_opentelemetry.py | 34 +++--- tests/nexus/test_workflow_caller.py | 4 +- tests/test_converter.py | 48 ++++---- tests/test_service.py | 4 +- tests/worker/test_activity.py | 15 ++- .../worker/workflow_sandbox/test_importer.py | 6 +- 24 files changed, 168 insertions(+), 247 deletions(-) diff --git a/temporalio/bridge/client.py b/temporalio/bridge/client.py index d89b330fb..564005ef0 100644 --- a/temporalio/bridge/client.py +++ b/temporalio/bridge/client.py @@ -8,13 +8,15 @@ from collections.abc import Mapping from dataclasses import dataclass from datetime import timedelta -from typing import Optional, Tuple, Type, TypeVar, Union +from typing import TypeVar import google.protobuf.message import temporalio.bridge.runtime import temporalio.bridge.temporal_sdk_bridge -from temporalio.bridge.temporal_sdk_bridge import RPCError +from temporalio.bridge.temporal_sdk_bridge import ( + RPCError, # type:ignore[reportUnusedImport] +) @dataclass diff --git a/temporalio/bridge/metric.py b/temporalio/bridge/metric.py index 6bccb82cc..4b8d7453d 100644 --- a/temporalio/bridge/metric.py +++ b/temporalio/bridge/metric.py @@ -6,7 +6,6 @@ from __future__ import annotations from collections.abc import Mapping -from typing import Optional, Union import temporalio.bridge.runtime import temporalio.bridge.temporal_sdk_bridge diff --git a/temporalio/bridge/runtime.py b/temporalio/bridge/runtime.py index 6d718fe03..fa7fb275d 100644 --- a/temporalio/bridge/runtime.py +++ b/temporalio/bridge/runtime.py @@ -7,7 +7,7 @@ from collections.abc import Callable, Mapping, Sequence from dataclasses import dataclass -from typing import Any, Dict, Optional, Type +from typing import Any from typing_extensions import Protocol diff --git a/temporalio/bridge/testing.py b/temporalio/bridge/testing.py index 8db2edc2a..9f0db3098 100644 --- a/temporalio/bridge/testing.py +++ b/temporalio/bridge/testing.py @@ -7,7 +7,6 @@ from collections.abc import Sequence from dataclasses import dataclass -from typing import Optional import temporalio.bridge.runtime import temporalio.bridge.temporal_sdk_bridge diff --git a/temporalio/bridge/worker.py b/temporalio/bridge/worker.py index ea6820865..f37c76f19 100644 --- a/temporalio/bridge/worker.py +++ b/temporalio/bridge/worker.py @@ -8,16 +8,9 @@ from collections.abc import Awaitable, Callable, MutableSequence, Sequence from dataclasses import dataclass from typing import ( - List, - Optional, - Set, - Tuple, TypeAlias, - Union, ) -import temporalio.api.common.v1 -import temporalio.api.history.v1 import temporalio.bridge.client import temporalio.bridge.proto import temporalio.bridge.proto.activity_task @@ -27,7 +20,6 @@ import temporalio.bridge.runtime import temporalio.bridge.temporal_sdk_bridge import temporalio.converter -import temporalio.exceptions from temporalio.api.common.v1.message_pb2 import Payload from temporalio.bridge._visitor import VisitorFunctions from temporalio.bridge.temporal_sdk_bridge import ( @@ -80,10 +72,7 @@ class PollerBehaviorAutoscaling: initial: int -PollerBehavior: TypeAlias = Union[ - PollerBehaviorSimpleMaximum, - PollerBehaviorAutoscaling, -] +PollerBehavior: TypeAlias = PollerBehaviorSimpleMaximum | PollerBehaviorAutoscaling @dataclass @@ -118,11 +107,11 @@ class WorkerVersioningStrategyLegacyBuildIdBased: build_id_with_versioning: str -WorkerVersioningStrategy: TypeAlias = Union[ - WorkerVersioningStrategyNone, - WorkerDeploymentOptions, - WorkerVersioningStrategyLegacyBuildIdBased, -] +WorkerVersioningStrategy: TypeAlias = ( + WorkerVersioningStrategyNone + | WorkerDeploymentOptions + | WorkerVersioningStrategyLegacyBuildIdBased +) @dataclass @@ -150,11 +139,9 @@ class FixedSizeSlotSupplier: num_slots: int -SlotSupplier: TypeAlias = Union[ - FixedSizeSlotSupplier, - ResourceBasedSlotSupplier, - BridgeCustomSlotSupplier, -] +SlotSupplier: TypeAlias = ( + FixedSizeSlotSupplier | ResourceBasedSlotSupplier | BridgeCustomSlotSupplier +) @dataclass diff --git a/temporalio/envconfig.py b/temporalio/envconfig.py index 34078ddfe..1406270a2 100644 --- a/temporalio/envconfig.py +++ b/temporalio/envconfig.py @@ -9,16 +9,16 @@ from collections.abc import Mapping from dataclasses import dataclass, field from pathlib import Path -from typing import Any, Dict, Literal, Optional, TypeAlias, Union, cast +from typing import Any, Literal, TypeAlias, cast from typing_extensions import Self, TypedDict import temporalio.service from temporalio.bridge.temporal_sdk_bridge import envconfig as _bridge_envconfig -DataSource: TypeAlias = Union[ - Path, str, bytes -] # str represents a file contents, bytes represents raw data +DataSource: TypeAlias = ( + Path | str | bytes +) # str represents a file contents, bytes represents raw data # We define typed dictionaries for what these configs look like as TOML. @@ -76,7 +76,7 @@ def _source_to_path_and_data( elif isinstance(source, bytes): data = source elif source is not None: - raise TypeError( + raise TypeError( # type: ignore[reportUnreachable] "config_source must be one of pathlib.Path, str, bytes, or None, " f"but got {type(source).__name__}" ) @@ -93,7 +93,7 @@ def _read_source(source: DataSource | None) -> bytes | None: return source.encode("utf-8") if isinstance(source, bytes): return source - raise TypeError( + raise TypeError( # type: ignore[reportUnreachable] f"Source must be one of pathlib.Path, str, or bytes, but got {type(source).__name__}" ) @@ -248,7 +248,7 @@ def to_client_connect_config(self) -> ClientConnectConfig: config["rpc_metadata"] = self.grpc_meta # Cast to ClientConnectConfig - this is safe because we've only included non-None values - return cast(ClientConnectConfig, config) + return cast(ClientConnectConfig, config) # type: ignore[reportInvalidCast] @staticmethod def load( diff --git a/temporalio/worker/_replayer.py b/temporalio/worker/_replayer.py index 26c5961d4..7c93a453b 100644 --- a/temporalio/worker/_replayer.py +++ b/temporalio/worker/_replayer.py @@ -8,7 +8,6 @@ from collections.abc import AsyncIterator, Mapping, Sequence from contextlib import AbstractAsyncContextManager, asynccontextmanager from dataclasses import dataclass -from typing import Dict, Optional, Type from typing_extensions import TypedDict @@ -180,7 +179,7 @@ def workflow_replay_iterator( replayed. """ - def make_lambda(plugin, next): + def make_lambda(plugin, next): # type: ignore[reportMissingParameterType] return lambda r, hs: plugin.run_replayer(r, hs, next) next_function = lambda r, hs: r._workflow_replay_iterator(hs) @@ -204,7 +203,7 @@ async def _workflow_replay_iterator( # Create eviction hook def on_eviction_hook( - run_id: str, + _run_id: str, remove_job: temporalio.bridge.proto.workflow_activation.RemoveFromCache, ) -> None: nonlocal last_replay_failure diff --git a/temporalio/worker/_worker.py b/temporalio/worker/_worker.py index bbe02c54e..f664c0877 100644 --- a/temporalio/worker/_worker.py +++ b/temporalio/worker/_worker.py @@ -13,11 +13,7 @@ from datetime import timedelta from typing import ( Any, - List, - Optional, - Type, TypeAlias, - Union, cast, ) @@ -82,10 +78,7 @@ def _to_bridge(self) -> temporalio.bridge.worker.PollerBehavior: ) -PollerBehavior: TypeAlias = Union[ - PollerBehaviorSimpleMaximum, - PollerBehaviorAutoscaling, -] +PollerBehavior: TypeAlias = PollerBehaviorSimpleMaximum | PollerBehaviorAutoscaling class Worker: @@ -471,7 +464,7 @@ def _init_from_config(self, client: temporalio.client.Client, config: WorkerConf == temporalio.common.VersioningBehavior.UNSPECIFIED ) - def check_activity(activity): + def check_activity(activity: str): if self._activity_worker is None: raise ValueError( f"Activity function {activity} " @@ -711,7 +704,7 @@ async def run(self) -> None: explicit shutdown instead. """ - def make_lambda(plugin, next): + def make_lambda(plugin: Plugin, next: Callable[[Worker], Awaitable[None]]): return lambda w: plugin.run_worker(w, next) next_function = lambda w: w._run() @@ -865,7 +858,7 @@ async def run(): self._async_context_run_task = asyncio.create_task(run()) return self - async def __aexit__(self, exc_type: type[BaseException] | None, *args) -> None: + async def __aexit__(self, exc_type: type[BaseException] | None, *args: Any) -> None: """Same as :py:meth:`shutdown` for use by ``async with``. Note, this will raise the worker fatal error if one occurred and the @@ -1077,7 +1070,7 @@ def _extract_bridge_client_for_worker( elif hasattr(client.service_client, "worker_service_client"): bridge_client = client.service_client.worker_service_client if not isinstance(bridge_client, temporalio.service._BridgeServiceClient): - raise TypeError( + raise TypeError( # type: ignore[reportUnreachable] "Client's worker_service_client cannot be used for a worker" ) else: diff --git a/temporalio/worker/_workflow.py b/temporalio/worker/_workflow.py index 2e4b48469..16e0de5e8 100644 --- a/temporalio/worker/_workflow.py +++ b/temporalio/worker/_workflow.py @@ -61,12 +61,10 @@ def __init__( debug_mode: bool, disable_eager_activity_execution: bool, metric_meter: temporalio.common.MetricMeter, - on_eviction_hook: None - | ( - Callable[ - [str, temporalio.bridge.proto.workflow_activation.RemoveFromCache], None - ] - ), + on_eviction_hook: Callable[ + [str, temporalio.bridge.proto.workflow_activation.RemoveFromCache], None + ] + | None, disable_safe_eviction: bool, should_enforce_versioning_behavior: bool, assert_local_activity_valid: Callable[[str], None], diff --git a/temporalio/worker/workflow_sandbox/_importer.py b/temporalio/worker/workflow_sandbox/_importer.py index 8dde47254..010c0c082 100644 --- a/temporalio/worker/workflow_sandbox/_importer.py +++ b/temporalio/worker/workflow_sandbox/_importer.py @@ -19,12 +19,7 @@ from contextlib import ExitStack, contextmanager from typing import ( Any, - Dict, Generic, - List, - Optional, - Set, - Tuple, TypeVar, no_type_check, ) @@ -79,7 +74,7 @@ def __init__( ) if builtin_matcher: - def restrict_built_in(name: str, orig: Any, *args, **kwargs): + def restrict_built_in(name: str, orig: Any, *args: Any, **kwargs: Any): # Check if restricted against matcher if ( builtin_matcher @@ -147,7 +142,9 @@ def applied(self) -> Iterator[None]: try: with _thread_local_sys_modules.applied(sys, "modules", self.new_modules): with _thread_local_import.applied( - builtins, "__import__", self.import_func + builtins, + "__import__", + self.import_func, # type: ignore[reportArgumentType] ): with self._builtins_restricted(): yield None @@ -480,15 +477,11 @@ def __setitem__(self, key: str, value: types.ModuleType) -> None: def __or__( self, other: Mapping[str, types.ModuleType] ) -> dict[str, types.ModuleType]: - if sys.version_info < (3, 9): - raise NotImplementedError return self.current.__or__(other) # type: ignore[operator] def __ior__( self, other: Mapping[str, types.ModuleType] ) -> dict[str, types.ModuleType]: - if sys.version_info < (3, 9): - raise NotImplementedError return self.current.__ior__(other) __ror__ = __or__ @@ -497,7 +490,7 @@ def copy(self) -> dict[str, types.ModuleType]: return self.current.copy() @classmethod - def fromkeys(cls, *args, **kwargs) -> Any: + def fromkeys(cls, *args: Any, **kwargs: Any) -> Any: return dict.fromkeys(*args, **kwargs) def _lazily_passthrough_if_available(self, key: str) -> types.ModuleType | None: diff --git a/temporalio/worker/workflow_sandbox/_restrictions.py b/temporalio/worker/workflow_sandbox/_restrictions.py index 34f517de1..126b1cf5a 100644 --- a/temporalio/worker/workflow_sandbox/_restrictions.py +++ b/temporalio/worker/workflow_sandbox/_restrictions.py @@ -23,11 +23,6 @@ from typing import ( Any, ClassVar, - Dict, - Optional, - Set, - Tuple, - Type, TypeVar, cast, ) @@ -38,7 +33,7 @@ HAVE_PYDANTIC = True except ImportError: - HAVE_PYDANTIC = False + HAVE_PYDANTIC = False # type: ignore[reportConstantRedefinition] import temporalio.exceptions import temporalio.workflow @@ -873,7 +868,7 @@ def __init__( if hasattr(access_func, "__get__"): # A Python function, can be turned into a bound method. - def _bind_func(instance: _RestrictedProxy, obj: Any) -> Callable: + def _bind_func(_instance: _RestrictedProxy, obj: Any) -> Callable: return access_func.__get__(obj, type(obj)) # type: ignore bind_func = _bind_func @@ -881,7 +876,7 @@ def _bind_func(instance: _RestrictedProxy, obj: Any) -> Callable: elif access_func is not None: # A C function, use partial to bind the first argument. - def _bind_func(instance: _RestrictedProxy, obj: Any) -> Callable: + def _bind_func(_instance: _RestrictedProxy, obj: Any) -> Callable: return functools.partial(access_func, obj) # type: ignore bind_func = _bind_func @@ -896,12 +891,12 @@ def _bind_func(instance: _RestrictedProxy, obj: Any) -> Callable: self.is_attr = is_attr def __set_name__(self, owner: _RestrictedProxy, name: str) -> None: - self.name = name + self.name = name # type: ignore[reportUninitializedInstanceVariable] def __get__(self, instance: _RestrictedProxy, owner: type | None = None) -> Any: - if instance is None: - if self.class_value is not None: - return self.class_value + if instance is None: # type: ignore[reportUninitializedInstanceVariable] + if self.class_value is not None: # type: ignore[reportUnreachable] + return self.class_value # type: ignore[reportUnreachable] return self @@ -989,7 +984,7 @@ def _is_restrictable(v: Any) -> bool: class _RestrictedProxy: - def __init__(self, *args, **kwargs) -> None: + def __init__(self, *args: Any, **kwargs: Any) -> None: # When we instantiate this class, we have the signature of: # __init__( # self, @@ -1037,7 +1032,7 @@ def __setattr__(self, __name: str, __value: Any) -> None: state.assert_child_not_restricted(__name) setattr(state.obj, __name, __value) - def __call__(self, *args, **kwargs) -> _RestrictedProxy: + def __call__(self, *args: Any, **kwargs: Any) -> _RestrictedProxy: state = _RestrictionState.from_proxy(self) _trace("__call__ on %s", state.name) state.assert_child_not_restricted("__call__") diff --git a/temporalio/workflow.py b/temporalio/workflow.py index e561a45ad..30cb2f472 100644 --- a/temporalio/workflow.py +++ b/temporalio/workflow.py @@ -30,16 +30,11 @@ TYPE_CHECKING, Any, Concatenate, - Dict, Generic, - List, Literal, NoReturn, - Optional, - Tuple, - Type, + Type, # type: ignore[reportDeprecated] TypeVar, - Union, cast, overload, ) @@ -57,7 +52,6 @@ import temporalio.bridge.proto.child_workflow import temporalio.bridge.proto.common import temporalio.bridge.proto.nexus -import temporalio.bridge.proto.workflow_activation import temporalio.bridge.proto.workflow_commands import temporalio.common import temporalio.converter @@ -913,7 +907,7 @@ def workflow_last_failure(self) -> BaseException | None: ... ) -def _set_current_update_info(info: UpdateInfo) -> None: +def _set_current_update_info(info: UpdateInfo) -> None: # type: ignore[reportUnusedFunction] _current_update_info.set(info) @@ -1687,7 +1681,7 @@ def get_name_and_result_type( raise ValueError("Cannot invoke dynamic workflow explicitly") return defn.name, defn.ret_type else: - raise TypeError("Workflow must be a string or callable") + raise TypeError("Workflow must be a string or callable") # type: ignore[reportUnreachable] @staticmethod def _apply_to_class( @@ -1892,7 +1886,7 @@ def _bind_method(obj: Any, fn: Callable[..., Any]) -> Callable[..., Any]: # considered an inspect.iscoroutinefunction fn = cast(Callable[..., Awaitable[Any]], fn) - async def with_object(*args, **kwargs) -> Any: + async def with_object(*args: Any, **kwargs: Any) -> Any: return await fn(obj, *args, **kwargs) return with_object @@ -2525,7 +2519,7 @@ async def execute_activity( # Overload for async no-param activity @overload def start_activity_class( - activity: Type[CallableAsyncNoParam[ReturnType]], + activity: Type[CallableAsyncNoParam[ReturnType]], # type: ignore[reportDeprecated] *, task_queue: str | None = None, schedule_to_close_timeout: timedelta | None = None, @@ -2544,7 +2538,7 @@ def start_activity_class( # Overload for sync no-param activity @overload def start_activity_class( - activity: Type[CallableSyncNoParam[ReturnType]], + activity: Type[CallableSyncNoParam[ReturnType]], # type: ignore[reportDeprecated] *, task_queue: str | None = None, schedule_to_close_timeout: timedelta | None = None, @@ -2563,7 +2557,7 @@ def start_activity_class( # Overload for async single-param activity @overload def start_activity_class( - activity: Type[CallableAsyncSingleParam[ParamType, ReturnType]], + activity: Type[CallableAsyncSingleParam[ParamType, ReturnType]], # type: ignore[reportDeprecated] arg: ParamType, *, task_queue: str | None = None, @@ -2583,7 +2577,7 @@ def start_activity_class( # Overload for sync single-param activity @overload def start_activity_class( - activity: Type[CallableSyncSingleParam[ParamType, ReturnType]], + activity: Type[CallableSyncSingleParam[ParamType, ReturnType]], # type: ignore[reportDeprecated] arg: ParamType, *, task_queue: str | None = None, @@ -2603,7 +2597,7 @@ def start_activity_class( # Overload for async multi-param activity @overload def start_activity_class( - activity: Type[Callable[..., Awaitable[ReturnType]]], + activity: Type[Callable[..., Awaitable[ReturnType]]], # type: ignore[reportDeprecated] *, args: Sequence[Any], task_queue: str | None = None, @@ -2623,7 +2617,7 @@ def start_activity_class( # Overload for sync multi-param activity @overload def start_activity_class( - activity: Type[Callable[..., ReturnType]], + activity: Type[Callable[..., ReturnType]], # type: ignore[reportDeprecated] *, args: Sequence[Any], task_queue: str | None = None, @@ -2641,7 +2635,7 @@ def start_activity_class( def start_activity_class( - activity: Type[Callable], + activity: Type[Callable], # type: ignore[reportDeprecated] arg: Any = temporalio.common._arg_unset, *, args: Sequence[Any] = [], @@ -2682,7 +2676,7 @@ def start_activity_class( # Overload for async no-param activity @overload async def execute_activity_class( - activity: Type[CallableAsyncNoParam[ReturnType]], + activity: Type[CallableAsyncNoParam[ReturnType]], # type: ignore[reportDeprecated] *, task_queue: str | None = None, schedule_to_close_timeout: timedelta | None = None, @@ -2701,7 +2695,7 @@ async def execute_activity_class( # Overload for sync no-param activity @overload async def execute_activity_class( - activity: Type[CallableSyncNoParam[ReturnType]], + activity: Type[CallableSyncNoParam[ReturnType]], # type: ignore[reportDeprecated] *, task_queue: str | None = None, schedule_to_close_timeout: timedelta | None = None, @@ -2720,7 +2714,7 @@ async def execute_activity_class( # Overload for async single-param activity @overload async def execute_activity_class( - activity: Type[CallableAsyncSingleParam[ParamType, ReturnType]], + activity: Type[CallableAsyncSingleParam[ParamType, ReturnType]], # type: ignore[reportDeprecated] arg: ParamType, *, task_queue: str | None = None, @@ -2740,7 +2734,7 @@ async def execute_activity_class( # Overload for sync single-param activity @overload async def execute_activity_class( - activity: Type[CallableSyncSingleParam[ParamType, ReturnType]], + activity: Type[CallableSyncSingleParam[ParamType, ReturnType]], # type: ignore[reportDeprecated] arg: ParamType, *, task_queue: str | None = None, @@ -2760,7 +2754,7 @@ async def execute_activity_class( # Overload for async multi-param activity @overload async def execute_activity_class( - activity: Type[Callable[..., Awaitable[ReturnType]]], + activity: Type[Callable[..., Awaitable[ReturnType]]], # type: ignore[reportDeprecated] *, args: Sequence[Any], task_queue: str | None = None, @@ -2780,7 +2774,7 @@ async def execute_activity_class( # Overload for sync multi-param activity @overload async def execute_activity_class( - activity: Type[Callable[..., ReturnType]], + activity: Type[Callable[..., ReturnType]], # type: ignore[reportDeprecated] *, args: Sequence[Any], task_queue: str | None = None, @@ -2798,7 +2792,7 @@ async def execute_activity_class( async def execute_activity_class( - activity: Type[Callable], + activity: Type[Callable], # type: ignore[reportDeprecated] arg: Any = temporalio.common._arg_unset, *, args: Sequence[Any] = [], @@ -3505,7 +3499,7 @@ async def execute_local_activity( # Overload for async no-param activity @overload def start_local_activity_class( - activity: type[CallableAsyncNoParam[ReturnType]], + activity: Type[CallableAsyncNoParam[ReturnType]], # type: ignore[reportDeprecated] *, schedule_to_close_timeout: timedelta | None = None, schedule_to_start_timeout: timedelta | None = None, @@ -3520,7 +3514,7 @@ def start_local_activity_class( # Overload for sync no-param activity @overload def start_local_activity_class( - activity: type[CallableSyncNoParam[ReturnType]], + activity: Type[CallableSyncNoParam[ReturnType]], # type: ignore[reportDeprecated] *, schedule_to_close_timeout: timedelta | None = None, schedule_to_start_timeout: timedelta | None = None, @@ -3535,7 +3529,7 @@ def start_local_activity_class( # Overload for async single-param activity @overload def start_local_activity_class( - activity: type[CallableAsyncSingleParam[ParamType, ReturnType]], + activity: Type[CallableAsyncSingleParam[ParamType, ReturnType]], # type: ignore[reportDeprecated] arg: ParamType, *, schedule_to_close_timeout: timedelta | None = None, @@ -3551,7 +3545,7 @@ def start_local_activity_class( # Overload for sync single-param activity @overload def start_local_activity_class( - activity: type[CallableSyncSingleParam[ParamType, ReturnType]], + activity: Type[CallableSyncSingleParam[ParamType, ReturnType]], # type: ignore[reportDeprecated] arg: ParamType, *, schedule_to_close_timeout: timedelta | None = None, @@ -3567,7 +3561,7 @@ def start_local_activity_class( # Overload for async multi-param activity @overload def start_local_activity_class( - activity: Type[Callable[..., Awaitable[ReturnType]]], + activity: Type[Callable[..., Awaitable[ReturnType]]], # type: ignore[reportDeprecated] *, args: Sequence[Any], schedule_to_close_timeout: timedelta | None = None, @@ -3583,7 +3577,7 @@ def start_local_activity_class( # Overload for sync multi-param activity @overload def start_local_activity_class( - activity: Type[Callable[..., ReturnType]], + activity: Type[Callable[..., ReturnType]], # type: ignore[reportDeprecated] *, args: Sequence[Any], schedule_to_close_timeout: timedelta | None = None, @@ -3597,7 +3591,7 @@ def start_local_activity_class( def start_local_activity_class( - activity: Type[Callable], + activity: Type[Callable], # type: ignore[reportDeprecated] arg: Any = temporalio.common._arg_unset, *, args: Sequence[Any] = [], @@ -3632,7 +3626,7 @@ def start_local_activity_class( # Overload for async no-param activity @overload async def execute_local_activity_class( - activity: Type[CallableAsyncNoParam[ReturnType]], + activity: Type[CallableAsyncNoParam[ReturnType]], # type: ignore[reportDeprecated] *, schedule_to_close_timeout: timedelta | None = None, schedule_to_start_timeout: timedelta | None = None, @@ -3648,7 +3642,7 @@ async def execute_local_activity_class( # Overload for sync no-param activity @overload async def execute_local_activity_class( - activity: Type[CallableSyncNoParam[ReturnType]], + activity: Type[CallableSyncNoParam[ReturnType]], # type: ignore[reportDeprecated] *, schedule_to_close_timeout: timedelta | None = None, schedule_to_start_timeout: timedelta | None = None, @@ -3664,7 +3658,7 @@ async def execute_local_activity_class( # Overload for async single-param activity @overload async def execute_local_activity_class( - activity: Type[CallableAsyncSingleParam[ParamType, ReturnType]], + activity: Type[CallableAsyncSingleParam[ParamType, ReturnType]], # type: ignore[reportDeprecated] arg: ParamType, *, schedule_to_close_timeout: timedelta | None = None, @@ -3681,7 +3675,7 @@ async def execute_local_activity_class( # Overload for sync single-param activity @overload async def execute_local_activity_class( - activity: Type[CallableSyncSingleParam[ParamType, ReturnType]], + activity: Type[CallableSyncSingleParam[ParamType, ReturnType]], # type: ignore[reportDeprecated] arg: ParamType, *, schedule_to_close_timeout: timedelta | None = None, @@ -3698,7 +3692,7 @@ async def execute_local_activity_class( # Overload for async multi-param activity @overload async def execute_local_activity_class( - activity: Type[Callable[..., Awaitable[ReturnType]]], + activity: Type[Callable[..., Awaitable[ReturnType]]], # type: ignore[reportDeprecated] *, args: Sequence[Any], schedule_to_close_timeout: timedelta | None = None, @@ -3715,7 +3709,7 @@ async def execute_local_activity_class( # Overload for sync multi-param activity @overload async def execute_local_activity_class( - activity: Type[Callable[..., ReturnType]], + activity: Type[Callable[..., ReturnType]], # type: ignore[reportDeprecated] *, args: Sequence[Any], schedule_to_close_timeout: timedelta | None = None, @@ -3730,7 +3724,7 @@ async def execute_local_activity_class( async def execute_local_activity_class( - activity: Type[Callable], + activity: Type[Callable], # type: ignore[reportDeprecated] arg: Any = temporalio.common._arg_unset, *, args: Sequence[Any] = [], @@ -4082,10 +4076,10 @@ async def signal( async def signal( self, - signal: str | Callable, - arg: Any = temporalio.common._arg_unset, + signal: str | Callable, # type: ignore[reportUnusedParameter] + arg: Any = temporalio.common._arg_unset, # type: ignore[reportUnusedParameter] *, - args: Sequence[Any] = [], + args: Sequence[Any] = [], # type: ignore[reportUnusedParameter] ) -> None: """Signal this child workflow. @@ -4594,10 +4588,10 @@ async def signal( async def signal( self, - signal: str | Callable, - arg: Any = temporalio.common._arg_unset, + signal: str | Callable, # type: ignore[reportUnusedParameter] + arg: Any = temporalio.common._arg_unset, # type: ignore[reportUnusedParameter] *, - args: Sequence[Any] = [], + args: Sequence[Any] = [], # type: ignore[reportUnusedParameter] ) -> None: """Signal this external workflow. @@ -4638,9 +4632,8 @@ def get_external_workflow_handle( def get_external_workflow_handle_for( - workflow: ( - MethodAsyncNoParam[SelfType, Any] | MethodAsyncSingleParam[SelfType, Any, Any] - ), + workflow: MethodAsyncNoParam[SelfType, Any] # type: ignore[reportUnusedParameter] + | MethodAsyncSingleParam[SelfType, Any, Any], workflow_id: str, *, run_id: str | None = None, @@ -5036,7 +5029,7 @@ def _on_timeout(): done.put_nowait(None) # Queue a dummy value for _wait_for_one(). todo.clear() # Can't do todo.remove(f) in the loop. - def _on_completion(f): + def _on_completion(f): # type:ignore[reportMissingParameterType] if not todo: return # _on_timeout() was here first. todo.remove(f) @@ -5135,7 +5128,7 @@ async def _wait( timeout_handle = loop.call_later(timeout, _release_waiter, waiter) counter = len(fs) # type: ignore[arg-type] - def _on_completion(f): + def _on_completion(f): # type:ignore[reportMissingParameterType] nonlocal counter counter -= 1 if ( @@ -5169,7 +5162,7 @@ def _on_completion(f): return done, pending -def _release_waiter(waiter: asyncio.Future[Any], *args) -> None: +def _release_waiter(waiter: asyncio.Future[Any], *_args: Any) -> None: # Taken almost verbatim from # https://github.com/python/cpython/blob/v3.12.3/Lib/asyncio/tasks.py#L467 @@ -5186,19 +5179,6 @@ def _is_unbound_method_on_cls(fn: Callable[..., Any], cls: type) -> bool: ) -class _UnexpectedEvictionError(temporalio.exceptions.TemporalError): - def __init__( - self, - reason: temporalio.bridge.proto.workflow_activation.RemoveFromCache.EvictionReason.ValueType, - message: str, - ) -> None: - self.reason = temporalio.bridge.proto.workflow_activation.RemoveFromCache.EvictionReason.Name( - reason - ) - self.message = message - super().__init__(f"{self.reason}: {message}") - - class NondeterminismError(temporalio.exceptions.TemporalError): """Error that can be thrown during replay for non-deterministic workflow.""" diff --git a/tests/api/test_grpc_stub.py b/tests/api/test_grpc_stub.py index ba00774e0..64ac90256 100644 --- a/tests/api/test_grpc_stub.py +++ b/tests/api/test_grpc_stub.py @@ -1,7 +1,7 @@ import re from collections.abc import Mapping from datetime import timedelta -from typing import Any, Union, cast +from typing import Any, cast import pytest from google.protobuf.empty_pb2 import Empty diff --git a/tests/conftest.py b/tests/conftest.py index 41f8e1f38..cdf7dbea5 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -44,13 +44,13 @@ ), f"Expected protobuf 4.x/5.x/6.x, got {protobuf_version}" -def pytest_runtest_setup(item): +def pytest_runtest_setup(item): # type: ignore[reportMissingParameterType] """Print a newline so that custom printed output starts on new line.""" if item.config.getoption("-s"): print() -def pytest_addoption(parser): +def pytest_addoption(parser): # type: ignore[reportMissingParameterType] parser.addoption( "-E", "--workflow-environment", @@ -77,7 +77,7 @@ def __init__(self, underlying: asyncio.AbstractEventLoopPolicy): # type: ignore def get_event_loop(self): return self._underlying.get_event_loop() - def set_event_loop(self, loop): + def set_event_loop(self, loop): # type: ignore[reportMissingParameterType] return self._underlying.set_event_loop(loop) def new_event_loop(self): # type: ignore[reportIncompatibleMethodOverride] @@ -86,7 +86,7 @@ def new_event_loop(self): # type: ignore[reportIncompatibleMethodOverride] def get_child_watcher(self): return self._underlying.get_child_watcher() - def set_child_watcher(self, watcher): + def set_child_watcher(self, watcher): # type: ignore[reportMissingParameterType] return self._underlying.set_child_watcher(watcher) @@ -95,7 +95,7 @@ def env_type(request: pytest.FixtureRequest) -> str: return request.config.getoption("--workflow-environment") # type: ignore[reportReturnType] -@pytest_asyncio.fixture(scope="session") +@pytest_asyncio.fixture(scope="session") # type: ignore[reportUntypedFunctionDecorator] async def env(env_type: str) -> AsyncGenerator[WorkflowEnvironment, None]: if env_type == "local": http_port = 7243 @@ -163,12 +163,12 @@ def mp_fork_ctx() -> Iterator[multiprocessing.context.BaseContext | None]: p.join() -@pytest_asyncio.fixture +@pytest_asyncio.fixture # type: ignore[reportUntypedFunctionDecorator] async def client(env: WorkflowEnvironment) -> Client: return env.client -@pytest_asyncio.fixture(scope="session") +@pytest_asyncio.fixture(scope="session") # type: ignore[reportUntypedFunctionDecorator] async def worker( env: WorkflowEnvironment, ) -> AsyncGenerator[ExternalWorker, None]: @@ -182,7 +182,7 @@ async def worker( # hook forcefully kills the process as success when the exit code from pytest # is a success. @pytest.hookimpl(hookwrapper=True, trylast=True) -def pytest_cmdline_main(config): +def pytest_cmdline_main(config): # type: ignore[reportMissingParameterType, reportUnusedParameter] result = yield if result.get_result() == 0: os._exit(0) diff --git a/tests/contrib/pydantic/models.py b/tests/contrib/pydantic/models.py index 97e2694db..dddeb5d7e 100644 --- a/tests/contrib/pydantic/models.py +++ b/tests/contrib/pydantic/models.py @@ -7,12 +7,8 @@ from typing import ( Annotated, Any, - Dict, Generic, - List, - Tuple, TypeVar, - Union, cast, ) @@ -370,21 +366,21 @@ def _assert_timedelta_validity(td: timedelta): assert issubclass(td.__class__, timedelta) -PydanticModels = Union[ - StandardTypesModel, - StrictStandardTypesModel, - ComplexTypesModel, - SpecialTypesModel, - StrictSpecialTypesModel, - ParentModel, - FieldFeaturesModel, - AnnotatedFieldsModel, - GenericModel[Any], - UnionModel, - PydanticDatetimeModel, - PydanticDateModel, - PydanticTimedeltaModel, -] +PydanticModels = ( + StandardTypesModel + | StrictStandardTypesModel + | ComplexTypesModel + | SpecialTypesModel + | StrictSpecialTypesModel + | ParentModel + | FieldFeaturesModel + | AnnotatedFieldsModel + | GenericModel[Any] + | UnionModel + | PydanticDatetimeModel + | PydanticDateModel + | PydanticTimedeltaModel +) def make_list_of_pydantic_objects() -> list[PydanticModels]: @@ -419,7 +415,7 @@ def make_dataclass_objects() -> list[MyDataClass]: ComplexCustomType = tuple[list[MyDataClass], list[PydanticModels]] -ComplexCustomUnionType = list[Union[MyDataClass, PydanticModels]] +ComplexCustomUnionType = list[MyDataClass | PydanticModels] class PydanticModelWithStrictField(BaseModel): diff --git a/tests/contrib/pydantic/models_2.py b/tests/contrib/pydantic/models_2.py index decec56df..4794f95a4 100644 --- a/tests/contrib/pydantic/models_2.py +++ b/tests/contrib/pydantic/models_2.py @@ -7,13 +7,7 @@ from re import Pattern from typing import ( Any, - Dict, - List, NamedTuple, - Optional, - Set, - Tuple, - Union, cast, ) diff --git a/tests/contrib/pydantic/test_pydantic.py b/tests/contrib/pydantic/test_pydantic.py index c70eee56f..69a723a56 100644 --- a/tests/contrib/pydantic/test_pydantic.py +++ b/tests/contrib/pydantic/test_pydantic.py @@ -16,6 +16,10 @@ SandboxMatcher, _RestrictedProxy, ) +from tests.contrib.pydantic.activities import ( + misc_objects_activity, + pydantic_objects_activity, +) from tests.contrib.pydantic.models import ( PydanticModels, PydanticModelWithStrictField, @@ -35,8 +39,6 @@ RoundTripPydanticObjectsWorkflow, _test_pydantic_model_with_strict_field, clone_objects, - misc_objects_activity, - pydantic_objects_activity, ) diff --git a/tests/contrib/pydantic/workflows.py b/tests/contrib/pydantic/workflows.py index d67e7db42..4733dec4c 100644 --- a/tests/contrib/pydantic/workflows.py +++ b/tests/contrib/pydantic/workflows.py @@ -1,6 +1,5 @@ import dataclasses from datetime import datetime, timedelta -from typing import List from uuid import UUID from pydantic import BaseModel, create_model @@ -26,7 +25,7 @@ def clone_objects(objects: list[PydanticModels]) -> list[PydanticModels]: new_objects = [] for o in objects: fields = {} - for name, f in o.model_fields.items(): + for name, f in o.model_fields.items(): # type: ignore[reportDeprecated] fields[name] = (f.annotation, f) model = create_model(o.__class__.__name__, **fields) # type: ignore new_objects.append(model(**o.model_dump(by_alias=True))) @@ -171,5 +170,5 @@ async def run( @workflow.defn class NoTypeAnnotationsWorkflow: @workflow.run - async def run(self, arg): + async def run(self, arg): # type: ignore[reportMissingParameterType] return arg diff --git a/tests/contrib/test_opentelemetry.py b/tests/contrib/test_opentelemetry.py index 0308da2b8..d7828def6 100644 --- a/tests/contrib/test_opentelemetry.py +++ b/tests/contrib/test_opentelemetry.py @@ -11,7 +11,7 @@ from contextlib import contextmanager from dataclasses import dataclass from datetime import timedelta -from typing import Dict, List, Optional, cast +from typing import Any, cast import opentelemetry.context import pytest @@ -598,9 +598,7 @@ async def run(self) -> dict[str, str]: ) -async def test_opentelemetry_baggage_propagation_basic( - client_with_tracing: Client, env: WorkflowEnvironment -): +async def test_opentelemetry_baggage_propagation_basic(client_with_tracing: Client): task_queue = f"task_queue_{uuid.uuid4()}" async with Worker( client_with_tracing, @@ -625,13 +623,10 @@ async def test_opentelemetry_baggage_propagation_basic( @activity.defn async def read_baggage_local_activity() -> dict[str, str]: - return cast( - dict[str, str], - { - "user_id": get_baggage_value("user.id"), - "tenant_id": get_baggage_value("tenant.id"), - }, - ) + return { + "user_id": get_baggage_value("user.id"), + "tenant_id": get_baggage_value("tenant.id"), + } @workflow.defn @@ -645,7 +640,7 @@ async def run(self) -> dict[str, str]: async def test_opentelemetry_baggage_propagation_local_activity( - client_with_tracing: Client, env: WorkflowEnvironment + client_with_tracing: Client, ): task_queue = f"task_queue_{uuid.uuid4()}" async with Worker( @@ -692,7 +687,7 @@ async def run(self) -> None: async def test_opentelemetry_baggage_propagation_with_retries( - client_with_tracing: Client, env: WorkflowEnvironment + client_with_tracing: Client, ) -> None: global retry_attempt_baggage_values retry_attempt_baggage_values = [] @@ -748,7 +743,6 @@ async def run(self) -> None: ) async def test_opentelemetry_context_restored_after_activity( client_with_tracing: Client, - env: WorkflowEnvironment, activity: Callable[[], None], expect_failure: bool, ) -> None: @@ -757,12 +751,12 @@ async def test_opentelemetry_context_restored_after_activity( original_attach = context.attach original_detach = context.detach - def tracked_attach(ctx): + def tracked_attach(ctx): # type:ignore[reportMissingParameterType] nonlocal attach_count attach_count += 1 return original_attach(ctx) - def tracked_detach(token): + def tracked_detach(token): # type:ignore[reportMissingParameterType] nonlocal detach_count detach_count += 1 return original_detach(token) @@ -817,7 +811,7 @@ async def run(self) -> str: async def test_opentelemetry_interceptor_works_if_no_context( - client_with_tracing: Client, env: WorkflowEnvironment + client_with_tracing: Client, ): task_queue = f"task_queue_{uuid.uuid4()}" async with Worker( @@ -845,13 +839,13 @@ async def test_opentelemetry_interceptor_works_if_no_context( def test_opentelemetry_safe_detach(): class _fake_self: - def _load_workflow_context_carrier(*args): + def _load_workflow_context_carrier(*_args): return None - def _set_on_context(self, ctx): + def _set_on_context(self, ctx: Any): return opentelemetry.context.set_value("test-key", "test-value", ctx) - def _completed_span(*args, **kwargs): + def _completed_span(*args: Any, **_kwargs: Any): pass # create a context manager and force enter to happen on this thread diff --git a/tests/nexus/test_workflow_caller.py b/tests/nexus/test_workflow_caller.py index eceef65d8..07c22e688 100644 --- a/tests/nexus/test_workflow_caller.py +++ b/tests/nexus/test_workflow_caller.py @@ -1423,7 +1423,7 @@ async def test_workflow_run_operation_overloads( class CustomMetricsService: @nexusrpc.handler.sync_operation async def custom_metric_op( - self, ctx: nexusrpc.handler.StartOperationContext, input: None + self, _ctx: nexusrpc.handler.StartOperationContext, _input: None ) -> None: counter = nexus.metric_meter().create_counter( "my-operation-counter", "my-operation-description", "my-operation-unit" @@ -1433,7 +1433,7 @@ async def custom_metric_op( @nexusrpc.handler.sync_operation def custom_metric_op_executor( - self, ctx: nexusrpc.handler.StartOperationContext, input: None + self, _ctx: nexusrpc.handler.StartOperationContext, _input: None ) -> None: counter = nexus.metric_meter().create_counter( "my-executor-operation-counter", diff --git a/tests/test_converter.py b/tests/test_converter.py index 138ea65b5..b4be61062 100644 --- a/tests/test_converter.py +++ b/tests/test_converter.py @@ -13,17 +13,9 @@ from enum import Enum, IntEnum from typing import ( Any, - Deque, - Dict, - List, + Dict, # type:ignore[reportDeprecated] Literal, NewType, - Optional, - Set, - Text, - Tuple, - Type, - Union, ) from uuid import UUID, uuid4 @@ -56,7 +48,7 @@ # StrEnum is available in 3.11+ if sys.version_info >= (3, 11): - from enum import StrEnum + from enum import StrEnum # type:ignore[reportUnreachable] class NonSerializableClass: @@ -73,7 +65,7 @@ class SerializableEnum(IntEnum): if sys.version_info >= (3, 11): - class SerializableStrEnum(StrEnum): + class SerializableStrEnum(StrEnum): # type:ignore[reportUnreachable] FOO = "foo" @@ -99,12 +91,12 @@ class NewTypeMessage: async def test_converter_default(): async def assert_payload( - input, - expected_encoding, - expected_data, + input, # type:ignore[reportMissingParameterType] + expected_encoding, # type:ignore[reportMissingParameterType] + expected_data, # type:ignore[reportMissingParameterType] *, - expected_decoded_input=None, - type_hint=None, + expected_decoded_input=None, # type:ignore[reportMissingParameterType] + type_hint=None, # type:ignore[reportMissingParameterType] ): payloads = await DataConverter().encode([input]) # Check encoding and data @@ -258,7 +250,7 @@ def test_encode_search_attribute_values(): with pytest.raises(TypeError, match="of type tuple not one of"): encode_search_attribute_values([("bad type",)]) # type: ignore[arg-type] with pytest.raises(ValueError, match="Timezone must be present"): - encode_search_attribute_values([datetime.utcnow()]) + encode_search_attribute_values([datetime.utcnow()]) # type: ignore[reportDeprecated] with pytest.raises(TypeError, match="must have the same type"): encode_search_attribute_values(["foo", 123]) # type: ignore[arg-type] @@ -266,7 +258,7 @@ def test_encode_search_attribute_values(): def test_decode_search_attributes(): """Tests decode from protobuf for python types""" - def payload(key, dtype, data, encoding=None): + def payload(key, dtype, data, encoding=None): # type:ignore[reportMissingParameterType] if encoding is None: encoding = {"encoding": b"json/plain"} check = temporalio.api.common.v1.Payload( @@ -388,13 +380,13 @@ def fail(hint: Any, value: Any) -> None: ok(NestedDataClass, {"foo": "bar", "unknownfield": "baz"}, NestedDataClass("bar")) # Optional/Union - ok(Optional[int], 5) - ok(Optional[int], None) - ok(Optional[MyDataClass], MyDataClass("foo", 5, SerializableEnum.FOO)) - ok(Union[int, str], 5) - ok(Union[int, str], "foo") - ok(Union[MyDataClass, NestedDataClass], MyDataClass("foo", 5, SerializableEnum.FOO)) - ok(Union[MyDataClass, NestedDataClass], NestedDataClass("foo")) + ok(int | None, 5) + ok(int | None, None) + ok(MyDataClass | None, MyDataClass("foo", 5, SerializableEnum.FOO)) + ok(int | str, 5) + ok(int | str, "foo") + ok(MyDataClass | NestedDataClass, MyDataClass("foo", 5, SerializableEnum.FOO)) + ok(MyDataClass | NestedDataClass, NestedDataClass("foo")) ok(int | None, None) ok(int | None, 5) fail(int | None, "1") @@ -414,7 +406,7 @@ def fail(hint: Any, value: Any) -> None: ok(set[int], {5, 6}) ok(set, {5, 6}) ok(list, ["foo"]) - ok(Deque[int], deque([5, 6])) + ok(deque[int], deque([5, 6])) ok(Sequence[int], [5, 6]) fail(list[int], [1, 2, "3"]) @@ -445,7 +437,7 @@ def fail(hint: Any, value: Any) -> None: ok(dict[None, str], {"null": "1"}) # Dict has a different value for None keys - ok(Dict[None, str], {None: "1"}) + ok(Dict[None, str], {None: "1"}) # type:ignore[reportDeprecated] # Alias ok(MyDataClassAlias, MyDataClass("foo", 5, SerializableEnum.FOO)) @@ -461,7 +453,7 @@ def fail(hint: Any, value: Any) -> None: # StrEnum is available in 3.11+ if sys.version_info >= (3, 11): # StrEnum - ok(SerializableStrEnum, SerializableStrEnum.FOO) + ok(SerializableStrEnum, SerializableStrEnum.FOO) # type:ignore[reportUnreachable] ok( list[SerializableStrEnum], [SerializableStrEnum.FOO, SerializableStrEnum.FOO], diff --git a/tests/test_service.py b/tests/test_service.py index 61acf7ded..9fdcd9fc7 100644 --- a/tests/test_service.py +++ b/tests/test_service.py @@ -3,7 +3,7 @@ import re from collections.abc import Callable, Mapping from datetime import timedelta -from typing import Any, Dict, Tuple, Type +from typing import Any import google.protobuf.empty_pb2 import google.protobuf.message @@ -47,7 +47,7 @@ def assert_all_calls_present( ) -> None: # Collect service calls service_calls = set() - for name, call in inspect.getmembers(service): + for name, _call in inspect.getmembers(service): # ignore private methods and non-rpc members "client" and "service" if name[0] != "_" and name != "client" and name != "service": service_calls.add(name) diff --git a/tests/worker/test_activity.py b/tests/worker/test_activity.py index 7a9e27f84..e66a42dc0 100644 --- a/tests/worker/test_activity.py +++ b/tests/worker/test_activity.py @@ -15,7 +15,7 @@ from dataclasses import dataclass from datetime import datetime, timedelta, timezone from time import sleep -from typing import Any, List, NoReturn, Optional, Type +from typing import Any, NoReturn import pytest @@ -101,7 +101,7 @@ async def test_activity_custom_name( shared_state_manager: SharedStateManager, ): @activity.defn(name="my custom activity name!") - async def get_name(name: str) -> str: + async def get_name(_name: str) -> str: return f"Name: {activity.info().activity_type}" result = await _execute_workflow_with_activity( @@ -202,7 +202,7 @@ async def capture_info() -> None: ) assert info - assert info.activity_id + assert info.activity_id # type:ignore[reportUnreachable] assert info.activity_type == "capture_info" assert info.attempt == 1 assert abs( @@ -364,7 +364,7 @@ async def test_activity_kwonly_params(): with pytest.raises(TypeError) as err: @activity.defn - async def say_hello(*, name: str) -> str: + async def say_hello(*, name: str) -> str: # type:ignore[reportUnusedFunction] return f"Hello, {name}!" assert str(err.value).endswith("cannot have keyword-only arguments") @@ -1045,7 +1045,6 @@ async def say_hello(name: str) -> str: async def test_activity_worker_shutdown( client: Client, worker: ExternalWorker, - shared_state_manager: SharedStateManager, ): activity_started = asyncio.Event() @@ -1541,11 +1540,11 @@ async def test_activity_dynamic_duplicate( shared_state_manager: SharedStateManager, ): @activity.defn(dynamic=True) - async def dyn_activity_1(args: Sequence[RawValue]) -> None: + async def dyn_activity_1(_args: Sequence[RawValue]) -> None: pass @activity.defn(dynamic=True) - async def dyn_activity_2(args: Sequence[RawValue]) -> None: + async def dyn_activity_2(_args: Sequence[RawValue]) -> None: pass with pytest.raises(TypeError) as err: @@ -1823,7 +1822,7 @@ async def wait_cancel() -> str: activity.heartbeat() with pytest.raises(WorkflowFailureError) as e: - result = await _execute_workflow_with_activity( + await _execute_workflow_with_activity( client, worker, wait_cancel, diff --git a/tests/worker/workflow_sandbox/test_importer.py b/tests/worker/workflow_sandbox/test_importer.py index 290ef8648..0ed478c03 100644 --- a/tests/worker/workflow_sandbox/test_importer.py +++ b/tests/worker/workflow_sandbox/test_importer.py @@ -20,7 +20,7 @@ def test_workflow_sandbox_importer_invalid_module(): with pytest.raises(RestrictedWorkflowAccessError) as err: with Importer(restrictions, RestrictionContext()).applied(): - import tests.worker.workflow_sandbox.testmodules.invalid_module + import tests.worker.workflow_sandbox.testmodules.invalid_module # type:ignore[reportUnusedImport] assert ( err.value.qualified_name == "tests.worker.workflow_sandbox.testmodules.invalid_module" @@ -116,8 +116,8 @@ def test_workflow_sandbox_importer_invalid_module_members(): def test_workflow_sandbox_importer_sys_module(): # Import outside to make sure this is in sys.modules - import tests.worker.workflow_sandbox.testmodules.passthrough_module - import tests.worker.workflow_sandbox.testmodules.stateful_module + import tests.worker.workflow_sandbox.testmodules.passthrough_module # type:ignore[reportUnusedImport] + import tests.worker.workflow_sandbox.testmodules.stateful_module # type:ignore[reportUnusedImport] with Importer(restrictions, RestrictionContext()).applied(): # Passthrough should be there but not non-passthrough