Skip to content

gh-134170: Add colorization to unraisable exceptions #134183

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 20 commits into
base: main
Choose a base branch
from

Conversation

ZeroIntensity
Copy link
Member

@ZeroIntensity ZeroIntensity commented May 18, 2025

It's pretty now:

image

I don't think it's worth it/possible to add a test for this.


📚 Documentation preview 📚: https://cpython-previews--134183.org.readthedocs.build/

@@ -1485,6 +1485,21 @@ write_unraisable_exc_file(PyThreadState *tstate, PyObject *exc_type,
}
}

// Try printing the exception with color
PyObject *print_exception_fn = PyImport_ImportModuleAttrString("traceback",
Copy link
Member

Choose a reason for hiding this comment

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

This would print the exception with color on stderr but write_unraisable_exc_file accepts arbitrary file objects. So:

  • Let's use a separate function to print the exception with color
  • Only import if file is not None.

Copy link
Member Author

Choose a reason for hiding this comment

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

I just modified _print_exception_bltin to take a file, I don't think we need a new function. Is that alright?

Copy link
Member

Choose a reason for hiding this comment

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

Actually, the comment for this function is:

Do nothing if sys.stderr attribute doesn't exist or is set to None

So I don't really know which one is the correct implementation. There are cases when sys.__stderr__ may be None (as said in the docs). OTOH, the Python function doesn't check for the existence of sys.stderr itself. So I think the comment is a bit misleading. Can you check which contract is the expected one? Thanks.+

Copy link
Member Author

Choose a reason for hiding this comment

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

Hm, what am I checking for? If sys.stderr doesn't work, we'll raise an exception and fall back to the C implementation.

Copy link
Member

Choose a reason for hiding this comment

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

But if sys.stderr does not exist, the function says "Do nothing if sys.stderr attribute doesn't exist or is set to None" which in this case isn't right as we're not doing "nothing" (we're still calling something). I'm not against your implementation, I'm just trying to understand the comment actually

Copy link
Member Author

Choose a reason for hiding this comment

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

Hmm, yeah, I think that comment is wrong. Should I change it?

Copy link
Member

Choose a reason for hiding this comment

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

Yes (wrong comments are misleading!)

Copy link
Member Author

Choose a reason for hiding this comment

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

Did that and added an assertion. The caller always validates sys.stdout.

Copy link
Member

@picnixz picnixz left a comment

Choose a reason for hiding this comment

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

Let's this by raising an unraisable exception inside the hook itself and check that we don't crash. I don't know if we can recursively call sys.unraisablehook because of that, but if we can, we should check that we don't segfault for whatever reason.

@ZeroIntensity
Copy link
Member Author

Sorry, forgot about this PR!

Let's this by raising an unraisable exception inside the hook itself and check that we don't crash. I don't know if we can recursively call sys.unraisablehook because of that, but if we can, we should check that we don't segfault for whatever reason.

I think this makes sense for a follow-up, because it'll apply to the current implementation as well, right? Ideally, that test would get backported.

In general, we shouldn't have to worry too much about breaking things here, because we're just adding execution of Python code to a path where you could already execute arbitrary Python code.

@picnixz
Copy link
Member

picnixz commented Jun 2, 2025

I think this makes sense for a follow-up, because it'll apply to the current implementation as well, right? Ideally, that test would get backported.

Yes.

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.

2 participants
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy