Skip to content
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

Use Python 3.11 exception notes (PEP 678) to provide hints on errors #96958

Closed
vstinner opened this issue Sep 20, 2022 · 3 comments
Closed

Use Python 3.11 exception notes (PEP 678) to provide hints on errors #96958

vstinner opened this issue Sep 20, 2022 · 3 comments
Labels
type-bug An unexpected behavior, bug, or error

Comments

@vstinner
Copy link
Member

Python 3.11 adds BaseException.add_note() method to add "notes" to exceptions (PEP 678). One of the Motivations is providing hints to novices:

programming environments for novices can provide more detailed descriptions of various errors, and tips for resolving them

I propose modifying the few existing errors which already provide hints by converting the sentence to a note: restrict the error message to the actual error, and move hints to notes.

Example of an existing error with a hint:

$ python3 -q
>>> import sys
>>> print >>sys.stderr, "hello"
...
TypeError: unsupported operand type(s) for >>: 'builtin_function_or_method' and '_io.TextIOWrapper'. Did you mean "print(<message>, file=<output_stream>)"?

Currently, the actual error ("unsupported operand") and the hint ("Did you mean...") are displayed on the same line. IMO displaying the hint on a separated line would make it easier to spot (it would be less likely to miss it).

Example raising a note manually to see how it's displayed:

try:
    raise TypeError("unsupported operand")
except Exception as exc:
    exc.add_note("Did you mean...")
    raise

Current Python 3.12 output:

Traceback (most recent call last):
  File "bug.py", line 2, in <module>
    raise TypeError("unsupported operand")
TypeError: unsupported operand
Did you mean...

I proposed PR #96878 to add _PyErr_AddNote() function to the internal C API.


I found these hints:

  • "Use sys.set_int_max_str_digits() to increase the limit": see PR gh-95778: Use a note for the max digits error message #96878
  • print >> 123: unsupported operand ...: Did you mean "print(<message>, "file=<output_stream>)"?
  • 1 is 2: "is" with a literal. Did you mean "=="?
  • 1 is not 2: "is" with a literal. Did you mean "!="?
  • "Suggestions" added by PyErr_Display() with _Py_Offer_Suggestions() (issue Offer suggestions on AttributeError and NameError #82711) is not a good fit: this code doesn't modify the exception on purpose
  • print "hello": Missing parentheses in call to 'print'. Did you mean print(...)? (similar error on exec code)
@vstinner vstinner added the type-bug An unexpected behavior, bug, or error label Sep 20, 2022
@iritkatriel
Copy link
Member

This achieves the same display:

>>> raise TypeError("unsupported operand\nDid you mean...")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand
Did you mean...

If there is a use case for being able to distinguish the error from the suggestion, then putting the suggestion in a note can help do that.

@vstinner
Copy link
Member Author

Is is something common to include a newline character in error messages? My worry is that maybe it's not displayed properly in a terminal, in logs, or in a graphical dialog (like a popup message). Well, now we have this new feature and I would like to use it :-) You know, eating our own dog food :-)

The disadvantage of notes is that it's something new (Python 3.11 is not released yet ;-)), so maybe existing tools don't show notes yet (just ignore them), and notes might be lost when an exception is converted to a new exception (of a different type and/or with a different error message). Example:

try:
    raise TypeError("original message")
except Exception as exc:
    raise ValueError(f"new message ({exc})") from None

Python 3.12 output:

Traceback (most recent call last):
  File "bug.py", line 4, in <module>
    raise ValueError(f"new message ({exc})") from None
ValueError: new message (original message)

@vstinner
Copy link
Member Author

@iritkatriel: Well, it seems like I failed to convince you to use notes for "suggestions". It seems like I misunderstood the part about "suggestions" (called "tips" in PEP 678). Since you authored PEP 678, I will follow your guidance and I close the issue. So it seems like right now, there is no need for a C API _PyErr_AddNote(): the add_note() method should be enough for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

No branches or pull requests

2 participants