xraywidgets v0.1, and the disassembler widget - #68
Merged
Conversation
The first of the interactive components issue #14 lists. Type Python, see the bytecode, and turn on the four things dis leaves out: the specialized opcodes the interpreter installed, the inline cache entries sitting between the instructions, the stack depth either side of each one, and the exception table. Every widget renders twice from one piece of code. With nothing installed it draws plain HTML with the real numbers in it and the buttons switched off, which is what a reader gets on GitHub, in an nbconvert render, in a PDF, and while Pyodide is still starting. With anywidget installed it draws the same picture with the buttons working. The front end holds no bytecode logic at all: Python computes the rows and renders the markup, the JavaScript puts it on the page and hands clicks back. So the two pictures cannot disagree, and there is a test that greps the module for opcode names to keep it that way. Two rules are enforced rather than remembered. parts.chip will not build a coloured badge without words in it, so colour is never the only signal, and style.py reads the palette out of pyxray.theme with a test that fails on a hand written hex colour, so the widgets cannot fork away from the diagrams beside them. Also adds pyxray.bytecode.exception_table, which the exception toggle needs and which nothing exposed before, and installs the live extra in the CI test job so the interactive half is exercised on every pull request.
This was referenced Aug 29, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The first of the interactive components on #14, and the one the pilot lesson needs before it can be written.
What it does
dis.disprints a good table and stops. The four things a reader keeps needing next are not in it, and each one is a toggle here, off by default because a first disassembly with all four on is a wall:trywent, since there have been noSETUP_FINALLYinstructions to look at since 3.11Why the front end decides nothing
Python computes the rows and renders the markup. The JavaScript puts that markup on the page, listens for a click on a toggle and a keystroke in the source box, and hands both back. It contains no opcode names, no cache arithmetic, and no idea what an exception table is.
That is not tidiness. If the browser worked out which opcodes were specialized there would be two answers to that question in this repository, and the one written in JavaScript is the one nobody tests. It would drift in the direction of looking right, and the person who noticed would be a reader who trusted the widget over
disand came away with the wrong idea about CPython.test_the_front_end_module_works_out_no_bytecode_of_its_owngreps the module for names indis.opmapand fails if it finds any.It is also what makes the static rendering real rather than a promise. There is no code path where a widget is only correct once a browser is involved, so the version on GitHub, in an nbconvert render, in a PDF export, and in the seconds before Pyodide has started has the right numbers in it.
Two rules that are code rather than review comments
parts.chipraises if you give it a badge with no words in it, so colour is never the only signal. The specialized badge says the word "specialized", which is what a reader with any of the common kinds of colour blindness needs, and also what survives a printed handout or a screenshot with the saturation eaten by compression.style.pyreads the palette out ofpyxray.themeand writes it as CSS custom properties, and a test greps the sheet for hand written hex colours. There is exactly one place the project decides what blue means, and the widgets cannot fork away from the diagrams sitting next to them.The toggles are real
<button>elements witharia-pressed, so they are reachable by tab and operable by space bar with no JavaScript involved, and a screen reader can say whether one is on. The static rendering marks them disabled, because a button that looks live and does nothing is worse than one that admits it.Also in here
pyxray.bytecode.exception_table, with aHandlerdataclass and acovers()method. The exception toggle needed it and nothing exposed it before. It is checked againstdis._parse_exception_tabledirectly rather than against a frozen listing, and there is a test that the protected range of the first handler really does contain the call that can raise.CI installs the
liveextra in the test job. Without it the interactive half of every widget would be run only on the machine of whoever happened to have anywidget installed, and the static half is the half that is easy to keep working by accident.Checks
just checkis green: 1067 passed and 2 skipped, up from 970, 352 citations resolved, and lint, format, blueprints, diagrams, lessons, notebooks and animations all clean.Refs #14.