python / python/cpython

Improve the default excepthook formatting for multi-line and exception notes

オープン
#127,596 コメント 6 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

interpreter-core type-feature
主要言語
Python
スター
77.2k
フォーク
35.9k
PR マージ指標
PR 指標を取得中

説明

Proposal:

Currently, it is possible to add notes to exceptions, see BaseException.add_note, but this feature is underutilized.

One of the reasons for that, I believe, is the poor formatting in the default excepthook:

Current Output

(single note)

$ ./python
Python 3.14.0a2+ experimental free-threading build (heads/gh-127429-dirty:cc4f57a74d0, Dec  1 2024, 07:06:51) [GCC 14.2.1 20240910] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> try:
...     raise Exception('error')
... except Exception as e:
...     e.add_note('some context')
...     raise
...
Traceback (most recent call last):
  File "<python-input-0>", line 2, in <module>
    raise Exception('error')
Exception: error
some context

(with multiple notes)

$ ./python
Python 3.14.0a2+ experimental free-threading build (heads/gh-127429-dirty:cc4f57a74d0, Dec  1 2024, 07:06:51) [GCC 14.2.1 20240910] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> try:
...     raise Exception('error')
... except Exception as e:
...     e.add_note('some context')
...     e.add_note('some context 2')
...     e.add_note('some context 3')
...     raise
...
Traceback (most recent call last):
  File "<python-input-0>", line 2, in <module>
    raise Exception('error')
Exception: error
some context
some context 2
some context 3

I think if we formatted it better, making the output easier to understand, we could start seeing better adoption of this feature.

(with multiple notes)

$ ./python
Python 3.14.0a2+ experimental free-threading build (heads/gh-127429-dirty:cc4f57a74d0, Dec  1 2024, 07:06:51) [GCC 14.2.1 20240910] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> try:
...     raise Exception('error')
... except Exception as e:
...     e.add_note('some context')
...     e.add_note('some context 2')
...     e.add_note('some context 3')
...     raise
...
Traceback (most recent call last):
  File "<python-input-0>", line 2, in <module>
    raise Exception('error')
Exception: error
├── Note: some context
├── Note: some context 2
└── Note: some context 3

In addition to this, multiline exception messages could also be improved.

Current Output

(multi-line string, with no notes)

$./python
Python 3.14.0a2+ experimental free-threading build (heads/gh-127429-dirty:cc4f57a74d0, Dec  1 2024, 07:06:51) [GCC 14.2.1 20240910] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> raise Exception('some error\n\nsome context\nsome context (cont.)\n\nsome extra context')
Traceback (most recent call last):
  File "<python-input-0>", line 1, in <module>
    raise Exception('some error\n\nsome context\nsome context (cont.)\n\nsome extra context')
Exception: some error

some context
some context (cont.)

some extra context

(multi-line string, with multi-line notes)

$ ./python
Python 3.14.0a2+ experimental free-threading build (heads/gh-127429-dirty:cc4f57a74d0, Dec  1 2024, 07:06:51) [GCC 14.2.1 20240910] on linux
>>> try:
...     raise Exception('some error\n\nsome error text\nsome error text (cont.)\n\nsome more error text')
... except Exception as e:
...     e.add_note('some context\nsome context (cont.)')
...     e.add_note('some context 2\n\nsome extra context 2')
...     e.add_note('some context 3\nsome context 3 (cont.)\n\nsome extra context 3')
...     raise
...
Traceback (most recent call last):
  File "<python-input-0>", line 2, in <module>
    raise Exception('some error\n\nsome error text\nsome error text (cont.)\n\nsome more error text')
Exception: some error

some error text
some error text (cont.)

some more error text
some context
some context (cont.)
some context 2

some extra context 2
some context 3
some context 3 (cont.)

some extra context 3

The first example IMO isn't optimal, but it's okay enough, but the second example is very confusing. We could format it something like:

$ ./python
Python 3.14.0a2+ experimental free-threading build (heads/gh-127429-dirty:cc4f57a74d0, Dec  1 2024, 07:06:51) [GCC 14.2.1 20240910] on linux
>>> try:
...     raise Exception('some error\n\nsome error text\nsome error text (cont.)\n\nsome more error text')
... except Exception as e:
...     e.add_note('some context\nsome context (cont.)')
...     e.add_note('some context 2\n\nsome extra context 2')
...     e.add_note('some context 3\nsome context 3 (cont.)\n\nsome extra context 3')
...     raise
...
Traceback (most recent call last):
  File "<python-input-0>", line 2, in <module>
    raise Exception('some error\n\nsome error text\nsome error text (cont.)\n\nsome more error text')
Exception: 
│ │ some error
│ │
│ │ some error text
│ │ some error text (cont.)
│ │
│ └ some more error text
│
├── Note:
│   │ some context
│   └ some context (cont.)
│
├── Note:
│   │ some context 2
│   │ 
│   └ some extra context 2
│
└── Note:
    │ some context 3
    │ some context 3 (cont.)
    │ 
    └ some extra context 3
Has this already been discussed elsewhere?

No response given

Links to previous discussion of this feature:

No response

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

調査の方向性

CPython のデフォルトの excepthook と例外フォーマットのエントリーポイントから始めます。この issue ではファイルもテストも指定されていません。現在の出力を、提案されている 1 行および複数行の note の例と比較し、メッセージ内容を失わずに意図されたツリー状のフォーマットになっていれば完了とみなします。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
python
領域
backend
issue の種類
機能追加
難易度
5/5
見積もり時間
1週間以上
活発さ
停滞
明瞭さ
おおむね明確
初心者へのやさしさ
35/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。