Skip to content

Do a lazy import of the _main CLI module#947

Merged
Kludex merged 10 commits into
pydantic:mainfrom
mbeijen:cli-perf
May 17, 2026
Merged

Do a lazy import of the _main CLI module#947
Kludex merged 10 commits into
pydantic:mainfrom
mbeijen:cli-perf

Conversation

@mbeijen

@mbeijen mbeijen commented May 16, 2026

Copy link
Copy Markdown
Contributor

Importing the CLI code doubles the import time for httpx altogether. By importing lazily at runtime, the additional time only happens when running the httpx CLI, and not on every "import httpx".

This speeds up imports by around 25%

Importing the CLI code doubles the import time for httpx altogether. By
importing lazily at runtime, the additional time only happens when
running the httpx CLI, and not on every "import httpx".
Kludex added 9 commits May 16, 2026 15:40
The console script now points at a tiny `_cli.py` shim that lazily imports
`_main` and preserves the friendly "install httpx[cli]" fallback. The
`httpx2.main` attribute remains importable via `__getattr__` but emits a
`DeprecationWarning` so existing callers have a migration path.
Drops the `_cli.py` shim and points the console script at
`httpx2._main:main`. The friendly "install httpx[cli]" fallback is
removed - users without the CLI extras will see a clear `ImportError`,
which is enough signal that they need `pip install httpx2[cli]`.
`_main` is a CLI-only internal module; users shouldn't be steered toward
calling it directly. Point them at the `httpx2` CLI entry point only.
Covers the two branches of `__getattr__` in `httpx2/__init__.py` that
the existing CLI tests don't exercise (they import `main` from
`httpx2._main` directly).
Bare `httpx2.does_not_exist` tripped ruff B018 (useless expression)
and the previous `# type: ignore[attr-defined]` tripped mypy
`unused-ignore` because `__getattr__` widens the module's attribute
type. Assigning to `_` keeps both linters happy.
Drops the two coverage-only tests and the `pytest` import they
required. The deprecation contract is documented by the warning text
itself, and the function is small enough that `# pragma: no cover`
is preferable to keeping dedicated tests for it.
@Kludex

Kludex commented May 17, 2026

Copy link
Copy Markdown
Member

I don't think the _main:main should be exposed programatically. That's only useful for the CLI.

@Kludex Kludex merged commit 3a960c8 into pydantic:main May 17, 2026
8 checks passed
@Kludex Kludex mentioned this pull request May 17, 2026
2 tasks
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.

3 participants