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-108082: Add PyErr_FormatUnraisable() function by serhiy-storchaka · Pull Request #111086 · python/cpython

Conversation

@serhiy-storchaka

@serhiy-storchaka serhiy-storchaka commented Oct 19, 2023 •
edited by github-actions Bot
Loading

Uh oh!

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

Copy link
Copy Markdown
Member
  • Issue: [C API] Enhance PyErr_WriteUnraisable() API to pass an error message #108082

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

Sorry, something went wrong.

Uh oh!

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

All reactions
@serhiy-storchaka
pythongh-108082: Add PyErr_FormatUnraisable() function
de02658
@serhiy-storchaka serhiy-storchaka added the topic-C-API label Oct 19, 2023
@serhiy-storchaka
serhiy-storchaka requested a review from vstinner October 19, 2023 19:41
@serhiy-storchaka
serhiy-storchaka requested review from a team and encukou as code owners October 19, 2023 19:41
@bedevere-app bedevere-app Bot mentioned this pull request Oct 19, 2023
[C API] Enhance PyErr_WriteUnraisable() API to pass an error message #108082
Closed
@bedevere-app bedevere-app Bot added the awaiting core review label Oct 19, 2023
vstinner
vstinner reviewed Oct 20, 2023
View reviewed changes

@vstinner vstinner left a comment

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

Variadic argument ... cannot be used in some programming languages like Go, see: capi-workgroup/problems#35 Would it be possible to add also a variant which takes an already formatted string?

Something like: PyErr_WriteUnraisableMsg(PyObject *msg) (I'm not sure about the name, nor the API).

Sorry, something went wrong.

Uh oh!

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

All reactions
Comment thread Doc/c-api/exceptions.rst
Similar to :c:func:`PyErr_WriteUnraisable`, but the *format* and subsequent
parameters help format the warning message; they have the same meaning and
values as in :c:func:`PyUnicode_FromFormat`.
If *format* is ``NULL``, only the traceback is printed.

@vstinner vstinner Oct 20, 2023 •
edited
Loading

Uh oh!

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

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

Would you mind to give examples? I'm not sure how to use this API.

I understood that PyErr_WriteUnraisable(obj) can be written as:

PyErr_FormatUnraisable("Exception ignored in: %R", obj);

And without an exception an object, it should be:

PyErr_FormatUnraisable("Exception ignored in:");

Do the format must end with a newline character?

If format is NULL, only the traceback is printed.

What's the usage of this mode? Is the caller expected to log something like "Exception ignored in xxx" manually?

Sorry, something went wrong.

Uh oh!

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

All reactions

@serhiy-storchaka serhiy-storchaka Oct 29, 2023

Copy link
Copy Markdown
Member Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

PyErr_FormatUnraisable(NULL) is the same as PyErr_WriteUnraisable(NULL). It just prints the traceback, without "Exception ignored ...".

I simply documented the existing behavior for PyErr_WriteUnraisable(), and for PyErr_FormatUnraisable(NULL) the most natural way is to do the same. What alternative do you propose?

Sorry, something went wrong.

Uh oh!

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

All reactions

@vstinner vstinner Oct 31, 2023

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

Sorry, my remark is not specific to NULL value, but more about the whole function. I don't know which string to pass to the function. I suggest to add an example to the doc. Like:

For example, ``PyErr_WriteUnraisable(obj)`` is similar to ``PyErr_FormatUnraisable("Exception ignored in: %R", obj);``.

Sorry, something went wrong.

Uh oh!

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

All reactions
vstinner
vstinner reviewed Oct 20, 2023
View reviewed changes

@vstinner vstinner left a comment

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

Would it be possible to not add this function to the limited C API in Python 3.13, but wait for Python 3.14?

Sorry, something went wrong.

Uh oh!

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

All reactions
@serhiy-storchaka
Merge branch 'main' into capi-PyErr_FormatUnraisable
20a11b3
@serhiy-storchaka

serhiy-storchaka commented Oct 29, 2023

Copy link
Copy Markdown
Member Author

Would it be possible to add also a variant which takes an already formatted string?

What if change PyErr_WriteUnraisable() so that if the argument is string, it prints it as is, instead of of adding "Exception ignored in:" and printing the repr?

All reactions

Sorry, something went wrong.

Uh oh!

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

serhiy-storchaka
serhiy-storchaka commented Oct 29, 2023
View reviewed changes
Comment thread Doc/c-api/exceptions.rst
Similar to :c:func:`PyErr_WriteUnraisable`, but the *format* and subsequent
parameters help format the warning message; they have the same meaning and
values as in :c:func:`PyUnicode_FromFormat`.
If *format* is ``NULL``, only the traceback is printed.

@serhiy-storchaka serhiy-storchaka Oct 29, 2023

Copy link
Copy Markdown
Member Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

PyErr_FormatUnraisable(NULL) is the same as PyErr_WriteUnraisable(NULL). It just prints the traceback, without "Exception ignored ...".

I simply documented the existing behavior for PyErr_WriteUnraisable(), and for PyErr_FormatUnraisable(NULL) the most natural way is to do the same. What alternative do you propose?

Sorry, something went wrong.

Uh oh!

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

All reactions
Comment thread Lib/test/test_capi/test_exceptions.py
(ENOENT, 'No such file or directory', 'file'))
# CRASHES setfromerrnowithfilename(ENOENT, NULL, b'error')

def test_err_writeunraisable(self):

@serhiy-storchaka serhiy-storchaka Oct 29, 2023

Copy link
Copy Markdown
Member Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

TODO: This test should be backported.

Sorry, something went wrong.

Uh oh!

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

All reactions

@serhiy-storchaka serhiy-storchaka Oct 29, 2023

Copy link
Copy Markdown
Member Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

See #111455.

Sorry, something went wrong.

Uh oh!

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

All reactions
serhiy-storchaka added 2 commits October 29, 2023 11:33
@serhiy-storchaka
Remove from the limited C API.
bceb8c5
@serhiy-storchaka
Merge branch 'main' into capi-PyErr_FormatUnraisable
bda2510
vstinner
vstinner approved these changes Oct 31, 2023
View reviewed changes

@vstinner vstinner left a comment

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

Overall, the change LGTM. I just suggest to add a small example in the doc. I also propose to change how errors are handled, but that can be done later, and I can propose a followu-p PR for that if you want.

Sorry, something went wrong.

Uh oh!

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

All reactions
Comment thread Doc/c-api/exceptions.rst
Similar to :c:func:`PyErr_WriteUnraisable`, but the *format* and subsequent
parameters help format the warning message; they have the same meaning and
values as in :c:func:`PyUnicode_FromFormat`.
If *format* is ``NULL``, only the traceback is printed.

@vstinner vstinner Oct 31, 2023

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

Sorry, my remark is not specific to NULL value, but more about the whole function. I don't know which string to pass to the function. I suggest to add an example to the doc. Like:

For example, ``PyErr_WriteUnraisable(obj)`` is similar to ``PyErr_FormatUnraisable("Exception ignored in: %R", obj);``.

Sorry, something went wrong.

Uh oh!

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

All reactions
Comment thread Lib/test/test_capi/test_exceptions.py
self.assertEqual(str(cm.unraisable.exc_value), 'oops!')
self.assertEqual(cm.unraisable.exc_traceback.tb_lineno,
firstline + 15)
self.assertIsNone(cm.unraisable.err_msg)

@vstinner vstinner Oct 31, 2023

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

I would prefer to log an error in the error handler in this case. Ignoring silently errors doesn't help :-(

Sorry, something went wrong.

Uh oh!

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

All reactions

@serhiy-storchaka serhiy-storchaka Oct 31, 2023

Copy link
Copy Markdown
Member Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

_PyErr_WriteUnraisableMsg() does the same: silently ignores decoding and memory errors.

I minimized changes. Other changes can be made in a separate PR.

Sorry, something went wrong.

Uh oh!

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

All reactions
Comment thread Python/errors.c Outdated
_PyErr_WriteUnraisableMsg(const char *err_msg_str, PyObject *obj)

static void
format_unraisable_v(PyObject *obj, const char *format, va_list va)

@vstinner vstinner Oct 31, 2023

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

Would it be possible to move obj to end, last parameter?

Sorry, something went wrong.

Uh oh!

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

All reactions

@serhiy-storchaka serhiy-storchaka Oct 31, 2023

Copy link
Copy Markdown
Member Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

Sure. But I would make the order of arguments inconsistent in format_unraisable() and format_unraisable_v().

Sorry, something went wrong.

Uh oh!

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

All reactions
Comment thread Python/errors.c
if (format != NULL) {
err_msg = PyUnicode_FromFormatV(format, va);
if (err_msg == NULL) {
PyErr_Clear();

@vstinner vstinner Oct 31, 2023

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

I don't think that it's the best behavior. I would prefer to goto error. What do you think?

Maybe PyUnicode_FromString("Exception ignored in sys.unraisablehook") can become a _Py_DECLARE_STR(exc_ignored_msg, "...") + _Py_STR(exc_ignored_msg) static immortal string to avoid error 3 while handling error 2 while handling error 1.

Sorry, something went wrong.

Uh oh!

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

All reactions

@serhiy-storchaka serhiy-storchaka Oct 31, 2023

Copy link
Copy Markdown
Member Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

It is the same as in _PyErr_WriteUnraisableMsg(). Changing the behavior of _PyErr_WriteUnraisableMsg() is out of the scope of this PR.

Sorry, something went wrong.

Uh oh!

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

All reactions
@bedevere-app bedevere-app Bot added awaiting merge and removed awaiting core review labels Oct 31, 2023
@vstinner

vstinner commented Oct 31, 2023

Copy link
Copy Markdown
Member

The main limitation of the new function is that it doesn't allow to pass an object. But I'm not sure that it's really useful. Maybe we should just deprecated this attribute of sys.unraisablehook. I don't know. I mostly added it to delegate the string formatting to the hook.

All reactions

Sorry, something went wrong.

Uh oh!

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

@serhiy-storchaka
Merge branch 'main' into capi-PyErr_FormatUnraisable
38b5ba2
@serhiy-storchaka

serhiy-storchaka commented Oct 31, 2023

Copy link
Copy Markdown
Member Author

The main limitation of the new function is that it doesn't allow to pass an object.

Only 6 of about 70 use cases in CPython code actually pass an object. If it is needed, we can add yet one function, but the function which do not require to pass mandatory NULL argument in 90% of cases is more convenient.

vstinner 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.

@serhiy-storchaka
Address review comments.
b7d68e7
@vstinner

vstinner commented Oct 31, 2023

Copy link
Copy Markdown
Member

Thanks for the short example in the doc ;-)

All reactions

Sorry, something went wrong.

Uh oh!

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

@serhiy-storchaka
serhiy-storchaka merged commit f6a0232 into python:main Oct 31, 2023
@bedevere-app bedevere-app Bot removed the awaiting merge label Oct 31, 2023
@serhiy-storchaka
serhiy-storchaka deleted the capi-PyErr_FormatUnraisable branch October 31, 2023 21:42
FullteaR pushed a commit to FullteaR/cpython that referenced this pull request Nov 3, 2023
@serhiy-storchaka @FullteaR
pythongh-108082: Add PyErr_FormatUnraisable() function (pythonGH-111086)
33462e8
aisk pushed a commit to aisk/cpython that referenced this pull request Feb 11, 2024
@serhiy-storchaka @aisk
pythongh-108082: Add PyErr_FormatUnraisable() function (pythonGH-111086)
7af0c34
Glyphack pushed a commit to Glyphack/cpython that referenced this pull request Sep 2, 2024
@serhiy-storchaka @Glyphack
pythongh-108082: Add PyErr_FormatUnraisable() function (pythonGH-111086)
7a60adc
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@vstinner vstinner vstinner approved these changes
@encukou encukou Awaiting requested review from encukou

Uh oh!

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

Assignees

No one assigned

Labels

topic-C-API

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.

2 participants

@serhiy-storchaka @vstinner
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.