|
8 | 8 | from nexusrpc._common import InputT, OperationInfo, OutputT, ServiceHandlerT
|
9 | 9 | from nexusrpc._service import Operation, OperationDefinition, ServiceDefinition
|
10 | 10 | from nexusrpc._util import (
|
| 11 | + get_operation, |
11 | 12 | get_operation_factory,
|
12 | 13 | is_async_callable,
|
13 | 14 | is_callable,
|
@@ -153,31 +154,28 @@ def collect_operation_handler_factories_by_method_name(
|
153 | 154 | )
|
154 | 155 | seen = set()
|
155 | 156 | for _, method in inspect.getmembers(user_service_cls, is_callable):
|
156 |
| - factory, op = get_operation_factory(method) # type: ignore[var-annotated] |
157 |
| - if factory and isinstance(op, Operation): |
158 |
| - # This is a method decorated with one of the *operation_handler decorators |
159 |
| - if op.name in seen: |
160 |
| - raise RuntimeError( |
161 |
| - f"Operation '{op.name}' in service '{user_service_cls.__name__}' " |
162 |
| - f"is defined multiple times." |
| 157 | + if factory := get_operation_factory(method): |
| 158 | + if op := get_operation(factory): |
| 159 | + if op.name in seen: |
| 160 | + raise RuntimeError( |
| 161 | + f"Operation '{op.name}' in service '{user_service_cls.__name__}' " |
| 162 | + f"is defined multiple times." |
| 163 | + ) |
| 164 | + if service and op.method_name not in service_method_names: |
| 165 | + _names = ", ".join(f"'{s}'" for s in sorted(service_method_names)) |
| 166 | + msg = ( |
| 167 | + f"Operation method name '{op.method_name}' in service handler {user_service_cls} " |
| 168 | + f"does not match an operation method name in the service definition. " |
| 169 | + f"Available method names in the service definition: " |
| 170 | + ) |
| 171 | + msg += _names if _names else "[none]" |
| 172 | + raise TypeError(msg) |
| 173 | + |
| 174 | + assert op.method_name, ( |
| 175 | + f"Operation '{op}' method name should not be empty. Please report this as a bug." |
163 | 176 | )
|
164 |
| - if service and op.method_name not in service_method_names: |
165 |
| - _names = ", ".join(f"'{s}'" for s in sorted(service_method_names)) |
166 |
| - msg = ( |
167 |
| - f"Operation method name '{op.method_name}' in service handler {user_service_cls} " |
168 |
| - f"does not match an operation method name in the service definition. " |
169 |
| - f"Available method names in the service definition: " |
170 |
| - ) |
171 |
| - msg += _names if _names else "[none]" |
172 |
| - msg += "." |
173 |
| - raise TypeError(msg) |
174 |
| - |
175 |
| - # TODO(preview) op_defn.method name should be non-nullable |
176 |
| - assert op.method_name, ( |
177 |
| - f"Operation '{op}' method name should not be None. This is an SDK bug." |
178 |
| - ) |
179 |
| - factories[op.method_name] = factory |
180 |
| - seen.add(op.name) |
| 177 | + factories[op.method_name] = factory |
| 178 | + seen.add(op.name) |
181 | 179 | return factories
|
182 | 180 |
|
183 | 181 |
|
@@ -212,7 +210,7 @@ def validate_operation_handler_methods(
|
212 | 210 | f"method name '{op_defn.method_name}'. But this operation is in service "
|
213 | 211 | f"definition '{service_definition}'."
|
214 | 212 | )
|
215 |
| - _, op = get_operation_factory(factory) |
| 213 | + op = get_operation(factory) |
216 | 214 | if not isinstance(op, Operation):
|
217 | 215 | raise ValueError(
|
218 | 216 | f"Method '{factory}' in class '{service_cls.__name__}' "
|
@@ -278,7 +276,7 @@ def service_definition_from_operation_handler_methods(
|
278 | 276 | """
|
279 | 277 | op_defns: dict[str, OperationDefinition[Any, Any]] = {}
|
280 | 278 | for name, method in user_methods.items():
|
281 |
| - _, op = get_operation_factory(method) |
| 279 | + op = get_operation(method) |
282 | 280 | if not isinstance(op, Operation):
|
283 | 281 | raise ValueError(
|
284 | 282 | f"In service '{service_name}', could not locate operation definition for "
|
|
0 commit comments