GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — gh-150072: Optimize logging imports by lazily importing `traceback` by IvyXu420 · Pull Request #150073 · python/cpython

Conversation

@IvyXu420

@IvyXu420 IvyXu420 commented May 19, 2026 •
edited by bedevere-app Bot
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor
  • Issue: Lazily import traceback in logging #150072

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@IvyXu420
Optimize logging imports by using lazy loading for traceback
66e631b
@IvyXu420
IvyXu420 requested a review from vsajip as a code owner May 19, 2026 10:39
@bedevere-app bedevere-app Bot mentioned this pull request May 19, 2026
Lazily import traceback in logging #150072
Open
@bedevere-app bedevere-app Bot added the awaiting review label May 19, 2026
@hugovk

hugovk commented May 19, 2026

Copy link
Copy Markdown
Member

Unfortunately the lazy import fails when trying to test logging during shutdown:

======================================================================
FAIL: test_logging_at_shutdown (test.test_logging.ModuleLevelMiscTest.test_logging_at_shutdown)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/runner/work/cpython/cpython/Lib/test/test_logging.py", line 5259, in test_logging_at_shutdown
    self.assertIn("exception in __del__", err)
    ~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: 'exception in __del__' not found in '--- Logging error ---\nException ignored while calling deallocator <function A.__del__ at 0x20002d3e8d0>:\nTraceback (most recent call last):\n  File "<string>", line 9, in __del__\n  File "/Users/runner/work/cpython/cpython/Lib/logging/__init__.py", line 2194, in exception\n  File "/Users/runner/work/cpython/cpython/Lib/logging/__init__.py", line 2186, in error\n  File "/Users/runner/work/cpython/cpython/Lib/logging/__init__.py", line 1553, in error\n  File "/Users/runner/work/cpython/cpython/Lib/logging/__init__.py", line 1669, in _log\n  File "/Users/runner/work/cpython/cpython/Lib/logging/__init__.py", line 1685, in handle\n  File "/Users/runner/work/cpython/cpython/Lib/logging/__init__.py", line 1741, in callHandlers\n  File "/Users/runner/work/cpython/cpython/Lib/logging/__init__.py", line 1031, in handle\n  File "/Users/runner/work/cpython/cpython/Lib/logging/__init__.py", line 1163, in emit\n  File "/Users/runner/work/cpython/cpython/Lib/logging/__init__.py", line 1080, in handleError\nImportError: sys.meta_path is None, Python is likely shutting down\n'
All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@IvyXu420

IvyXu420 commented May 19, 2026

Copy link
Copy Markdown
Contributor Author

We can fix the test by adding atexit.register(lambda: traceback) in __init__.py, which guarantees traceback will be imported before the interpreter cleans up. But sadly, the wall-clock time will still be unoptimized in that case.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@picnixz

picnixz commented May 19, 2026

Copy link
Copy Markdown
Member

I would prefer that we do not overcomplicate atexit callbacks in this case.

StanFromIreland reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@vsajip

vsajip commented May 19, 2026

Copy link
Copy Markdown
Member

I see your performance improvement figure in the issue - why is a few ms at application start time an issue? How much time do you practically save in a realistic application?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@hugovk

hugovk commented May 19, 2026

Copy link
Copy Markdown
Member

It helps for CLIs, and especially for --help which should usually be a no-op.

Some report 50ms delays can be noticeable, and 10-20ms sometimes be distinguished from 5ms or lower, when it comes to interactivity.

https://danluu.com/term-latency/
https://xyrillian.de/thoughts/posts/latency-matters.html

More conservatively, 100ms is often cited as a response time limit

https://www.nngroup.com/articles/response-times-3-important-limits/

CLI tools are sometimes (re-)written in languages like Rust or Go rather than Python or Node because of these lower millisecond times.

Slicing off 13ms here doesn't necessarily improve things on its own, but it's a fair chunk of 100ms, and it all adds up.

And especially as logging is so widely used, so if we can save here, then it benefits many.

Another use case is serverless computing, which can be billed by the millisecond.


@ByteFlowing1337 What OS did you use for the charts in #150072? Are they from debug or optimised builds of Python.

IvyXu420 and danielhollas reacted with thumbs up emoji
All reactions
  • 👍 2 reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@IvyXu420

IvyXu420 commented May 20, 2026

Copy link
Copy Markdown
Contributor Author

It helps for CLIs, and especially for --help which should usually be a no-op.

Exactly! That's why I wanna optimize it.

The figure showed in the issue was tested on the debug builds of python on Linux (WSL2).

On Linux (WSL2), with an optimized Python build, we obtained the following results:

Before (12ms) After (6ms)

As a result, this optimization shaves off roughly only 6ms.


Before #149318 was merged, importing logging is much slower than the current main branch, as _colorize is eagerly imported in traceback. Tested on official Windows release of python 3.14.4:

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@hugovk

hugovk commented May 20, 2026

Copy link
Copy Markdown
Member

As a result, this optimization shaves off roughly only 6ms.

I think 6ms saving would be good if was just a matter of adding lazy but the shutdown issue complicates it (and I had already tried it and prioritised other things for this reason :)

Before #149318 was merged, importing logging is much slower than the current main branch, as _colorize is eagerly imported in traceback. Tested on official Windows release of python 3.14.4:

Yeah, the traceback improvement was partly motivated by indirectly improving logging.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@danielhollas

danielhollas commented May 20, 2026

Copy link
Copy Markdown
Contributor

See also my previous (unsuccessful) attempt at this and the discussion in #112995

hugovk reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@vsajip

vsajip commented May 20, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

Instead of lazily importing it, what happens if you remove the import at the top of the module and just import it normally in the suites where it's referenced? Is it the same error on shutdown?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@danielhollas

danielhollas commented May 20, 2026

Copy link
Copy Markdown
Contributor

Instead of lazily importing it, what happens if you remove the import at the top of the module and just import it normally in the suites where it's referenced? Is it the same error on shutdown?

That what I did in #112995 and it doesn't work. Ultimately, inlining the imports into the functions is basically equivalent of having a lazy import at the top. I don't see a way around this TBH. I am actually in general surprised/worried that we don't see more issues at interpreter shutdown given that we now make more and more imports lazy in stdlib.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@hugovk hugovk mentioned this pull request Jun 30, 2026
Use lazy imports on Python 3.15 to improve startup speed python-pillow/Pillow#9733
Merged
@brittanyrey

brittanyrey commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

Would lazy importing re within the logging module be a safer alternative?
It's not as big of a win but it's the next best thing.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@hugovk

hugovk commented Jul 12, 2026

Copy link
Copy Markdown
Member

logging eagerly imports traceback which eagerly imports re, so it ends up reified anyway.

Lazily importing traceback in logging fails test_logging_at_shutdown.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@github-actions

github-actions Bot commented Oct 11, 2026

Copy link
Copy Markdown

This PR is stale because it has been open for 90 days with no activity.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@github-actions github-actions Bot added the stale Stale PR or inactive for long period of time. label Oct 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@vsajip vsajip Awaiting requested review from vsajip vsajip is a code owner

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

awaiting review stale Stale PR or inactive for long period of time.

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

6 participants

@IvyXu420 @hugovk @picnixz @vsajip @danielhollas @brittanyrey
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.