Skip to content

Code Analysis HTTPX Lazy Imports

Tu Shaokun edited this page Nov 6, 2026 · 1 revision

HTTPX: deferred imports are still dependencies

HTTPX change #3377 moved certifi and httpcore imports from module scope into functions and constructors. This study asks what that changes for callers: which dependency edges remain, which construction paths load the packages, and what a static lazy-import flag cannot tell us.

The historical source comparison is eeb5e3c2 → e9cabc8e. This development tree exposes an HTTPX.SSLContext class; the observations are not current-release API advice. The source answer, selected file hashes and import expectations were frozen before the analyzer ran.

Follow the construction path

The dependency declarations still require both packages. Moving an import changes its source context, not the installation requirement.

SSLContext.__init__:74–109 imports certifi before its early return for verify=False. HTTPTransport.__init__:136–220 imports httpcore before choosing its SSL context. Providing an existing standard-library SSL context bypasses HTTPX's context constructor on the inspected path, but still imports httpcore. That local bypass does not establish the import state of transitive dependencies.

Client._init_transport:694–716 returns a supplied transport before creating the default HTTP transport. With explicit no-proxy/no-mount controls, trust_env=False and http2=False, the selected MockTransport case bypasses that default construction route. Other supplied transports can independently load packages.

The exception mapping helper has another timing boundary: map_httpcore_exceptions loads the map before its try/yield if the cache is empty. Its httpcore import is therefore not restricted to an exception being raised. Calling the generator context manager and entering it are separate steps.

The upstream httpcore and certifi tests were read as behavioral intent. They were not run here and do not establish every intermediate constructor phase or a startup performance benefit.

What the captured facts establish

Both source roots were checked with the same explicit httpx/**/*.py scope using Python producer 272f995b. These are package-source captures, not the entire repository or installed dependencies.

Side Python files Import records Functions Parse errors Unresolved external references
Before 23 218 447 0 128
After 23 223 448 0 132

The three selected earlier certifi/httpcore imports are at module scope. Afterward, the certifi import and five transport/helper httpcore imports are marked lazy, while _main.py's guarded httpcore import is type-only. All ten selected records agree with frozen source expectations and remain unresolved external dependencies; the scan did not include the installed packages. No unresolved references were classified as unknown, outside or opaque in these two package scopes. These counts are descriptive, not an accuracy rate for all records.

Each check returned exit 0 under --fail-on never, with eight findings: one warning and seven informational. Those findings were not individually adjudicated in this study.

Saved questions using consumer 29f73e9c locate SSLContext.__init__, HTTPTransport.__init__ and Client._init_transport on both sides. All six source/archive question pairs match after excluding only the workflow document path. Python calls remain unavailable with a null total. These are reading locations and import facts, not a generated constructor call graph or a semantic answer.

Separate import-state observations

Six separate Python 3.13.16 processes imported the exact source roots in an isolated venv. No HTTPX distribution was installed. Loaded HTTPX module paths and selected source hashes were checked against the pinned checkout. The seven dependency wheels were pinned and verified against official PyPI hashes: certifi 2025.10.5, httpcore 1.0.9, h11 0.16.0, anyio 4.11.0, idna 3.11, sniffio 1.3.1 and typing_extensions 4.15.0. These versions form the tested environment; they do not reconstruct an original historical deployment. Optional CLI, HTTP2, trio and SOCKS extras were absent.

The six expectations incorporated both HTTPX and dependency source, and were frozen before the first target execution. Every process began with httpx, certifi and httpcore absent from sys.modules.

Selected operation certifi afterward httpcore afterward Finite observation
Before-change import httpx Present Present Module imports load both
After-change import httpx Absent Absent Neither is loaded yet
After-change SSLContext(verify=False) Present Absent HTTPX context constructor runs once
After-change HTTPTransport with a supplied standard-library SSL context Present Present HTTPX context constructor is bypassed; the pool retains the supplied object
After-change Client with controlled MockTransport Absent Absent Supplied transport retained; zero mounts and handler calls
After-change entry into an empty exception-map context, without raising Present Present Map loader runs once, before the body completes

All six matched. The supplied-context result is explained by httpcore 1.0.9's module-level certifi import. Its inspected source matched the verified installed wheel. Avoid equating a local constructor bypass with a process-wide dependency exclusion.

Function-entry profiling started after the initial HTTPX import and observed only two exact function code objects during the selected operations. It validates the supplied-context bypass and exception-map entry in this experiment; it is not a full call graph or a measurement of constructor calls during initial import. No HTTP request, target networking, full upstream suite, async/proxy matrix or startup benchmark ran. A small audit hook rejected network operations; none were observed. These finite observations do not establish all caller configurations or performance gains.

Reproduce from fixed public revisions

The standalone script below passed on its first execution from a directory containing only the script. It fetches the fixed source and analyzer revisions, verifies the archive, recreates both exact captures, checks the selected import flags and six source/archive question pairs, then runs the separate six-process oracle with verified binary wheels. It embeds all validators and runtime expectations; it has no local evidence-file dependency.

Requirements: Git, Node 22.23.2, CPython 3.13.16 with venv/pip, unzip, shasum and network access to GitHub, npm and PyPI. Set PYTHON if its executable is not named python3.13. Installs are confined to temporary analyzer checkouts and the temporary venv. Neither HTTPX source root is installed or modified, and no live Archify installation changes.

Raw-facts SHA256 before: f8fa054b4a40a94e633dfb70f48453feb17566169103486ed939a25fdf945792; after: 6fe324c765343adbafcadde79a6cd8c69fddcc0ed740c7e0fc5d54a0e208a865. Replay script SHA256: 98eb97ce63d3c1cd82e836691710fa1c085a56cfa53e6aa29eb2db62f3c24bf7.

Executed standalone source, archive and import-state replay
#!/bin/sh
set -eu
# Static capture and finite runtime study on a historical HTTPX change.
test "$(node --version)" = v22.23.2 || { echo 'Node 22.23.2 required' >&2; exit 1; }
PYTHON=${PYTHON:-python3.13}
test "$("$PYTHON" -c 'import platform;print(platform.python_version())')" = 3.13.16 || { echo 'Python 3.13.16 required' >&2; exit 1; }
export BAUIFY_PYTHON="$PYTHON"
WORK=$(mktemp -d "${TMPDIR:-/tmp}/archify-httpx-replay.XXXXXX")
printf 'Workspace: %s\n' "$WORK"
pin() { git init -q "$WORK/$1"; git -C "$WORK/$1" remote add origin "https://github.com/$2.git"; git -C "$WORK/$1" fetch -q --no-tags --depth=1 origin "$3"; git -C "$WORK/$1" checkout -q --detach FETCH_HEAD; test "$(git -C "$WORK/$1" rev-parse HEAD)" = "$3"; }
pin producer tt-a1i/archify 272f995b9a0a38789c1d7d8c76e73ce62636fe5b
pin consumer tt-a1i/archify 29f73e9c30ee72b3f085a2b13caedcaa50d1d4da
pin base encode/httpx eeb5e3c2a3ff2403ec47b5926715ecd61143d92d
pin head encode/httpx e9cabc8e1deb6548c5c5e2f453e343d39a2a5321
for source in producer consumer; do (cd "$WORK/$source/archify/modules/code-analysis" && npm ci --ignore-scripts --no-audit --no-fund); done
printf '%s  %s\n' 3f0a03a6d523fdf100779a5addc8d57c8e00dda36d854502e3e00d0915e4b22f "$WORK/consumer/archify.zip" | shasum -a 256 -c -
mkdir "$WORK/archive"; unzip -q "$WORK/consumer/archify.zip" -d "$WORK/archive"
(cd "$WORK/archive/archify/modules/code-analysis" && npm ci --ignore-scripts --no-audit --no-fund)
cd "$WORK"
printf '{"include":["httpx/**/*.py"]}\n' > scope.json
for side in base head; do
 node "$WORK/producer/archify/bin/archify.mjs" code-analysis check "$WORK/$side" --language py --config "$WORK/scope.json" --fail-on never --json --out "$WORK/capture-$side" > "check-$side-receipt.json" 2> "check-$side-stderr.txt"
 for source in consumer archive; do
  for entry in ssl transport client; do
   case "$entry" in
    ssl) FILE=httpx/_config.py; FUNCTION='SSLContext.__init__';;
    transport) FILE=httpx/_transports/default.py; FUNCTION='HTTPTransport.__init__';;
    client) FILE=httpx/_client.py; FUNCTION='Client._init_transport';;
   esac
   node "$WORK/$source/archify/bin/archify.mjs" code-analysis task "$WORK/capture-$side" --question 'How are certifi and httpcore dependencies deferred, and what paths still load them?' --entry "$FILE" --function "$FUNCTION" --root "$WORK/$side" --format json --out "$WORK/question-$side-$entry-$source.json" --json > "question-$side-$entry-$source-receipt.json" 2> "question-$side-$entry-$source-stderr.txt"
  done
 done
done
node --input-type=module <<'HTTPX_STATIC_CHECK'
import fs from 'node:fs';import assert from 'node:assert/strict';import {createHash} from 'node:crypto';
const read=p=>JSON.parse(fs.readFileSync(p,'utf8'));
const expected={base:{hash:'f8fa054b4a40a94e633dfb70f48453feb17566169103486ed939a25fdf945792',imports:218,functions:447,external:128,sites:[['httpx/_config.py','certifi',9,false,false],['httpx/_main.py','httpcore',9,false,false],['httpx/_transports/default.py','httpcore',34,false,false]],locations:{ssl:['httpx/_config.py','SSLContext.__init__',76,109],transport:['httpx/_transports/default.py','HTTPTransport.__init__',126,208],client:['httpx/_client.py','Client._init_transport',694,716]}},head:{hash:'6fe324c765343adbafcadde79a6cd8c69fddcc0ed740c7e0fc5d54a0e208a865',imports:223,functions:448,external:132,sites:[['httpx/_config.py','certifi',78,true,false],['httpx/_main.py','httpcore',24,false,true],...[75,151,240,300,389].map(n=>['httpx/_transports/default.py','httpcore',n,true,false])],locations:{ssl:['httpx/_config.py','SSLContext.__init__',74,109],transport:['httpx/_transports/default.py','HTTPTransport.__init__',136,220],client:['httpx/_client.py','Client._init_transport',694,716]}}};
let summary=[];for(const side of ['base','head']){const e=expected[side],raw=fs.readFileSync(`capture-${side}/raw-facts.json`),f=JSON.parse(raw),receipt=read(`check-${side}-receipt.json`);assert.equal(createHash('sha256').update(raw).digest('hex'),e.hash);assert.equal(f.files.length,23);assert.equal(f.imports.length,e.imports);assert.equal(f.functions.length,e.functions);assert.equal((f.parse_errors||[]).length,0);assert.deepEqual(f.unresolved,{external:e.external,outside:0,unknown:0,opaque:0});assert.equal(receipt.gate.failOn,'never');assert.equal(receipt.status,'ok');assert.equal(f.repository.adapterRevision,5);
 const imports=f.imports.filter(i=>['certifi','httpcore'].includes(i.specifier));assert.equal(imports.length,e.sites.length);for(const [file,specifier,line,lazy,typeOnly] of e.sites){let i=imports.find(x=>x.from===file&&x.specifier===specifier&&x.line===line);assert.ok(i,`${side} ${file}:${line}`);assert.equal(i.resolved,false);assert.equal(Boolean(i.lazy),lazy);assert.equal(Boolean(i.typeOnly),typeOnly);}
 for(const [name,[file,symbol,startLine,endLine]] of Object.entries(e.locations)){const a=read(`question-${side}-${name}-consumer.json`),b=read(`question-${side}-${name}-archive.json`);assert.deepEqual(a.entry.location,{file,symbol,startLine,endLine});assert.equal(a.entry.currentStatus,'ok');assert.equal(a.entry.factsStatus,'valid');assert.equal(a.calls.coverage,'unavailable');assert.equal(a.calls.total,null);delete a.workflow;delete b.workflow;assert.deepEqual(a,b);for(const mode of ['consumer','archive'])assert.equal(read(`question-${side}-${name}-${mode}-receipt.json`).status,'ok');}
 summary.push({side,rawFactsSha256:e.hash,files:23,imports:e.imports,functions:e.functions,parseErrors:0,unresolved:f.unresolved,selectedImports:imports,questionLocations:e.locations,findings:receipt.counts});}
fs.writeFileSync('static-verification.json',JSON.stringify(summary,null,2)+'\n');console.log('Static checks passed: both frozen raw hashes, 3/7 selected imports and six source/archive question pairs. Calls unavailable/null.');
HTTPX_STATIC_CHECK

# Separate finite runtime oracle; no HTTP request is made.
mkdir "$WORK/runtime" "$WORK/wheels"
cat > "$WORK/runtime/expected-runtime.json" <<'HTTPX_EMBED_EXPECTED_RUNTIME_JSON'
{
  "frozenBeforeFirstHTTPXExecution": true,
  "frozenAtUtc": "2026-11-06T13:34:49.055672+00:00",
  "dependencyPins": {
    "certifi": "2025.10.5",
    "httpcore": "1.0.9",
    "h11": "0.16.0",
    "anyio": "4.11.0",
    "idna": "3.11",
    "sniffio": "1.3.1",
    "typing_extensions": "4.15.0"
  },
  "sources": {
    "base": {
      "commit": "eeb5e3c2a3ff2403ec47b5926715ecd61143d92d",
      "sha256": {
        "httpx/__init__.py": "8230c40ce95b64f6dca746bb6387f76a3aa72dac51ab3c6c2ab259d0961ff9f6",
        "httpx/_client.py": "763ae09f3366e533e1b7a60ff162cb309c3c7a71aa57cd48ff5f58da7a272e1a",
        "httpx/_config.py": "35062499fd8c36ea00c642737d3ea44fb6ee2423338cdcbc7a44b2859bebd629",
        "httpx/_main.py": "ed17f68beb9cbac83fae710ce806d00a4967e3d90fe7a7d71cc8d37c7cbf621e",
        "httpx/_transports/default.py": "aa729f3a31244eb23f7ac9b3da3360c7915fa9f9d9c75143727abaa8c729781f",
        "tests/test_api.py": "25ca0bc1e95d701921db058dc465a914ca2d0c12cbcaa80f278013b16c24f440",
        "tests/test_config.py": "56595e32e85a7be1cbec1896dd834334ca4dc1536a874051b326832dd2267e57"
      }
    },
    "head": {
      "commit": "e9cabc8e1deb6548c5c5e2f453e343d39a2a5321",
      "sha256": {
        "httpx/__init__.py": "8230c40ce95b64f6dca746bb6387f76a3aa72dac51ab3c6c2ab259d0961ff9f6",
        "httpx/_client.py": "763ae09f3366e533e1b7a60ff162cb309c3c7a71aa57cd48ff5f58da7a272e1a",
        "httpx/_config.py": "ec55ce10c6ed02984f1bb6158badd6591bfc39e9fff5c1520c3f6e573bd6b795",
        "httpx/_main.py": "ec853bbbe0fcfd6786a47bdfc3f94cc09df2d1457a4e8f59aa04bf93f7a4ede9",
        "httpx/_transports/default.py": "6c9692828e7570cbb3b38b8d8ed24988210e9ca46396fa8bf1f73f9f3661826b",
        "httpx/_transports/mock.py": "3d3a34779ebb4484d7c46ae48ba90deffebbc300317f088c0dcb972626428c4a",
        "pyproject.toml": "df6ead82c82909bacc1f54fa0de8edc52dab17742d548d41c284506e3c05706f",
        "tests/test_api.py": "785f0650f616312f22a1573fbe383647c68b2282deaa18ad64da650331e1e90f",
        "tests/test_config.py": "f147eb86c47fcf9b1064cc7668f1971cf3d5f5a135cfc6317744b372627479d0"
      }
    }
  },
  "cases": [
    {
      "id": "base-import",
      "side": "base",
      "afterImport": {
        "httpx": true,
        "certifi": true,
        "httpcore": true
      },
      "final": {
        "httpx": true,
        "certifi": true,
        "httpcore": true
      },
      "calls": {
        "httpxSSLContextInit": 0,
        "exceptionMapLoader": 0
      }
    },
    {
      "id": "head-import",
      "side": "head",
      "afterImport": {
        "httpx": true,
        "certifi": false,
        "httpcore": false
      },
      "final": {
        "httpx": true,
        "certifi": false,
        "httpcore": false
      },
      "calls": {
        "httpxSSLContextInit": 0,
        "exceptionMapLoader": 0
      }
    },
    {
      "id": "head-ssl-verify-false",
      "side": "head",
      "afterImport": {
        "httpx": true,
        "certifi": false,
        "httpcore": false
      },
      "final": {
        "httpx": true,
        "certifi": true,
        "httpcore": false
      },
      "calls": {
        "httpxSSLContextInit": 1,
        "exceptionMapLoader": 0
      }
    },
    {
      "id": "head-provided-stdlib-context",
      "side": "head",
      "afterImport": {
        "httpx": true,
        "certifi": false,
        "httpcore": false
      },
      "final": {
        "httpx": true,
        "certifi": true,
        "httpcore": true
      },
      "calls": {
        "httpxSSLContextInit": 0,
        "exceptionMapLoader": 0
      }
    },
    {
      "id": "head-client-mock",
      "side": "head",
      "afterImport": {
        "httpx": true,
        "certifi": false,
        "httpcore": false
      },
      "final": {
        "httpx": true,
        "certifi": false,
        "httpcore": false
      },
      "calls": {
        "httpxSSLContextInit": 0,
        "exceptionMapLoader": 0
      }
    },
    {
      "id": "head-exception-map-no-error",
      "side": "head",
      "afterImport": {
        "httpx": true,
        "certifi": false,
        "httpcore": false
      },
      "final": {
        "httpx": true,
        "certifi": true,
        "httpcore": true
      },
      "calls": {
        "httpxSSLContextInit": 0,
        "exceptionMapLoader": 1
      }
    }
  ],
  "dependencySourceBasis": "Verified official httpcore1.0.9 wheel: __init__.py imports ._ssl.default_ssl_context; _ssl.py:3 imports certifi at module scope. Thus the supplied stdlib SSLContext path bypasses HTTPX.SSLContext.__init__ but process certifi state still becomes present. The exception map likewise imports httpcore before yielding, without an exception.",
  "boundaries": [
    "No HTTP requests, network target operations, startup benchmark or security advice.",
    "Exact historical HTTPX source commits with chosen pinned dependency versions; no original-production-environment claim.",
    "Existing context bypass is a local constructor-path fact, not a process-wide no-certifi guarantee.",
    "Only two exact Python function code objects are profiled; no inferred call graph.",
    "No async/http2/proxy/mount/environment-transports matrix is executed."
  ]
}
HTTPX_EMBED_EXPECTED_RUNTIME_JSON
cat > "$WORK/runtime/probe.py" <<'HTTPX_EMBED_PROBE_PY'
"""One fresh-process, source-root HTTPX import-state observation; never sends a request."""
import argparse
import hashlib
import importlib.metadata
import json
from pathlib import Path
import sys

parser=argparse.ArgumentParser();parser.add_argument('root',type=Path);parser.add_argument('case');args=parser.parse_args()
root=args.root.resolve();expected=json.loads((Path(__file__).resolve().parent/'expected-runtime.json').read_text())
case=next(c for c in expected['cases'] if c['id']==args.case)
assert sys.version_info[:3]==(3,13,16),sys.version
try:
 importlib.metadata.distribution('httpx')
except importlib.metadata.PackageNotFoundError:
 pass
else:
 raise AssertionError('HTTPX must come from pinned source, not an installed distribution')
for file,digest in expected['sources'][case['side']]['sha256'].items():
 assert hashlib.sha256((root/file).read_bytes()).hexdigest()==digest,file

def state():
 return {name:name in sys.modules for name in ['httpx','certifi','httpcore']}

before=state();assert before=={'httpx':False,'certifi':False,'httpcore':False}
network_attempts=[]
def audit(event,values):
 if event in ['socket.connect','socket.getaddrinfo','socket.sendto']:
  network_attempts.append(event);raise RuntimeError('network operation not permitted in import-state probe')
sys.addaudithook(audit)
sys.path.insert(0,str(root))
import httpx
assert Path(httpx.__file__).resolve()==root/'httpx/__init__.py'
for name,module in list(sys.modules.items()):
 if name=='httpx' or name.startswith('httpx.'):
  origin=getattr(module,'__file__',None)
  if origin:assert Path(origin).resolve().is_relative_to(root/'httpx'),(name,origin)
after_import=state();assert after_import==case['afterImport'],(args.case,after_import)
from httpx._transports import default
codes={httpx.SSLContext.__init__.__code__:'httpxSSLContextInit'}
if hasattr(default,'_load_httpcore_exceptions'):codes[default._load_httpcore_exceptions.__code__]='exceptionMapLoader'
counts={'httpxSSLContextInit':0,'exceptionMapLoader':0}
def profile(frame,event,arg):
 if event=='call' and frame.f_code in codes:counts[codes[frame.f_code]]+=1
extra={};sys.setprofile(profile)
try:
 if args.case in ['base-import','head-import']:
  pass
 elif args.case=='head-ssl-verify-false':
  context=httpx.SSLContext(verify=False)
 elif args.case=='head-provided-stdlib-context':
  import ssl
  context=ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
  transport=httpx.HTTPTransport(ssl_context=context,http2=False,proxy=None)
  extra['poolUsesProvidedContext']=transport._pool._ssl_context is context
  assert extra['poolUsesProvidedContext'];transport.close()
 elif args.case=='head-client-mock':
  handler_calls=[]
  def handler(request):
   handler_calls.append('called');raise AssertionError('no request is authorized')
  transport=httpx.MockTransport(handler)
  client=httpx.Client(transport=transport,trust_env=False,http2=False,proxy=None,mounts=None)
  extra={'clientUsesProvidedTransport':client._transport is transport,'mounts':len(client._mounts),'handlerCalls':len(handler_calls)}
  assert extra=={'clientUsesProvidedTransport':True,'mounts':0,'handlerCalls':0};client.close()
 elif args.case=='head-exception-map-no-error':
  extra['mapEmptyBefore']=not default.HTTPCORE_EXC_MAP
  assert extra['mapEmptyBefore']
  with default.map_httpcore_exceptions():extra['bodyCompletedWithoutException']=True
  extra['mapPopulatedAfter']=bool(default.HTTPCORE_EXC_MAP)
  assert extra['mapPopulatedAfter']
 else:
  raise AssertionError(args.case)
finally:
 sys.setprofile(None)
final=state();assert final==case['final'],(args.case,final)
assert counts==case['calls'],(args.case,counts)
assert not network_attempts
origins={name:getattr(sys.modules.get(name),'__file__',None) for name in ['httpx','certifi','httpcore','httpcore._ssl']}
versions={name:importlib.metadata.version(name) for name in expected['dependencyPins']}
assert versions==expected['dependencyPins']
print(json.dumps({'case':args.case,'side':case['side'],'sourceCommit':expected['sources'][case['side']]['commit'],'python':sys.version,'httpxVersionLabel':httpx.__version__,'sourceRoot':str(root),'httpxSourceSha256':hashlib.sha256((root/'httpx/__init__.py').read_bytes()).hexdigest(),'beforeTarget':before,'afterImport':after_import,'afterOperation':final,'profiledFunctionEntries':counts,'details':extra,'origins':origins,'dependencyVersions':versions,'networkAttempts':network_attempts,'meaning':'Finite source-root import-state observation, not a request/runtime-completeness/performance/security claim'},indent=2))
HTTPX_EMBED_PROBE_PY
cat > "$WORK/runtime/requirements.txt" <<'HTTPX_EMBED_REQUIREMENTS_TXT'
certifi==2025.10.5 --hash=sha256:0f212c2744a9bb6de0c56639a6f68afe01ecd92d91f14ae897c4fe7bbeeef0de
httpcore==1.0.9 --hash=sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55
h11==0.16.0 --hash=sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86
anyio==4.11.0 --hash=sha256:0287e96f4d26d4149305414d4e3bc32f0dcd0862365a4bddea19d7a1ec38c4fc
idna==3.11 --hash=sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea
sniffio==1.3.1 --hash=sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2
typing_extensions==4.15.0 --hash=sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548
HTTPX_EMBED_REQUIREMENTS_TXT
printf '%s  %s\n' 8edaccf3342bd297fd46b8c455661d1a85b601d74cf959704cf59a99674aeb8c "$WORK/runtime/expected-runtime.json" | shasum -a 256 -c -
printf '%s  %s\n' 87ee7349efed3a58e6ed6e574c9b809397bad168b83bb1cedee96073193c852a "$WORK/runtime/probe.py" | shasum -a 256 -c -
printf '%s  %s\n' 05c6cdfcde651dfcc9176b5aeafaebcb7cfc5066752f8eea1dd1db8c1038f2c3 "$WORK/runtime/requirements.txt" | shasum -a 256 -c -
"$PYTHON" -m venv "$WORK/venv"
"$WORK/venv/bin/python" -m pip download --only-binary=:all: --no-deps --require-hashes --dest "$WORK/wheels" -r "$WORK/runtime/requirements.txt"
"$WORK/venv/bin/python" - <<'HTTPX_WHEEL_CHECK'
import hashlib,json,pathlib,urllib.request
versions={'certifi':'2025.10.5','httpcore':'1.0.9','h11':'0.16.0','anyio':'4.11.0','idna':'3.11','sniffio':'1.3.1','typing_extensions':'4.15.0'}
paths=list(pathlib.Path('wheels').glob('*.whl'));assert len(paths)==len(versions);results=[]
for name,version in versions.items():
 with urllib.request.urlopen(f'https://pypi.org/pypi/{name}/{version}/json',timeout=60) as r: metadata=json.load(r)
 match=[p for p in paths if p.name in {x['filename'] for x in metadata['urls']}];assert len(match)==1,(name,match)
 p=match[0];actual=hashlib.sha256(p.read_bytes()).hexdigest();official=next(x['digests']['sha256'] for x in metadata['urls'] if x['filename']==p.name);assert actual==official,(name,p.name)
 results.append({'name':name,'version':version,'filename':p.name,'sha256':actual,'officialPyPI':True})
pathlib.Path('runtime/wheel-verification.json').write_text(json.dumps(results,indent=2)+'\n');print('Seven pinned binary wheel hashes agree with official PyPI metadata.')
HTTPX_WHEEL_CHECK
"$WORK/venv/bin/python" -m pip install --no-index --find-links "$WORK/wheels" --no-deps --require-hashes -r "$WORK/runtime/requirements.txt"
export PYTHONDONTWRITEBYTECODE=1
for case in base-import head-import head-ssl-verify-false head-provided-stdlib-context head-client-mock head-exception-map-no-error; do
 case "$case" in base-import) root="$WORK/base";; *) root="$WORK/head";; esac
 "$WORK/venv/bin/python" "$WORK/runtime/probe.py" "$root" "$case" > "$WORK/runtime/$case.json" 2> "$WORK/runtime/$case-stderr.txt"
done
"$WORK/venv/bin/python" - <<'HTTPX_RUNTIME_CHECK'
import json,pathlib
cases=['base-import','head-import','head-ssl-verify-false','head-provided-stdlib-context','head-client-mock','head-exception-map-no-error']
results=[json.loads(pathlib.Path(f'runtime/{x}.json').read_text()) for x in cases]
assert [x['case'] for x in results]==cases
assert all(not x['networkAttempts'] for x in results)
assert results[3]['profiledFunctionEntries']['httpxSSLContextInit']==0 and results[3]['afterOperation']['certifi']
pathlib.Path('runtime/observations.json').write_text(json.dumps(results,indent=2)+'\n')
print('Six finite fresh-process import-state checks passed; supplied context bypasses HTTPX constructor but httpcore loads certifi transitively.')
HTTPX_RUNTIME_CHECK

AI-assisted investigation and writing. No product defect or code change is assumed from this study. See saved Python/Java questions, pandas source questions and the validation index.

Clone this wiki locally