Skip to content

Add inline types to Requests#7272

Draft
nateprewitt wants to merge 2 commits intomainfrom
inline_types_rfc
Draft

Add inline types to Requests#7272
nateprewitt wants to merge 2 commits intomainfrom
inline_types_rfc

Conversation

@nateprewitt
Copy link
Member

Add inline type annotations

Important

We want feedback from people who actively maintain projects that depend on Requests or use it heavily. Please share your experience testing this against your code in the linked issue.

Comments that are clearly AI-generated will be hidden or removed. This is a library written "for Humans". The conversation is between maintainers and users, not a prompt.

Overview

This PR adds type annotations throughout Requests to codify the type contract alongside the code. This is a path for what inline typing in Requests could look like. The goals are to establish what APIs are intended to support, make more reasoned decisions about code changes, and make using Requests in a modern development environment easier.

The package passes strict type checking with pyright, with the caveat that a few decisions on internals have been deferred for discussion by the maintainers and broader community. Right now, the intended behavior for those is undefined.

Related issue: RFC: Adding inline type annotations to Requests

How to verify locally

pip install pyright typing-extensions
python -m pyright src/requests/

Should report 0 errors. typing-extensions is needed on Python 3.10-3.12.

Main design decisions

  • cast() over assert/isinstance for type narrowing to avoid breaking downstream code at runtime
  • New _types.py module centralizing Protocols, type aliases, and TypeVars
  • SupportsRead/SupportsItems as @runtime_checkable Protocols replacing hasattr checks
  • is_prepared() as a TypeIs guard that's a no-op at runtime (always returns True)
  • ~100 type suppressions, each documented with an inline PR comment

Runtime impact

A full catalog of every runtime-impacting change is available here. The behavioral changes and bug fixes are the ones worth scrutinizing. The rest is mechanical.

Open discussion points

  • str vs bytes URL handling: Requests has historically accepted both when Python 2.7 was primary usage. These types currently declare str only. This needs a decision on whether to fix existing broken bytes behavior or formalize the str-only contract.
  • yield_requests API: Needs documentation and a decision on how this should even work in practice. This API decision came through without review and I don't think there's any realistic usage outside of the library.

What's NOT in this PR

  • mypy compatibility: Developed against pyright. If we do add mypy, that will be in a separate follow-up. Public API types should still work for mypy users.
  • Public API changes: No signature changes, no new exceptions, no runtime assertions.
  • Test type-checking: Tests are not under strict mode. There are a number of tests that intentionally violate the type contract. We'll address those once we have a final plan here.

Lost commits from 4bd79e3...0e4ae38 in the squash. This readds them.
@nateprewitt nateprewitt added this to the Soon™ milestone Mar 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant