Skip to content

Defer pygments and pdb imports (9% speedup) - #14874

Open
giampaolo wants to merge 2 commits into
pytest-dev:mainfrom
giampaolo:speedup
Open

Defer pygments and pdb imports (9% speedup)#14874
giampaolo wants to merge 2 commits into
pytest-dev:mainfrom
giampaolo:speedup

Conversation

@giampaolo

Copy link
Copy Markdown

Hello,
pytest currently imports pygments and pdb on every run, even though they are only needed in specific cases:

  • pygments is only used when there is a failure, for the summary shown at the end, and only when terminal colors are enabled.
  • pdb is only used with the --pdb CLI option, and only if a test fails.

Note: pdb became noticeably more expensive to import in Python 3.14, as it now pulls in socket, asyncio, and selectors modules, which together bring in roughly 40 additional modules.

Using this patched pytest version against the psutil test suite (839 tests) with --plugins-disabled and --collect-only, I see about a 9% speedup:

~/svn/pytest {speedup}$ python3 bench_real.py
upstream/main   378.8ms
working tree    343.8ms
-> +35.0ms (+9.2%)

bench_real.py

Comment thread src/_pytest/debugging.py


def pytest_configure(config: Config) -> None:
import pdb

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.

Can't we just import pdb in a conditional branch ? The new class feel unnecessary.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately no. With a pure import the following tests fail:

FAILED test_pdb_set_trace_interception
FAILED TestDebuggingBreakpoints::test_sys_breakpoint_interception
FAILED test_pdbcls_via_local_module
FAILED test_pdb_wrapper_class_is_reused
FAILED test_quit_with_swallowed_SystemExit

test_pdb_set_trace_interception runs pytest with no options at all and expects import pdb; pdb.set_trace() inside a test to be intercepted. Checking "pdb" in sys.modules at configure time doesn't work either, because test modules are imported during collection, which happens after pytest_configure.

So the only thing left to hook is the import itself, and a sys.meta_path entry has to be an object exposing find_spec.

@bluetech bluetech added the skip news used on prs to opt out of the changelog requirement label Aug 13, 2026
@bluetech

Copy link
Copy Markdown
Member

The pygments change LGTM, but maybe @nicoddemus should ACK.

The pdb seems to add some complexity. It seems to me like it would perhaps be better to improve this in cpython itself, maybe the imports can be changed to lazy there? I see cpython has an issue Improve import time of various stdlib modules so at least they seem open to it.

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

I also think the pygments changes are OK, but I agree with @bluetech that the pdb changes are a bit too complex to our liking. After all, we will need to maintain that code moving forward, and who knows what bugs might happen because of it?

I'm -0 on accepting this, while 9% speed up is not negligible, the necessary code to achieve that is not ideal (and this is not saying the code per-se is bad, seems like it is the only solution possible here).

from .wcwidth import wcswidth


if TYPE_CHECKING:

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.

We could leave a note at the global level mentioning that the local imports for pygments are optional, and related to a speed up.

@giampaolo

giampaolo commented Aug 13, 2026

Copy link
Copy Markdown
Author

@nicoddemus sure, I see where you're coming from. I would probably reject the pdb complexity as well. Happy to remove it and just ship the pygments change if you think it's worth it. That alone should be around a 5% speedup.

@nicoddemus

Copy link
Copy Markdown
Member

Thanks.

Lets give it a day for others to weigh in but if nobody manifests otherwise, go ahead with just keeping the pygments changes.

Btw, how much speedup do the pygments changes (in isolation) provide?

Keep this PR to pygments only. The pdb part needs a sys.meta_path
finder, which deserves its own discussion.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@giampaolo

Copy link
Copy Markdown
Author

Done. The speedup is very modest, so not sure if it's worth it.

~/svn/pytest {speedup}$ python3 bench_real.py 
upstream/main   371.7ms
working tree    364.8ms
-> +6.9ms (+1.9%)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

skip news used on prs to opt out of the changelog requirement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants