Skip to content

fix: give each request configuration and headers inspection handler its own HeadersCollection - #726

Merged
Vincent Biret (baywet) merged 4 commits into
microsoft:mainfrom
HardMax71:fix/own-headers-collection-per-instance
Sep 10, 2026
Merged

Vincent Biret (baywet) merged 4 commits into
microsoft:mainfrom
HardMax71:fix/own-headers-collection-per-instance

Conversation

@HardMax71

Copy link
Copy Markdown
Contributor

Overview

RequestConfiguration.headers defaulted to one HeadersCollection() evaluated at class definition, so every configuration built without headers= shared it and a header added for one request rode along on every other request in the process. field(default_factory=HeadersCollection) gives each instance its own, as proposed in the issue.

The same shape sat two levels deeper on the http package. HeadersInspectionHandlerOption.__init__ used HeadersCollection() as the default for both request_headers and response_headers; the if request_headers else HeadersCollection() guard never replaced them because HeadersCollection has no __len__, so an empty collection is truthy. And HeadersInspectionHandler.__init__ used HeadersInspectionHandlerOption() as its default, so every handler built without options shared one option object and, through it, the same two collections: the headers one client inspected showed up on, and were cleared by, another. Both defaults are None now and the constructor creates a fresh object.

Related Issue

Fixes #507

Notes

The other middleware constructors (RedirectHandler, RetryHandler, UserAgentHandler, UrlReplaceHandler, ParametersNameDecodingHandler) take their option object as a function default too, so all handlers of one class share one option. Those options carry configuration values rather than per-request state, so the effect is limited to mutating handler.options after construction. Left out of this PR to keep it on #507; happy to send the same Optional[...] = None change for them separately.

Testing Instructions

  • cd packages/abstractions && pytest tests/test_base_request_configuration.py: two configurations get distinct collections, a header added to one is not visible on the other, a fresh configuration starts empty. Fails on main.
  • cd packages/http/httpx && pytest tests/middleware_tests/test_headers_inspection_handler.py: two options do not share request or response collections, two handlers do not share an option object. Both fail on main.
  • Full suites: abstractions 135 passed, http 110 passed. yapf, mypy and pylint clean on the touched source files.

…ts own HeadersCollection

RequestConfiguration.headers, HeadersInspectionHandlerOption's two
collections and HeadersInspectionHandler's option object were all
defaults evaluated once, so every instance built without an explicit
value shared them and headers leaked between unrelated requests.
@HardMax71
Max Azatian (HardMax71) requested a review from a team as a code owner September 10, 2026 16:03
Copilot AI lite review requested due to automatic review settings September 10, 2026 16:03

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.

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 reviewed changes address shared mutable defaults and include regression coverage with no blocking issues.

Review details
  • Files reviewed: 5/5 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

@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.

Thanks for the contribution!

@github-project-automation github-project-automation Bot moved this to In Progress 🚧 in Kiota Sep 10, 2026
…tory collections

Same fix as the RequestConfiguration half, spelled the same way.

@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 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 new/updated test test_import_base_request_configuration_no_warning does not reliably assert “no warnings on import” as written, and the HeadersInspectionHandlerOption docstring name is inconsistent with the actual class name.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details
  • Files reviewed: 5/5 changed files
  • Comments generated: 2
  • Review effort level: Lite

Comment thread packages/abstractions/tests/test_base_request_configuration.py Outdated
The test reloaded nothing and len(pytest.warns()) recorded nothing, so
it passed whatever the module did on import. Also name the handler
correctly in the option docstring.
auto-merge was automatically disabled September 10, 2026 18:04

Head branch was pushed to by a user without write access

@sonarqubecloud

Copy link
Copy Markdown

@HardMax71

Copy link
Copy Markdown
Contributor Author

Vincent Biret (@baywet) small changes cause of Copilot, can you pls re-review/approve?

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 changes eliminate confirmed shared-mutable-state bugs and add targeted regression tests covering the corrected behaviors.

Review details
  • Files reviewed: 5/5 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

@baywet
Vincent Biret (baywet) merged commit e1d47d6 into microsoft:main Sep 10, 2026
102 checks passed
@github-project-automation github-project-automation Bot moved this from In Progress 🚧 to Done ✔️ in Kiota Sep 10, 2026
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.

RequestConfiguration instances share the same HeadersCollection instance by default

3 participants