Execute a function and return its result as a primitive value.
(
self,
parent_name: str,
parent_state: Mapping[str, Any],
name: str,
raw_inputs: Mapping[str, Any],
)
| 378 | return None |
| 379 | |
| 380 | async def get_structured_result( |
| 381 | self, |
| 382 | parent_name: str, |
| 383 | parent_state: Mapping[str, Any], |
| 384 | name: str, |
| 385 | raw_inputs: Mapping[str, Any], |
| 386 | ) -> tuple[Any, Field | Function]: |
| 387 | """Execute a function and return its result as a primitive value.""" |
| 388 | obj_type = self.get_object(parent_name) |
| 389 | |
| 390 | if name == "": |
| 391 | fn = obj_type.get_constructor(self._converter) |
| 392 | else: |
| 393 | parent = await self._get_parent_instance(obj_type, parent_state) |
| 394 | |
| 395 | # NB: fields are not executed by the SDK, they're returned directly by |
| 396 | # the engine, but this is still useful for testing. |
| 397 | if name in obj_type.fields: |
| 398 | f = obj_type.fields[name] |
| 399 | result = getattr(parent, f.original_name) |
| 400 | return result, f |
| 401 | |
| 402 | fn = obj_type.get_bound_function(parent, name) |
| 403 | |
| 404 | inputs = await self._convert_inputs(fn, raw_inputs) |
| 405 | bound = fn.bind_arguments(**inputs) |
| 406 | |
| 407 | if logger.isEnabledFor(logging.DEBUG): |
| 408 | logger.debug("func => %s", repr(fn.signature)) |
| 409 | logger.debug("input args => %s", repr(raw_inputs)) |
| 410 | logger.debug("bound args => %s", repr(bound.arguments)) |
| 411 | |
| 412 | result = await self.call(fn.wrapped, *bound.args, **bound.kwargs) |
| 413 | |
| 414 | # Provide better errors for missing async/await |
| 415 | if inspect.iscoroutine(result): |
| 416 | result.close() # avoid RuntimeWarning |
| 417 | |
| 418 | if not inspect.iscoroutinefunction(fn.wrapped): |
| 419 | msg = ( |
| 420 | f"Function '{fn}' returned a coroutine.\n" |
| 421 | "Did you forget to add 'async' to the function signature?" |
| 422 | ) |
| 423 | else: |
| 424 | msg = ( |
| 425 | f"Async function '{fn}' was never awaited.\n" |
| 426 | "Did you forget to add an 'await' to the return value?" |
| 427 | ) |
| 428 | raise FunctionError(msg) from None |
| 429 | |
| 430 | return result, fn |
| 431 | |
| 432 | async def call(self, func: Func[P, R], *args: P.args, **kwargs: P.kwargs) -> R: |
| 433 | """Call a function and return its result.""" |