Skip to content

Introduction

DHV DHV v1.0.0 — Python 3.14.0 ┌─ Source───────────────────────────────────────────────────┌─ Disassembly────────────────────────────────────────────── │ 1  """The main application class."""│0      0RESUME                 0                     │ 2  │1      2LOAD_CONST             'The main application │ 3  ######################################################│class.'               │ 4  # Python imports.│4STORE_NAME             __doc__               │ 5  from argparse importNamespace│5      6LOAD_SMALL_INT         0                     │ 6  │8LOAD_CONST             ('Namespace',)        │ 7  ######################################################│10IMPORT_NAME            argparse              │ 8  # Textual imports.│12IMPORT_FROM            Namespace             │ 9  from textual.app importInvalidThemeError│14STORE_NAME             Namespace             │10  │16POP_TOP                 │11  ######################################################│9      18LOAD_SMALL_INT         0                     │12  # Textual enhanced imports.│20LOAD_CONST             ('InvalidThemeError'… │13  from textual_enhanced.app importEnhancedApp│22IMPORT_NAME            textual.app           │14  │24IMPORT_FROM            InvalidThemeError     │15  ######################################################│26STORE_NAME             InvalidThemeError     │16  # Local imports.│28POP_TOP                 │17  from.import __version__ │13     30LOAD_SMALL_INT         0                     │18  from.data import(│32LOAD_CONST             ('EnhancedApp',)      │19      load_configuration,┌─ AST────────────────────────────────────────────────────── │20      update_configuration,│Module │21  )│body │22  from.screens importMain│Expr │23  │value │24  │Constant │25  ######################################################│value │26  classDHV(EnhancedApp[None]):│'The main application class.' │27  """The main application class."""│kind │28  │None │29      HELP_TITLE =f"DHV v{__version__}"│ImportFrom │30      HELP_ABOUT =""" │module │31      `DHV` is a terminal-based Python code explorer; it│'argparse' │32      by and is maintained by [Dave Pearson](https://www│names │33      Free Software and can be [found on │alias │34      GitHub](https://github.com/davep/dhv). │name │35      """│'Namespace' │36      HELP_LICENSE =""" │asname │▉│▍  f1 Help  f5 Opcode Counts  f10 Quit  ^n New  ^l Load ▏^p Commands

DHV is a Python code exploration tool for the terminal, designed to let you type in, load up, and edit Python code, and see what the resulting abstract syntax tree and bytecode looks like.

If you've ever felt curious about what your Python source code gets turned into, this is one tool that might help satisfy that curiosity.

Installation

Note

DHV requires Python 3.13 or later.

pipx

The application can be installed using pipx:

pipx install dhv

uv

The package can be install using uv:

uv tool install --python 3.13 dhv

Running DHV

Once you've installed DHV using one of the above methods, you can run the application using the dhv command.

Command line options

DHV has a number of command line options; they include:

-b, --bindings

Prints the application commands whose keyboard bindings can be modified, giving the defaults too.

dhv --bindings
ChangeCodeTheme - Change the theme of the Python code editor
    Default: ctrl+f9
ChangeTheme - Change the application's theme
    Default: f9
Help - Show help for and information about the application
    Default: f1, ?
LoadFile - Load the content of a Python source file
    Default: ctrl+l
NewCode - Empty the editor ready to enter some new code
    Default: ctrl+n
OpcodeCounts - View the count of opcodes in the code
    Default: f5
Quit - Quit the application
    Default: f10, ctrl+q
ShowASTOnly - Only show the AST of the source code
    Default: ctrl+t
ShowDisassemblyAndAST - Show both the disassembly and the AST of the source code
    Default: ctrl+o
ShowDisassemblyOnly - Only show the disassembly of the source code
    Default: ctrl+b
SwitchLayout - Switch the screen layout between horizontal and vertical
    Default: f2
ToggleOffsets - Toggle the display of the offsets
    Default: f3
ToggleOpcodes - Toggle the display of the numeric opcodes
    Default: f4

-h, --help

Prints the help for the dhv command.

dhv --help
usage: dhv [-h] [-v] [--license] [-b] [-t THEME] [source]

DHV - A tool to dive into Python code.

positional arguments:
  source                A Python source file to disassemble

options:
  -h, --help            show this help message and exit
  -v, --version         Show version information
  --license, --licence  Show license information
  -b, --bindings        List commands that can have their bindings changed
  -t, --theme THEME     Set the theme for the application (set to ? to list
                        available themes)

v1.0.0

--license, --licence

Prints a summary of DHV's license.

dhv --license
DHV - A Python code explorer for the terminal.  
Copyright (C) 2025 Dave Pearson

This program is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
Software Foundation, either version 3 of the License, or (at your option)
any later version.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.

You should have received a copy of the GNU General Public License along with
this program. If not, see <https://www.gnu.org/licenses/>.

-t, --theme

Sets DHV's theme; this overrides and changes any previous theme choice made via the user interface.

To see a list of available themes use ? as the theme name:

dhv --theme=?
catppuccin-latte
catppuccin-mocha
dracula
flexoki
gruvbox
monokai
nord
solarized-light
textual-dark
textual-light
tokyo-night

-v, --version

Prints the version number of DHV.

dhv --version
dhv v1.0.0

Getting help

A great way to get to know DHV is to read the help screen. Once in the application you can see this by pressing F1.

The DHV Help Screen DHV v1.0.0 — Python 3.14.0 ┌─ Source───────────────────────────────────────────────────┌─ Disassembly────────────────────────────────────────────── │ 1  """The mai┌─ Help ─────────────────────────────────────────────────────────────────────────────────┐ │ 2  ││in application▃ │ 3  ##########││ │ 4  # Python i││ │ 5  from argpa│DHV v1.0.0│ │ 6  ││pace',)        │ 7  ##########││e              │ 8  # Textual ││ce             │ 9  from textu│Python Source│ce             │10  ││ │11  ##########│This panel is the Python source code that you're exploring.│ │12  # Textual ││idThemeError'… │13  from textu││.app           │14  │Main application keys and commands│ThemeError     │15  ##########││ThemeError     │16  # Local im│The following key bindings and commands are available:│ │17  from.imp││ │18  from.data│┌────────────────┬─────┬──────────────────────────────────────────────────────────┐│cedApp',)      │19      load_c││Command│Key│Description││_enhanced.app  │20      update│├────────────────┼─────┼──────────────────────────────────────────────────────────┤│dApp           │21  )││Change Code│^f9│Change the theme of the Python code editor││dApp           │22  from.scre││Theme│││▃│ │23  │├────────────────┼─────┼──────────────────────────────────────────────────────────┤│ │24  ││Change Theme│f9│Change the application's theme││─────────────── │25  ##########│├────────────────┼─────┼──────────────────────────────────────────────────────────┤│ │26  classDHV(││Help│f1│Show help for and information about the application││ │27  """The│├────────────────┼─────┼──────────────────────────────────────────────────────────┤│ │28  ││Load File│^l│Load the content of a Python source file││ │29      HELP_T│├────────────────┼─────┼──────────────────────────────────────────────────────────┤│ │30      HELP_A││New Code│^n│Empty the editor ready to enter some new code││ │31      `DHV` │├────────────────┼─────┼──────────────────────────────────────────────────────────┤│ │32      by and││Opcode Counts│f5│View the count of opcodes in the code││ │33      Free S│├────────────────┼─────┼──────────────────────────────────────────────────────────┤│ │34      GitHub││Quit│f10│Quit the application││ │35      """│├────────────────┼─────┼──────────────────────────────────────────────────────────┤│ │36      HELP_L││Show AST Only│^t│Only show the AST of the source code││ │37      DHV - │├────────────────┼─────┼──────────────────────────────────────────────────────────┤│ │38  ││Show│^o│Show both the disassembly and the AST of the source code││ │39      This p││Disassembly││││ │40      under ││And AST││││ │41      Softwa│────────────────────────────────────────────────────────────────────────────────────────│ │42      any la│▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔│ │43  │ Okay [Esc]│ │44      This p│▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁│ │45      ANY WA└────────────────────────────────────────────────────────────────────────────────────────┘ │46      FITNESS FOR A PARTICULAR PURPOSE. See the GNU Gene│module │▉│▍  f1 Help  f5 Opcode Counts  f10 Quit  ^n New  ^l Load ▏^p Commands

The help will adapt to which part of the screen has focus, providing extra detail where appropriate.

The command palette

Another way of discovering commands and keys in DHV is to use the command palette (by default you can call it with ctrl+p or meta+x).

The DHV Command Palette DHV v1.0.0 — Python 3.14.0 ┌─ Source───────────────────────────────────────────────────┌─ Disassembly────────────────────────────────────────────── │ 1  """The main application class."""│0      0RESUME                 0                     │ 2  ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔in application▃ │ 3  ########## │ 4  # Python iSearch for commands… │ 5  from argpa │ 6  pace',)        │ 7  ##########Change Code Theme [^f9]e              │ 8  # Textual Change the theme of the Python code editorce             │ 9  from textuChange Theme [f9]ce             │10  Change the application's theme │11  ##########Help [f1] │12  # Textual Show help for and information about the applicationidThemeError'… │13  from textuQuit [f10].app           │14  Quit the applicationThemeError     │15  ##########Load File [^l]ThemeError     │16  # Local imLoad the content of a Python source file │17  from.impNew Code [^n] │18  from.dataEmpty the editor ready to enter some new codecedApp',)      │19      load_cOpcode Counts [f5]_enhanced.app  │20      updateView the count of opcodes in the codedApp           │21  )Switch Layout [f2]dApp           │22  from.screSwitch the screen layout between horizontal and vertical │23  Toggle Offsets [f3] │24  Toggle the display of the offsets─────────────── │25  ##########Toggle Opcodes [f4] │26  classDHV(Toggle the display of the numeric opcodes │27  """TheShow AST Only [^t] │28  Only show the AST of the source code │29      HELP_TShow Disassembly And AST [^o] │30      HELP_AShow both the disassembly and the AST of the source code │31      `DHV` Show Disassembly Only [^b] │32      by andOnly show the disassembly of the source code │33      Free S▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ │34      GitHub](https://github.com/davep/dhv). │ImportFrom │35      """│module │36      HELP_LICENSE =""" │'argparse' │37      DHV - A Python code explorer for the terminal.  \n│names │38  │alias │39      This program is free software: you can redistribut│name │40      under the terms of the GNU General Public License │'Namespace' │41      Software Foundation, either version 3 of the Licen│asname │42      any later version. │None │43  │level │44      This program is distributed in the hope that it wi│0 │45      ANY WARRANTY; without even the implied warranty of│ImportFrom │46      FITNESS FOR A PARTICULAR PURPOSE. See the GNU Gene│module │▉│▍  f1 Help  f5 Opcode Counts  f10 Quit  ^n New  ^l Load ▏^p Commands

Questions and feedback

If you have any questions about DHV, or you have ideas for how it might be improved, do please feel free to visit the discussion area and ask your question or suggest an improvement.

When doing so, please do search past discussions and also issues current and previous to make sure I've not already dealt with this, or don't have your proposed change already flagged as something to do.