Skip to content

gh-149026: Add colour to pickletools CLI output#149027

Open
hugovk wants to merge 4 commits intopython:mainfrom
hugovk:3.15-pickletools-colour
Open

gh-149026: Add colour to pickletools CLI output#149027
hugovk wants to merge 4 commits intopython:mainfrom
hugovk:3.15-pickletools-colour

Conversation

@hugovk
Copy link
Copy Markdown
Member

@hugovk hugovk commented Apr 26, 2026

Create a pickle file, for example:

import pickle

data = {
    "a": [1, 2.0, 3 + 4j],
    "b": ("character string", b"byte string"),
    "c": {None, True, False},
}

with open("data.pickle", "wb") as f:
    pickle.dump(data, f, protocol=5)

Then ./python.exe -m pickletools data.pickle:

image

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

@hugovk hugovk requested a review from AA-Turner as a code owner April 26, 2026 20:06
@hugovk hugovk added the stdlib Standard Library Python modules in the Lib/ directory label Apr 26, 2026
@hugovk
Copy link
Copy Markdown
Member Author

hugovk commented Apr 26, 2026

Aside: the alignment is the same in main without colour, and the code says:

            # make a mild effort to align arguments
            ...
            # make a mild effort to align annotations
            ...

If someone's up for making a bit less mild effort in another PR, go for it!

@picnixz
Copy link
Copy Markdown
Member

picnixz commented Apr 27, 2026

Can we have the instruction names in white (no color)? I find it less readable with colors as all instructions have the same color.

@hugovk
Copy link
Copy Markdown
Member Author

hugovk commented Apr 27, 2026

Like this?

image

Or I think bold cyan is better?

image

@picnixz
Copy link
Copy Markdown
Member

picnixz commented Apr 27, 2026

IMO, too many colors hurt more than they help. White is not that good either actually... I do like the colors for literals and the first column but I feel that colors for instruction names are always too much because it's just adding colors to words that will anyway be classified identically.

Alternatively, how about some "dead" words such as MARK/NONE etc and add categorize the opcodes themselves into colorized categories. This could help a bit more visually (e.g., I want to locate all MARK, whether I use colors or not now I won't be able to find it easily without a CTRL+F).

@hugovk
Copy link
Copy Markdown
Member Author

hugovk commented Apr 27, 2026

Something like this?
image

@picnixz
Copy link
Copy Markdown
Member

picnixz commented Apr 27, 2026

Much better IMO! I would suggest not having colors for opcodes that have a colored literal (like SHORT_BINUNICODE). WDYT?

@hugovk
Copy link
Copy Markdown
Member Author

hugovk commented Apr 27, 2026

image

Or we could stripe it to match the value? But give the mild attempt at alignment, maybe they're a bit too close.

image

@picnixz
Copy link
Copy Markdown
Member

picnixz commented Apr 27, 2026

Or we could stripe it to match the value? But give the mild attempt at alignment, maybe they're a bit too close.

It would require a bit more effort to parse the literal in this case. I think the no-color option is better IMO. FTR, the MARK can be in gray as the PROTO because each MARK is followed by an indent I thnk.

@hugovk
Copy link
Copy Markdown
Member Author

hugovk commented Apr 27, 2026

MARK in grey:
image

@picnixz
Copy link
Copy Markdown
Member

picnixz commented Apr 27, 2026

I like those colors, at least they are more readable to me (and I have very poor eyesight). What about light theme though?

@hugovk
Copy link
Copy Markdown
Member Author

hugovk commented Apr 27, 2026

image

Copy link
Copy Markdown
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.

I find the colors much readable now! thanks for the work

Comment thread Lib/pickletools.py
indentchunk = ' ' * indentlevel
errormsg = None
annocol = annotate # column hint for annotations
t = get_theme(tty_file=out if out is not None else sys.stdout).pickletools
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

For follow up:

  • Allow tty_file to be None and if so, fallback to sys.stdout?
  • Is it always safe to use the "t" variable? I love using variables with 1 letter in general but since we don't run linters, we may not always catch shadowing if it happens so maybe we should quickly recheck that in the other existing parts of the stdlib.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

  • Allow tty_file to be None and if so, fallback to sys.stdout?

Yes, it can be None, and ends up at this fallback:

cpython/Lib/_colorize.py

Lines 520 to 521 in 62792c8

if file is None:
file = sys.stdout

  • Is it always safe to use the "t" variable? I love using variables with 1 letter in general but since we don't run linters, we may not always catch shadowing if it happens so maybe we should quickly recheck that in the other existing parts of the stdlib.

I'm generally not a fan of one-letter variables :) But I think it's okay here to make the f-strings more readable, and we've been doing that since adding this theme support: #133347.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Hum, then we should just pass out directly, insteada of
tty_file=out if out is not None else sys.stdout (or am I missing something?

Comment thread Lib/pickletools.py
Comment thread Lib/pickletools.py Outdated
Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

awaiting core review stdlib Standard Library Python modules in the Lib/ directory

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants