python / cpython

The Python programming language
https://www.python.org
Other
62.15k stars 29.87k forks source link

Use a less red-ish color for the new prompt and non-error colorized traceback text #118626

Open treyhunner opened 4 months ago

treyhunner commented 4 months ago

Bug report

Bug description:

I noticed that the magenta color used by the new REPL and within the non-error text in the new colorized tracebacks in 3.13 looks quite a bit like an error-related color in some popular color schemes.

Here's an image which shows how an error message displays in a few fairly popular terminal color schemes.

magenta

I've included both "bold as bright" and not. Some terminal emulators enable that setting by default while others do not.

Here are 3 more images showing how the prompt and error messages would display if cyan, blue, or green were used instead of magenta.

cyan blue green

A script I used to help generate those images

I couldn't find data on which color schemes are the most widely used, so I took my best guesses from a bit of research. From the schemes I looked at (Dracula, Nord, Solarized Dark/Light, Gruvbox Dark/Light) I think Cyan, Blue, or Green would look the least like red.

I don't want to start a debate over what color to paint the bike shed, but I think the closeness of the magenta and red colors are important enough to discuss before 3.13.0 lands.

CPython versions tested on:

3.13, CPython main branch

Operating systems tested on:

Linux

Linked PRs

nineteendo commented 4 months ago

Hmm, sounds more like an enhancement than a bug.

hugovk commented 4 months ago

Regarding bug/feature, I think this is something we can tweak during beta, so let's keep the bug label.

I like the suggestion. We could keep the exception name (ZeroDivisionError) magenta/red-ish.

For example compare GitHub's pytb highlighter:

>>> 4 / 0
Traceback (most recent call last):
  File "<python-input-0>", line 1, in <module>
    4 / 0
    ~~^~~
ZeroDivisionError: division by zero
>>> 3.to_bytes(1, 'little')"
  File "<string>", line 1
    3.to_bytes(1, 'little')
     ^
SyntaxError: invalid decimal literal

I think Pygments does something similar.

treyhunner commented 4 months ago

I like the suggestion. We could keep the exception name (ZeroDivisionError) magenta/red-ish.

I agree that the exception name, and even the exception message, in magenta or red seems very appropriate.

hugovk commented 3 months ago

Here's a suggestion.

I'm trying to mirror something like GitHub's pytb colour groups to avoid having too many colours:

>>> 4 / 0
Traceback (most recent call last):
  File "<python-input-0>", line 1, in <module>
    4 / 0
    ~~^~~
ZeroDivisionError: division by zero
>>>
>>> 3.to_bytes(1, 'little')"
  File "<string>", line 1
    3.to_bytes(1, 'little')
     ^
SyntaxError: invalid decimal literal

In the before and after below, I'm using macOS and have iTerm with a dark theme, and Terminal with light theme (Novel), to make it easy to compare without having to dig in the settings each time.

Before image image
After image image
GitHub pytb image image

What do you think?

hugovk commented 3 months ago

And a longer traceback using this script based on a test:

2.py ```python def foo(*args): x = {'a': {'b': None}} y = x['a']['b']['c'] def baz2(*args): return (lambda *args: foo(*args))(1, 2, 3, 4) def baz1(*args): return baz2(1, 2, 3, 4) def bar(): return baz1(1, 2, 3 , 4) bar() ```
pytb ```pytb ❯ ./python.exe 2.py Traceback (most recent call last): File "/Users/hugo/github/python/cpython/main/2.py", line 20, in bar() ~~~^^ File "/Users/hugo/github/python/cpython/main/2.py", line 15, in bar return baz1(1, 2, 3 , 4) File "/Users/hugo/github/python/cpython/main/2.py", line 11, in baz1 return baz2(1, 2, 3, 4) File "/Users/hugo/github/python/cpython/main/2.py", line 7, in baz2 return (lambda *args: foo(*args))(1, 2, 3, 4) ~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^ File "/Users/hugo/github/python/cpython/main/2.py", line 7, in return (lambda *args: foo(*args))(1, 2, 3, 4) ~~~^^^^^^^ File "/Users/hugo/github/python/cpython/main/2.py", line 3, in foo y = x['a']['b']['c'] ~~~~~~~~~~~^^^^^ TypeError: 'NoneType' object is not subscriptable ```
Before image image
After image image
GitHub pytb image image