Skip to content

fix(abstractions): default the type params of RequestAdapter and ParsableFactory - #787

Merged
Vincent Biret (baywet) merged 3 commits into
microsoft:mainfrom
HardMax71:fix/typevar-defaults-for-bare-generics
Oct 14, 2026
Merged

Vincent Biret (baywet) merged 3 commits into
microsoft:mainfrom
HardMax71:fix/typevar-defaults-for-bare-generics

Conversation

@HardMax71

@HardMax71 Max Azatian (HardMax71) commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor

Overview

Generated clients use RequestAdapter and ParsableFactory without type arguments. Every request builder takes request_adapter: RequestAdapter, and every error map is a dict[str, type[ParsableFactory]]. Under mypy --strict each of those is a "Missing type arguments" error wherever the generated code is checked, which is the usual setup when kiota generates a client into a project. They're all 141 strict errors left in the validation client, and msgraph-sdk 1.64.0 has about 26,500 such annotations.

This gives both type parameters a default (PEP 696) at the top of their range, so the bare names stay checked and strict checkers accept them without any generator change or regeneration:

  • ParsableFactory's U_co defaults to its bound, Parsable. It's covariant, so every ParsableFactory[X] still fits a bare ParsableFactory.
  • RequestAdapter's type parameter only appears as the return type of convert_to_native_async, so it becomes covariant and defaults to object, which every adapter's native request type fits.

TypeVar only takes a default in the stdlib from 3.13, so it comes from typing_extensions, which becomes a declared dependency of abstractions. It was already installed through opentelemetry-api.

tests/validation gets strict = true, so the existing validation job fails if generated code picks up a strict error again.

Related Issue

Part of #722, added there as its own item.

Notes

pylint wants the _co suffix on a covariant TypeVar, so RequestAdapter uses a new RequestType_co. The old RequestType stays importable as it was, as #722 requires.

HttpxRequestAdapter.send_collection_async took a bare ParsableFactory, which only type-checked because the bare name meant ParsableFactory[Any]. It now declares ParsableFactory[ModelType], like the method it overrides.

HttpxRequestAdapter now subclasses RequestAdapter[httpx.Request], the type its convert_to_native_async returns. With the object default, a bare subclass would no longer fit an annotation that asks for RequestAdapter[httpx.Request].

As a downstream check, msgraph-sdk-python-core's CI step mypy src (mypy 1.17.1) still passes against this branch, and its strict run goes from 70 to 60 errors.

The floor is typing-extensions 4.4.0, the release that added default. The abstractions tests pass on Python 3.10 with exactly that version.

Since abstractions and http use the bare names themselves, mypy --strict also goes from 63 to 51 errors in abstractions and from 127 to 117 in http (mypy 2.4.0). It merges cleanly with #785.

Testing Instructions

  • From tests/validation, mypy validation (now strict) passes, also with --python-version 3.10 and 3.14. On main the strict run reports 141 errors.
  • The normal mypy run passes for all eight packages.
  • yapf -dr, isort, pylint --disable=W and pytest pass for abstractions and http.
  • tests/test_typing.py in packages/http/httpx runs mypy on a snippet that returns an HttpxRequestAdapter as RequestAdapter[httpx.Request]. Without the base-class change it fails with Incompatible return value type.

@HardMax71

Copy link
Copy Markdown
Contributor Author

hmm, default=any = no limits at all. I'll convert this PR to draft and reopen later

@HardMax71
Max Azatian (HardMax71) marked this pull request as draft October 10, 2026 15:27
…ableFactory

Generated clients annotate request_adapter: RequestAdapter and dict[str, type[ParsableFactory]] without type arguments, which mypy --strict reports wherever the generated code is checked. That's all 141 strict errors in tests/validation, and msgraph-sdk 1.64.0 has about 26,500 such annotations.

Give both type parameters a PEP 696 default at the top of their range. ParsableFactory's U_co defaults to its bound, Parsable, and since it's covariant every ParsableFactory[X] still fits the bare name. RequestAdapter's type parameter is only returned by convert_to_native_async, so it becomes covariant and defaults to object; pylint wants the _co suffix, so it's renamed to RequestType_co. HttpxRequestAdapter.send_collection_async now declares ParsableFactory[ModelType] like the method it overrides, since the bare name no longer means Any.

TypeVar only takes a default in the stdlib from 3.13, so it comes from typing_extensions, now a declared dependency of abstractions (it was already installed through opentelemetry-api). tests/validation runs with strict = true so CI catches a regression. Part of microsoft#722.
@HardMax71
Max Azatian (HardMax71) force-pushed the fix/typevar-defaults-for-bare-generics branch from 8a575ec to ea9b41c Compare October 10, 2026 15:31
@HardMax71 Max Azatian (HardMax71) changed the title fix(abstractions): default RequestAdapter and ParsableFactory type params to Any fix(abstractions): default the type params of RequestAdapter and ParsableFactory Oct 10, 2026
@HardMax71

Max Azatian (HardMax71) commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor Author

Rename from RequestType to RequestType_co is needed solely cause of pylint: it doesn't allow covariants without "_co" suffix. mypy doesn't care.

Ready for review btw

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

The public TypeVar rename and unspecialized HTTP adapter introduce typing compatibility regressions.

2 open findings
What changed in this PR

Adds safe defaults to core generic types so generated clients pass strict mypy checks.

Changes:

  • Defaults RequestAdapter and ParsableFactory type parameters.
  • Enables strict mypy validation.
  • Tightens the HTTP collection factory annotation.
File Description
tests/​validation/​pyproject.toml Enables strict mypy checking.
packages/​http/​httpx/​kiota_http/​httpx_request_adapter.py Specializes the collection factory annotation.
packages/​abstractions/​pyproject.toml Adds the TypeVar backport dependency.
packages/​abstractions/​kiota_abstractions/​serialization/​parsable_factory.py Defaults the parsable factory type.
packages/​abstractions/​kiota_abstractions/​request_adapter.py Makes the request type covariant and defaulted.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread packages/abstractions/kiota_abstractions/request_adapter.py
Comment thread packages/abstractions/kiota_abstractions/request_adapter.py
@baywet

Copy link
Copy Markdown
Member

Max Azatian (@HardMax71) would you mind addressing copilot's feedback please?

Copilot AI balanced review requested due to automatic review settings October 14, 2026 16:31

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@HardMax71

Copy link
Copy Markdown
Contributor Author

Vincent Biret (@baywet) addressed

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟢 Approval recommended

The focused typing changes address prior compatibility feedback, include regression coverage, and have no unresolved findings.

0 open findings

2 resolved since last review

🧠 Review effort: Balanced

@baywet Vincent Biret (baywet) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thank you for making the changes!

Copilot AI balanced review requested due to automatic review settings October 14, 2026 17:23

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@sonarqubecloud

Copy link
Copy Markdown

@baywet
Vincent Biret (baywet) merged commit 47b8104 into microsoft:main Oct 14, 2026
54 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done ✔️

Development

Successfully merging this pull request may close these issues.

3 participants