Skip to content

Commit f0b664f

Browse files
committed
Copy get_types utility from nexusrpc
1 parent bc6230c commit f0b664f

File tree

1 file changed

+49
-5
lines changed

1 file changed

+49
-5
lines changed

temporalio/nexus/_util.py

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,10 @@
1010
Callable,
1111
Optional,
1212
Type,
13+
Union,
1314
)
1415

15-
from nexusrpc.handler import (
16-
StartOperationContext,
17-
get_start_method_input_and_output_type_annotations,
18-
)
16+
from nexusrpc.handler import StartOperationContext
1917
from nexusrpc.types import (
2018
InputT,
2119
OutputT,
@@ -41,7 +39,8 @@ def get_workflow_run_start_method_input_and_output_type_annotations(
4139
`start` must be a type-annotated start method that returns a
4240
:py:class:`temporalio.nexus.WorkflowHandle`.
4341
"""
44-
input_type, output_type = get_start_method_input_and_output_type_annotations(start)
42+
43+
input_type, output_type = _get_start_method_input_and_output_type_annotations(start)
4544
origin_type = typing.get_origin(output_type)
4645
if not origin_type:
4746
output_type = None
@@ -66,6 +65,51 @@ def get_workflow_run_start_method_input_and_output_type_annotations(
6665
return input_type, output_type
6766

6867

68+
def _get_start_method_input_and_output_type_annotations(
69+
start: Callable[
70+
[ServiceHandlerT, WorkflowRunOperationContext, InputT],
71+
Union[OutputT, Awaitable[OutputT]],
72+
],
73+
) -> tuple[
74+
Optional[Type[InputT]],
75+
Optional[Type[OutputT]],
76+
]:
77+
"""Return operation input and output types.
78+
79+
`start` must be a type-annotated start method that returns a synchronous result.
80+
"""
81+
try:
82+
type_annotations = typing.get_type_hints(start)
83+
except TypeError:
84+
# TODO(preview): stacklevel
85+
warnings.warn(
86+
f"Expected decorated start method {start} to have type annotations"
87+
)
88+
return None, None
89+
output_type = type_annotations.pop("return", None)
90+
91+
if len(type_annotations) != 2:
92+
# TODO(preview): stacklevel
93+
suffix = f": {type_annotations}" if type_annotations else ""
94+
warnings.warn(
95+
f"Expected decorated start method {start} to have exactly 2 "
96+
f"type-annotated parameters (ctx and input), but it has {len(type_annotations)}"
97+
f"{suffix}."
98+
)
99+
input_type = None
100+
else:
101+
ctx_type, input_type = type_annotations.values()
102+
if not issubclass(ctx_type, WorkflowRunOperationContext):
103+
# TODO(preview): stacklevel
104+
warnings.warn(
105+
f"Expected first parameter of {start} to be an instance of "
106+
f"WorkflowRunOperationContext, but is {ctx_type}."
107+
)
108+
input_type = None
109+
110+
return input_type, output_type
111+
112+
69113
def get_callable_name(fn: Callable[..., Any]) -> str:
70114
method_name = getattr(fn, "__name__", None)
71115
if not method_name and callable(fn) and hasattr(fn, "__call__"):

0 commit comments

Comments
 (0)