Skip to content

gh-144207: Syntax highlighting (theming support) for dis module#144208

Open
AbduazizZiyodov wants to merge 21 commits intopython:mainfrom
Abduaziz-Projects:dis-theme-support
Open

gh-144207: Syntax highlighting (theming support) for dis module#144208
AbduazizZiyodov wants to merge 21 commits intopython:mainfrom
Abduaziz-Projects:dis-theme-support

Conversation

@AbduazizZiyodov
Copy link
Copy Markdown

@AbduazizZiyodov AbduazizZiyodov commented Jan 24, 2026

About

Implemented in similar fashion (e.g unittest, difflib etc.) by defining ThemeSection and registered theme on Theme class.

Basic highlighting shown in forum(green for all opcodes), but in this PR: one color maps to group of opcodes (e.g. blue for binary opcodes) -- gives better context and it is determined via color_by_opname method.

I have trouble with tests, now dis is defaulting to colored output and 2 tests were failing. I had to set environment variable: NO_COLOR=1... I think, there might be better ways of doing this, one is to define force_no_color flag(keyword only) to dis.dis function which I'm not certain. So, I would like to elaborate with you on that.

EDIT: Any ideas/additions on color mapping is encouraged :)

Sample screenshots

(see #144208 (comment) for the latest)

In dark mode dark_01 dark_02
In light mode light_01 light_02
No color no_color_01

Thanks.

Highlights opcode's name, arguments, exception table labels.
…ecause dis is not defaulting to syntax highligthing. Of course it needs better handling which I'm not sure now.
@bedevere-app
Copy link
Copy Markdown

bedevere-app Bot commented Jan 24, 2026

Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool.

If this change has little impact on Python users, wait for a maintainer to apply the skip news label instead.

@bedevere-app
Copy link
Copy Markdown

bedevere-app Bot commented Jan 24, 2026

Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool.

If this change has little impact on Python users, wait for a maintainer to apply the skip news label instead.

@python-cla-bot
Copy link
Copy Markdown

python-cla-bot Bot commented Jan 24, 2026

All commit authors signed the Contributor License Agreement.

CLA signed

Copy link
Copy Markdown
Member

@StanFromIreland StanFromIreland left a comment

Choose a reason for hiding this comment

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

Please add a NEWS entry and update What's New.

Comment thread Lib/test/test_dis.py Outdated
Comment thread Lib/_colorize.py Outdated
Comment thread Lib/dis.py Outdated
Comment thread Lib/test/test_dis.py
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.

Please add tests for the colouration.

@bedevere-app
Copy link
Copy Markdown

bedevere-app Bot commented Jan 24, 2026

Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool.

If this change has little impact on Python users, wait for a maintainer to apply the skip news label instead.

Comment thread Lib/dis.py Outdated
Comment thread Lib/_colorize.py
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.

Please add a What's News entry and tests. I personally do not like this by default since I use grep/cut on the dis output so I would prefer a CLI option to enable colors. EDIT: not a concern anymore

Comment thread Lib/_colorize.py
"GET_AWAITABLE",
"GET_AITER",
"GET_ANEXT",
"END_ASYNC_FOR",
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.

I am a bit confused with END_FOR and END_ASYNC_FOR being colored differently but I do not remember the exact effect of the latter.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I've read that END_FOR is equivalent(or alias I would say) to POP_TOP:

Removes the top-of-stack item. Equivalent to POP_TOP. Used to clean up at the end of loops, hence the name.

and it is specified under "General instructions" section while END_ASYNC_FOR in "Coroutine opcodes" (I generalized this into "control flow" opcodes).

Almost all opcodes are dealing with stack, but END_ASYNC_FOR is putting little more effort than END_FOR which is just stack.pop(), that's why I thought END_ASYNC_FOR is different than END_FOR.

That's my understanding.

We might elaborate our discussion on categories in your next comment too.

Comment thread Lib/_colorize.py Outdated
exception_label: str = ANSIColors.CYAN
argument_detail: str = ANSIColors.GREY

op_stack: str = ANSIColors.BOLD_YELLOW
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.

How were those categories determined? are they determined already like that in dis.rst?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

are they determined already like that in dis.rst?

Almost, I first grouped according to dis.rst then re-categorized them according to my understanding (how these opcodes relate, semantically) -- which might need some refinement too.

Comment thread Lib/dis.py Outdated
@bedevere-app
Copy link
Copy Markdown

bedevere-app Bot commented Jan 24, 2026

A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated.

Once you have made the requested changes, please leave a comment on this pull request containing the phrase I have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.

@hugovk
Copy link
Copy Markdown
Member

hugovk commented Jan 24, 2026

I personally do not like this by default since I use grep/cut on the dis output

Not to worry, it can stay on by default because colour is automatically disabled in pipes:

image

@picnixz
Copy link
Copy Markdown
Member

picnixz commented Jan 24, 2026

Oh! great then. I was worried about this. Do we plan to have colors for JSON? (or maybe we already do?) or for symtable? (the symtable cli is very rudimentary and I sometimes want a better one).

There are few modules who output formatted code (AFAIR, dis, symtable, json or even ast) so I wondered whether those would also be colorized. And if we eventually plan to add colors wherever we can (it should be a separate DPO thread/gh issue)

@hugovk
Copy link
Copy Markdown
Member

hugovk commented Jan 24, 2026

json, yes: https://docs.python.org/3/whatsnew/3.14.html#json. symtable, no[t yet].

@bedevere-app
Copy link
Copy Markdown

bedevere-app Bot commented Jan 25, 2026

Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool.

If this change has little impact on Python users, wait for a maintainer to apply the skip news label instead.

Comment thread Lib/dis.py Outdated
@AbduazizZiyodov
Copy link
Copy Markdown
Author

Oh! great then. I was worried about this. Do we plan to have colors for JSON? (or maybe we already do?) or for symtable? (the symtable cli is very rudimentary and I sometimes want a better one).

There are few modules who output formatted code (AFAIR, dis, symtable, json or even ast) so I wondered whether those would also be colorized. And if we eventually plan to add colors wherever we can (it should be a separate DPO thread/gh issue) @picnixz

Indeed! symtable needs this enhancement as you mentioned, I'll work on this too after this PR gets merged, if anyone hasn't planned.

Copy link
Copy Markdown
Member

@StanFromIreland StanFromIreland left a comment

Choose a reason for hiding this comment

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

Please add tests.

Comment thread Doc/whatsnew/3.15.rst Outdated
Comment thread Doc/whatsnew/3.15.rst Outdated
Comment thread Doc/whatsnew/3.15.rst Outdated
Comment thread Doc/whatsnew/3.15.rst Outdated
@AbduazizZiyodov
Copy link
Copy Markdown
Author

I'll focus on tests, and try suggested ideas from discussion forum too (probably reducing number of categories maybe).

@hugovk hugovk changed the title gh-144207: Syntax highlighting(theming support) for dis module gh-144207: Syntax highlighting (theming support) for dis module Feb 26, 2026
@AbduazizZiyodov
Copy link
Copy Markdown
Author

  • Updated base theme, tried to apply suggestions from discussion thread. I would say, its more "load/pop" oriented now:

    Dark dark-1 dark-2
    Light light-1 light-2
  • Added DisColoredTests test case. Another way would've been re-writing some(or all) of existing templates in "colored fashion" and test them separately - introduces a lot of redundancy (IMO).

    Example
     # existing template
     dis_f = """\
     %3d           RESUME                   0
     
     %3d           LOAD_GLOBAL              1 (print + NULL)
                   LOAD_FAST_BORROW         0 (a)
                   CALL                     1
                   POP_TOP
     
     %3d           LOAD_SMALL_INT           1
                   RETURN_VALUE
     """ % (_f.__code__.co_firstlineno,
            _f.__code__.co_firstlineno + 1,
            _f.__code__.co_firstlineno + 2)
     
     # to colored
     dis_f_colored = """\
     %3d           %sRESUME%s                   0
     %3d           %sLOAD_GLOBAL%s              1 %s(print + NULL)%s
                   %sLOAD_FAST_BORROW%s         0 %s(a)%s
                   %sCALL%s                     1
                   %sPOP_TOP%s
     %3d           %sLOAD_SMALL_INT%s           1
                   %sRETURN_VALUE%s
     """ % (_f.__code__.co_firstlineno, 
             theme.op_call_return, theme.reset,
            _f.__code__.co_firstlineno + 1,
            theme.op_load, theme.reset, theme.argument_detail, theme.reset,
            theme.op_load, theme.reset, theme.argument_detail, theme.reset,
            theme.op_call_return, theme.reset,
            theme.op_pop, theme.reset,
            _f.__code__.co_firstlineno + 2,
            theme.op_load, theme.reset,
            theme.op_call_return, theme.reset
     )

    I'm skeptic whether it would give enough value for effort spent. Let me know if you have thoughts on different method of testing there.

  • Manually tested color customization option (as far as I know, its experimental) as mentioned in discussion forum:

    Default default
    Customized customized
    Contents of PYTHONSTARTUP
     try:
         from dataclasses import replace
         from _colorize import ANSIColors, default_theme, set_theme
     except ImportError:
         pass
     else:
         print("Replacing theme ...")
         theme = default_theme.copy_with(
             dis=replace(
                 default_theme.dis,
                 label_bg=ANSIColors.BOLD_GREEN,
                 label_fg=ANSIColors.BLACK,
                 exception_label=ANSIColors.BOLD_GREEN,
                 argument_detail=ANSIColors.BOLD_GREEN,
                 op_load=ANSIColors.BOLD_GREEN,
                 op_pop=ANSIColors.BOLD_YELLOW,
                 op_call_return=ANSIColors.BOLD_MAGENTA,
                 op_control_flow=ANSIColors.BOLD_CYAN,
                 reset=ANSIColors.RESET,
             ),
         )
         set_theme(theme)

Comment thread Lib/test/test_dis.py Outdated
Copy link
Copy Markdown
Member

@sobolevn sobolevn left a comment

Choose a reason for hiding this comment

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

LGTM, I did not check that colorizations logic, because I am not an expert in it.

@picnixz
Copy link
Copy Markdown
Member

picnixz commented Mar 1, 2026

I emitted some reservations in https://discuss.python.org/t/syntax-highlighting-for-dis-module/105833/14 about the explosion of colors. I would prefer that we have alternate colorization in terms of blocks like godbolt

@hugovk
Copy link
Copy Markdown
Member

hugovk commented Apr 18, 2026

Where are we up to with this one? There's just over a couple of weeks before the 3.15 feature freeze.

@picnixz Is the current state a blocker for you?

@picnixz
Copy link
Copy Markdown
Member

picnixz commented Apr 19, 2026

I have commented on the DPO thread about my concerns for the overusage of colors and suggested zebra lines per section.

@hugovk
Copy link
Copy Markdown
Member

hugovk commented Apr 20, 2026

OK, thanks!

@AbduazizZiyodov Do you know what to do next? Do you have an idea of the colour scheme to use?

@AbduazizZiyodov
Copy link
Copy Markdown
Author

OK, thanks!

@AbduazizZiyodov Do you know what to do next? Do you have an idea of the colour scheme to use?

I have some idea, the screenshot I've shared on discourse forum + coloring exception tables (e.g. magenta, red). Any suggestions are welcome - current color scheme(the way it "rendered") looks bit sharp to me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants