Skip to content

gh-156777: Optimize import overhead in the logging package - #156778

Open
brittanyrey wants to merge 4 commits into
python:mainfrom
brittanyrey:b-perf-logging-lazy-imports
Open

gh-156777: Optimize import overhead in the logging package#156778
brittanyrey wants to merge 4 commits into
python:mainfrom
brittanyrey:b-perf-logging-lazy-imports

Conversation

@brittanyrey

@brittanyrey brittanyrey commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

summary

  • Lift the function-level imports in logging/handlers.py and logging/config.py to module scope as lazy imports, and mark other cold-path imports lazy.
  • Imports reachable from interpreter finalization stay eager and are now commented as such.
  • The Windows-only (_winapi, winreg) and optional third-party (win32evtlogutil) imports stay function-level on purpose: as module-level lazy imports they would break inspect.getmembers() and pydoc on non-Windows.

perf

Import before after delta
import logging.config 29.42 ms 21.09 ms −28.3%
import logging.handlers 25.60 ms 21.05 ms −17.8%
import logging 20.15 ms 20.08 ms −0.4% (noise)

Lift the function-level imports in logging/handlers.py and logging/config.py
to module scope as lazy imports, and mark other cold-path imports lazy.

Imports reachable from interpreter finalization stay eager and are now
commented as such: at teardown sys.modules has been cleared, so resolving a
lazy import raises ImportError('sys.meta_path is None').

The Windows-only (_winapi, winreg) and optional third-party
(win32evtlogutil) imports stay function-level on purpose: as module-level
lazy imports they would break inspect.getmembers() and pydoc on non-Windows.

import logging.config    -28.3%
import logging.handlers  -17.8%
import logging           unchanged
Call-time benchmarks unchanged (all within noise).
Comment thread Lib/logging/__init__.py Outdated
Comment thread Lib/logging/handlers.py Outdated
Comment thread Misc/NEWS.d/next/Library/2026-08-31-08-20-00.gh-issue-156777.La7yLg.rst Outdated
Co-authored-by: Pieter Eendebak <pieter.eendebak@gmail.com>
Comment thread Lib/logging/config.py Outdated
Comment thread Lib/logging/config.py Outdated
Comment thread Lib/logging/handlers.py
Comment thread Lib/logging/__init__.py Outdated
Sort each import block into the isort/Ruff groups requested in review:
plain imports, from-imports, lazy imports, lazy from-imports.

In logging/config.py, replace ``lazy import logging.handlers`` with
``lazy from logging import handlers``. The former binds the name
``logging`` lazily, so it shadows the eager ``import logging`` above it
and any use of ``logging.<anything>`` in the module pulls in
logging.handlers. Aliased to ``logging_handlers`` because ``handlers``
is already a local variable in _install_handlers() and
_configure_queue_handler().

Now logging.handlers is imported only when a handler is configured
through the ``class`` key; previously dictConfig(), fileConfig() and
stopListening() all reified it.

Co-authored-by: Pieter Eendebak <pieter.eendebak@gmail.com>
Co-authored-by: Hugo van Kemenade <hugovk@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants