Skip to content

Python: Fix request-info deserialization for NoneType - #9998

Merged
Eduard van Valkenburg (eavanvalkenburg) merged 7 commits into
microsoft:mainfrom
Giraffe0129:fix-workflow-event-none-type
Nov 4, 2026
Merged

Eduard van Valkenburg (eavanvalkenburg) merged 7 commits into
microsoft:mainfrom
Giraffe0129:fix-workflow-event-none-type

Conversation

@Giraffe0129

Copy link
Copy Markdown
Contributor

Motivation & Context

WorkflowEvent.from_dict(event.to_dict()) raises AttributeError when request data is None or the response type is type(None). serialize_type() produces "builtins.NoneType", but the builtins module does not expose a NoneType attribute.

This also prevents WorkflowAgent.RequestInfoFunctionArgs.from_dict() from reconstructing function arguments containing these request-info events.

Description & Review Guide

  • What are the major changes?
    • Add a fixed mapping from "builtins.NoneType" to type(None) in deserialize_type(), after caller-supplied allowed_types validation and before module-namespace lookup.
    • Document the supported name and add regression tests for type serialization, event round trips, and function-argument round trips.
    • Add from __future__ import annotations to the modified source module to follow the Python coding standards.
  • What is the impact of these changes?
    • Request-info events containing these types can be reconstructed without changing the serialized format.
    • Caller-supplied type validation retains precedence, and deserialization does not import modules selected by serialized input.
  • What do you want reviewers to focus on?
    • The placement of the fixed mapping and coverage of request and response NoneType cases.

Related Issue

Fixes #9938

AI Assistance

  • No material AI assistance was used.
  • This is an AI-assisted contribution. I reviewed, understood, and verified all submitted content and accept responsibility for it.

AI assistance details: an AI coding assistant helped draft the implementation, regression tests, and this description, and assisted with code review and local validation. Validation included the issue reproduction, the workflow test suite, Ruff checks and formatting for the four changed files, and Pyright for the changed source file. In a separate process, disabling the mapping reproduced the original failure in five regression cases while the ordinary-type control passed.

Contribution Checklist

  • The code builds clean without any errors or warnings
  • All unit tests pass, and I have added new tests where possible
  • The PR follows the Contribution Guidelines
  • This PR links to an agreed issue with no competing open PR, or the Related Issue section documents a trivial-change or repository-automation exception.
  • This is not a breaking change. If it is a breaking change, add the breaking change label (or add "[BREAKING]" to the title prefix, before or after any language prefix) — a workflow keeps the label and title prefix in sync automatically.

The workflow unit tests passed locally: 1528 passed, 1 skipped, and 2 xfailed, with 4 warnings. Ruff checks and formatting passed for all four changed files, and Pyright reported no errors or warnings for the changed source file. A full build and the complete core unit test suite have not been verified in this review, so those checklist items remain unchecked.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

No active review issues were identified in the change enabling NoneType workflow-event deserialization.

No open issues 🎉

What changed in this PR

Fixes #9938 by allowing Python workflow request-info events containing NoneType to deserialize without changing their serialized format.

Changes:

  • Resolves "builtins.NoneType" through a fixed alias after caller-supplied type validation, without importing modules.
  • Adds regression coverage for type serialization, event reconstruction, and workflow-agent argument round trips.
  • Documents the alias and enables postponed annotations in the typing utility module.
File Description
python/​packages/​core/​tests/​workflow/​test_workflow_agent.py Tests argument reconstruction with None request data and a NoneType response.
python/​packages/​core/​tests/​workflow/​test_typing_utils.py Adds NoneType serialization and deserialization coverage.
python/​packages/​core/​tests/​workflow/​test_request_info_event_rehydrate.py Tests event round trips for NoneType requests and responses, plus an ordinary-type control.
python/​packages/​core/​agent_framework/​_workflows/​_typing_utils.py Adds and documents the fixed NoneType alias while preserving caller validation precedence.

Review effort: Balanced

@Giraffe0129

Copy link
Copy Markdown
Contributor Author

@microsoft-github-policy-service agree

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

No active review issues are reported for the change supporting NoneType workflow event deserialization.

No open issues 🎉

Review effort: Balanced

Merged via the queue into microsoft:main with commit 989bc99 Nov 4, 2026
50 checks passed

This branch was previously deployed

1 inactive deployment
github-app-auth — 0e1c5695 Deployed Nov 4, 2026 by Giraffe0129 via add_label #27036
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

python Usage: [Issues, PRs], Target: Python

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Python: [Bug]: WorkflowEvent.from_dict fails for a request_info event with None data or a NoneType response

3 participants