Python: resolve postponed @response_handler annotations - #8328
Python: resolve postponed @response_handler annotations#8328CoralGarden52 wants to merge 3 commits into
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
Add fallback-path coverage and verify workflow_output_types registration for two-argument contexts.
Get a fresh assessment by requesting another Copilot review.
Pull request overview
Fixes postponed-annotation handling for Python @response_handler methods.
Changes:
- Resolve annotations with
typing.get_type_hints, with raw-annotation fallback. - Add regression coverage for future annotations.
File summaries
| File | Summary |
|---|---|
python/packages/core/tests/workflow/test_executor_future.py |
Tests response-handler registration with postponed annotations. |
python/packages/core/agent_framework/_workflows/_request_info_mixin.py |
Resolves response-handler parameter annotations. |
Review details
- Files reviewed: 2/2 changed files
- Comments generated: 2
- Review effort level: Lite (auto)
Note
Copilot is running an experiment and ran this review at Lite.
💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.
| try: | ||
| type_hints = typing.get_type_hints(func) | ||
| except (NameError, AttributeError, RecursionError): | ||
| type_hints = {p.name: p.annotation for p in params} |
There was a problem hiding this comment.
Implemented in commit cf3e412. Added regression coverage for the unresolved-annotation fallback path and verified that it produces the existing ValueError diagnostic. The postponed-annotation test now uses WorkflowContext[str, bool] and asserts both output_types and workflow_output_types. The targeted executor tests and full workflow test suite pass.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Ricky-7-Yan
left a comment
There was a problem hiding this comment.
Reviewed current head cf3e412. Resolving annotations with typing.get_type_hints() and using the same (NameError, AttributeError, RecursionError) raw-annotation fallback as the existing @handler and function-executor validation paths keeps the decorator behaviors aligned. The regression exercises the public class-decoration/discovery path, verifies request/response plus both WorkflowContext type arguments, and the added unresolved-reference case covers the fallback diagnostic. I found no blocking issue in the scoped diff.
The full upstream Python workflows have not run on this external branch; this approval relies on the current code/tests and the author's reported full core suite, Ruff, and Pyright results rather than treating the governance checks as full CI.
Motivation & Context
The introspection path of
@response_handlerreads raw values frominspect.signature(func). Withfrom __future__ import annotations, valid request, response, andWorkflowContext[...]annotations are strings, so a valid executor class currently fails during decoration withValueErrorand cannot be imported or instantiated. The existing@handlerpath already resolves these annotations; issue #8327 tracks the missing response-handler counterpart.The bug was reproduced on clean upstream commit
3c670707766a8455da6491a9049cc9d575e019f0with a four-parameter response handler usingoriginal_request: str,response: int, andctx: WorkflowContext[str].Description & Review Guide
typing.get_type_hints(func)during signature validation, matching the existing@handlerbehavior.@response_handlermethods normally.ValueError: Response handler parameter 'ctx' must be annotated ... got WorkflowContext[str]; after the fix it registers(str, int)with workflow output typestr.5044 passed, 131 skipped, 2 xfailed; relevant request-info, executor, and future-annotation tests passed; Ruff format/lint passed; Pyright reported0 errors, 0 warningsfor both changed files._validate_handler_signature.Related Issue
Fixes #8327
Contribution Checklist
breaking changelabel (or add "[BREAKING]" to the title prefix, before or after any language prefix) — a workflow keeps the label and title prefix in sync automatically.