psf/requests
Input arrives as loosely-typed Python kwargs at `api.request()` or `Session.request()`, is funnelled into a `Request` value object, then normalised into a fully-serialised `PreparedRequest` (bytes body, `CaseInsensitiveDict` headers, percent-encoded URL string) by `Session.prepare_request()`. Session-level and environment-level settings are merged in at two distinct points — `merge_setting`/`merge_hooks` during preparation, and `merge_environment_settings` for proxies/verify/cert/stream just before send. The `PreparedRequest` crosses the adapter boundary into urllib3, and the urllib3 response crosses back through `HTTPAdapter.build_response()`, which is the sole constructor of `Response` objects. State ownership is clean: `Session` owns cookies, adapters and defaults; `PreparedRequest` owns the wire representation; `Response` owns `_content`/`_content_consumed` and lazily pulls bytes off `raw`. Output boundaries are the `Response` accessors and the environment mutations in `should_bypass_proxies` (via `set_environ`) and `extract_zipped_paths` (via `tempfile.mkstemp`).
- Settings precedence is implemented by `merge_setting(request_setting, session_setting)`: non-Mapping request values win outright, Mappings are merged with request keys overriding, and any key explicitly set to `None` is deleted from the merged result — that is how callers suppress a session default header.
- Hooks need special merging because `{'response': []}` would otherwise wipe session hooks; `merge_hooks` short-circuits when either side has an empty response list.
- Cookies flow through a three-way merge in `prepare_request`: `merge_cookies(merge_cookies(RequestsCookieJar(), self.cookies), request.cookies)`, so per-request cookies layer over session cookies into a fresh jar rather than mutating the session's.
- `PreparedRequest.prepare()` runs a fixed six-step pipeline — method, url, headers, cookies, body, auth — then hooks; the ordering comment states auth must be last so schemes like OAuth can sign a fully-formed request and still register hooks.
- `prepare_auth` mutates the prepared request by `self.__dict__.update(r.__dict__)` from whatever the auth callable returns, then recomputes Content-Length — so an auth handler can legitimately rewrite body and headers.
- Credentials embedded in the URL are extracted into auth during preparation: `prepare_auth` calls `get_auth_from_url(self.url)` when no explicit auth was supplied, and `prepare_url` reassembles netloc with the `auth@` prefix preserved.
- Environment enters the flow at `merge_environment_settings`, which (only when `trust_env`) seeds proxies from `getproxies()` and overrides `verify` from `REQUESTS_CA_BUNDLE` or `CURL_CA_BUNDLE` — explicitly to be cURL-compatible.
- Proxy selection is layered: `resolve_proxies` consults `should_bypass_proxies` (NO_PROXY, CIDR matching, platform `proxy_bypass`), then `select_proxy` picks by the key precedence `scheme://host` → `scheme` → `all://host` → `all`.
- Body length determination flows through `super_len()`, which probes `__len__`, `.len`, `fileno()`+`os.fstat`, and `seek/tell`, subtracting the current file position so partially-read files report the remaining bytes.
- Header values are validated at the input boundary by `check_header_validity`, which regex-matches against `HEADER_VALIDATORS` to reject CR/LF and leading-whitespace — the CRLF-injection guard.
- The response side is constructed exclusively in `HTTPAdapter.build_response()`, which lifts status, `CaseInsensitiveDict` headers, encoding from `get_encoding_from_headers`, `raw`, reason, url, extracts server cookies into `response.cookies`, and back-links `request` and `connection`.
- Cookies persist onto the Session after the fact: `Session.send` calls `extract_cookies_to_jar(self.cookies, request, r.raw)` for the final response and separately for every entry in `r.history`.
- Response bytes are pulled lazily: `content` joins `iter_content(CONTENT_CHUNK_SIZE)` (10 KiB) once and caches into `_content`, flipping `_content_consumed`; `Session.send` forces this by touching `r.content` whenever `stream` is falsy.
- urllib3 exceptions are translated into the requests hierarchy at exactly one place — the `try/except` ladder in `HTTPAdapter.send` mapping `MaxRetryError` reasons to `ConnectTimeout`/`RetryError`/`ProxyError`/`SSLError` and `ProtocolError`/`OSError` to `ConnectionError`.
- `should_bypass_proxies` temporarily mutates process environment via the `set_environ('no_proxy', ...)` context manager before calling the stdlib `proxy_bypass`, restoring the prior value in a `finally` block.