{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "65b8b71b",
   "metadata": {},
   "source": [
    "# Usage\n",
    "\n",
    "## Python API\n",
    "\n",
    "### `from_code`\n",
    "\n",
    "The main entrypoint to our API is the `CodeData` object. You can create it from any Python `CodeType`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "b6d22cb4",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">\n",
       "<span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">CodeData</span><span style=\"font-weight: bold\">(</span>\n",
       "    <span style=\"font-weight: bold\">(</span>\n",
       "        <span style=\"font-weight: bold\">(</span>\n",
       "            <span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">Instruction</span><span style=\"font-weight: bold\">(</span><span style=\"color: #008000; text-decoration-color: #008000\">'LOAD_FAST'</span>, <span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">Varname</span><span style=\"font-weight: bold\">(</span><span style=\"color: #008000; text-decoration-color: #008000\">'a'</span><span style=\"font-weight: bold\">)</span>, <span style=\"color: #808000; text-decoration-color: #808000\">line_number</span>=<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">7</span><span style=\"font-weight: bold\">)</span>,\n",
       "            <span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">Instruction</span><span style=\"font-weight: bold\">(</span><span style=\"color: #008000; text-decoration-color: #008000\">'LOAD_FAST'</span>, <span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">Varname</span><span style=\"font-weight: bold\">(</span><span style=\"color: #008000; text-decoration-color: #008000\">'b'</span><span style=\"font-weight: bold\">)</span>, <span style=\"color: #808000; text-decoration-color: #808000\">line_number</span>=<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">7</span><span style=\"font-weight: bold\">)</span>,\n",
       "            <span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">Instruction</span><span style=\"font-weight: bold\">(</span><span style=\"color: #008000; text-decoration-color: #008000\">'BINARY_ADD'</span>, <span style=\"color: #808000; text-decoration-color: #808000\">line_number</span>=<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">7</span><span style=\"font-weight: bold\">)</span>,\n",
       "            <span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">Instruction</span><span style=\"font-weight: bold\">(</span><span style=\"color: #008000; text-decoration-color: #008000\">'RETURN_VALUE'</span>, <span style=\"color: #808000; text-decoration-color: #808000\">line_number</span>=<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">7</span><span style=\"font-weight: bold\">)</span>\n",
       "        <span style=\"font-weight: bold\">)</span>,\n",
       "    <span style=\"font-weight: bold\">)</span>,\n",
       "    <span style=\"color: #808000; text-decoration-color: #808000\">filename</span>=<span style=\"color: #008000; text-decoration-color: #008000\">'/tmp/ipykernel_635/3063237183.py'</span>,\n",
       "    <span style=\"color: #808000; text-decoration-color: #808000\">first_line_number</span>=<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">6</span>,\n",
       "    <span style=\"color: #808000; text-decoration-color: #808000\">name</span>=<span style=\"color: #008000; text-decoration-color: #008000\">'fn'</span>,\n",
       "    <span style=\"color: #808000; text-decoration-color: #808000\">stacksize</span>=<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2</span>,\n",
       "    <span style=\"color: #808000; text-decoration-color: #808000\">type</span>=<span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">Function</span><span style=\"font-weight: bold\">(</span><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">Args</span><span style=\"font-weight: bold\">(</span><span style=\"color: #808000; text-decoration-color: #808000\">positional_or_keyword</span>=<span style=\"font-weight: bold\">(</span><span style=\"color: #008000; text-decoration-color: #008000\">'a'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'b'</span><span style=\"font-weight: bold\">)))</span>,\n",
       "    <span style=\"color: #808000; text-decoration-color: #808000\">_additional_args</span>=<span style=\"font-weight: bold\">(</span><span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">Constant</span><span style=\"font-weight: bold\">(</span><span style=\"color: #800080; text-decoration-color: #800080; font-style: italic\">None</span>, <span style=\"color: #808000; text-decoration-color: #808000\">_index_override</span>=<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">0</span><span style=\"font-weight: bold\">)</span>,<span style=\"font-weight: bold\">)</span>\n",
       "<span style=\"font-weight: bold\">)</span>\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\n",
       "\u001b[1mCodeData\u001b[0m\u001b[1m(\u001b[0m\n",
       "    \u001b[1m(\u001b[0m\n",
       "        \u001b[1m(\u001b[0m\n",
       "            \u001b[1mInstruction\u001b[0m\u001b[1m(\u001b[0m'LOAD_FAST', \u001b[1mVarname\u001b[0m\u001b[1m(\u001b[0m'a'\u001b[1m)\u001b[0m, line_number=\u001b[1m7\u001b[0m\u001b[1m)\u001b[0m,\n",
       "            \u001b[1mInstruction\u001b[0m\u001b[1m(\u001b[0m'LOAD_FAST', \u001b[1mVarname\u001b[0m\u001b[1m(\u001b[0m'b'\u001b[1m)\u001b[0m, line_number=\u001b[1m7\u001b[0m\u001b[1m)\u001b[0m,\n",
       "            \u001b[1mInstruction\u001b[0m\u001b[1m(\u001b[0m'BINARY_ADD', line_number=\u001b[1m7\u001b[0m\u001b[1m)\u001b[0m,\n",
       "            \u001b[1mInstruction\u001b[0m\u001b[1m(\u001b[0m'RETURN_VALUE', line_number=\u001b[1m7\u001b[0m\u001b[1m)\u001b[0m\n",
       "        \u001b[1m)\u001b[0m,\n",
       "    \u001b[1m)\u001b[0m,\n",
       "    filename='/tmp/ipykernel_635/3063237183.py',\n",
       "    first_line_number=\u001b[1m6\u001b[0m,\n",
       "    name='fn',\n",
       "    stacksize=\u001b[1m2\u001b[0m,\n",
       "    type=\u001b[1mFunction\u001b[0m\u001b[1m(\u001b[0m\u001b[1mArgs\u001b[0m\u001b[1m(\u001b[0mpositional_or_keyword=\u001b[1m(\u001b[0m'a', 'b'\u001b[1m)\u001b[0m\u001b[1m)\u001b[0m\u001b[1m)\u001b[0m,\n",
       "    _additional_args=\u001b[1m(\u001b[0m\u001b[1mConstant\u001b[0m\u001b[1m(\u001b[0m\u001b[3mNone\u001b[0m, _index_override=\u001b[1m0\u001b[0m\u001b[1m)\u001b[0m,\u001b[1m)\u001b[0m\n",
       "\u001b[1m)\u001b[0m\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Load rich first for prettier output\n",
    "from rich import pretty\n",
    "pretty.install()\n",
    "from code_data import CodeData\n",
    "\n",
    "def fn(a, b):\n",
    "    return a + b\n",
    "\n",
    "cd = CodeData.from_code(fn.__code__)\n",
    "cd"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "00eabb3c",
   "metadata": {},
   "source": [
    "Instead of using Python's built in code object, or the `dis` module, it reduces the amoutn of information to only that which is needed to recreate the code object. So all information about how it happens to be stored on disk, the bytecode offsets for example of each instruction, is ommited, making it simpler to use.\n",
    "\n",
    "### `normalize`\n",
    "\n",
    "We are also able to \"normalize\" the code object, removing pieces of it that are unused. For example, if you have dead code, Python will still include the constants\n",
    "that are present in it, even though there is no way they can be accessed:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "fe39e542",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">\n",
       "<span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">CodeData</span><span style=\"font-weight: bold\">(</span>\n",
       "    <span style=\"font-weight: bold\">(</span>\n",
       "        <span style=\"font-weight: bold\">(</span>\n",
       "            <span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">Instruction</span><span style=\"font-weight: bold\">(</span><span style=\"color: #008000; text-decoration-color: #008000\">'NOP'</span>, <span style=\"color: #808000; text-decoration-color: #808000\">line_number</span>=<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2</span><span style=\"font-weight: bold\">)</span>,\n",
       "            <span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">Instruction</span><span style=\"font-weight: bold\">(</span>\n",
       "                <span style=\"color: #008000; text-decoration-color: #008000\">'LOAD_CONST'</span>,\n",
       "                <span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">Constant</span><span style=\"font-weight: bold\">(</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">1</span>, <span style=\"color: #808000; text-decoration-color: #808000\">_index_override</span>=<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">3</span><span style=\"font-weight: bold\">)</span>,\n",
       "                <span style=\"color: #808000; text-decoration-color: #808000\">line_number</span>=<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">4</span>\n",
       "            <span style=\"font-weight: bold\">)</span>,\n",
       "            <span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">Instruction</span><span style=\"font-weight: bold\">(</span>\n",
       "                <span style=\"color: #008000; text-decoration-color: #008000\">'STORE_FAST'</span>,\n",
       "                <span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">Varname</span><span style=\"font-weight: bold\">(</span><span style=\"color: #008000; text-decoration-color: #008000\">'x'</span>, <span style=\"color: #808000; text-decoration-color: #808000\">_index_override</span>=<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">0</span><span style=\"font-weight: bold\">)</span>,\n",
       "                <span style=\"color: #808000; text-decoration-color: #808000\">line_number</span>=<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">4</span>\n",
       "            <span style=\"font-weight: bold\">)</span>,\n",
       "            <span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">Instruction</span><span style=\"font-weight: bold\">(</span>\n",
       "                <span style=\"color: #008000; text-decoration-color: #008000\">'LOAD_CONST'</span>,\n",
       "                <span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">Constant</span><span style=\"font-weight: bold\">(</span><span style=\"color: #800080; text-decoration-color: #800080; font-style: italic\">None</span>, <span style=\"color: #808000; text-decoration-color: #808000\">_index_override</span>=<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">0</span><span style=\"font-weight: bold\">)</span>,\n",
       "                <span style=\"color: #808000; text-decoration-color: #808000\">line_number</span>=<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">4</span>\n",
       "            <span style=\"font-weight: bold\">)</span>,\n",
       "            <span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">Instruction</span><span style=\"font-weight: bold\">(</span><span style=\"color: #008000; text-decoration-color: #008000\">'RETURN_VALUE'</span>, <span style=\"color: #808000; text-decoration-color: #808000\">line_number</span>=<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">4</span><span style=\"font-weight: bold\">)</span>\n",
       "        <span style=\"font-weight: bold\">)</span>,\n",
       "    <span style=\"font-weight: bold\">)</span>,\n",
       "    <span style=\"color: #808000; text-decoration-color: #808000\">filename</span>=<span style=\"color: #008000; text-decoration-color: #008000\">'/tmp/ipykernel_635/2121495508.py'</span>,\n",
       "    <span style=\"color: #808000; text-decoration-color: #808000\">first_line_number</span>=<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">1</span>,\n",
       "    <span style=\"color: #808000; text-decoration-color: #808000\">name</span>=<span style=\"color: #008000; text-decoration-color: #008000\">'fn'</span>,\n",
       "    <span style=\"color: #808000; text-decoration-color: #808000\">stacksize</span>=<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">1</span>,\n",
       "    <span style=\"color: #808000; text-decoration-color: #808000\">type</span>=<span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">Function</span><span style=\"font-weight: bold\">()</span>,\n",
       "    <span style=\"color: #808000; text-decoration-color: #808000\">_additional_args</span>=<span style=\"font-weight: bold\">(</span>\n",
       "        <span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">Constant</span><span style=\"font-weight: bold\">(</span><span style=\"color: #ff0000; text-decoration-color: #ff0000; font-style: italic\">False</span>, <span style=\"color: #808000; text-decoration-color: #808000\">_index_override</span>=<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">1</span><span style=\"font-weight: bold\">)</span>,\n",
       "        <span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">Constant</span><span style=\"font-weight: bold\">(</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">20</span>, <span style=\"color: #808000; text-decoration-color: #808000\">_index_override</span>=<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2</span><span style=\"font-weight: bold\">)</span>\n",
       "    <span style=\"font-weight: bold\">)</span>\n",
       "<span style=\"font-weight: bold\">)</span>\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\n",
       "\u001b[1mCodeData\u001b[0m\u001b[1m(\u001b[0m\n",
       "    \u001b[1m(\u001b[0m\n",
       "        \u001b[1m(\u001b[0m\n",
       "            \u001b[1mInstruction\u001b[0m\u001b[1m(\u001b[0m'NOP', line_number=\u001b[1m2\u001b[0m\u001b[1m)\u001b[0m,\n",
       "            \u001b[1mInstruction\u001b[0m\u001b[1m(\u001b[0m\n",
       "                'LOAD_CONST',\n",
       "                \u001b[1mConstant\u001b[0m\u001b[1m(\u001b[0m\u001b[1m1\u001b[0m, _index_override=\u001b[1m3\u001b[0m\u001b[1m)\u001b[0m,\n",
       "                line_number=\u001b[1m4\u001b[0m\n",
       "            \u001b[1m)\u001b[0m,\n",
       "            \u001b[1mInstruction\u001b[0m\u001b[1m(\u001b[0m\n",
       "                'STORE_FAST',\n",
       "                \u001b[1mVarname\u001b[0m\u001b[1m(\u001b[0m'x', _index_override=\u001b[1m0\u001b[0m\u001b[1m)\u001b[0m,\n",
       "                line_number=\u001b[1m4\u001b[0m\n",
       "            \u001b[1m)\u001b[0m,\n",
       "            \u001b[1mInstruction\u001b[0m\u001b[1m(\u001b[0m\n",
       "                'LOAD_CONST',\n",
       "                \u001b[1mConstant\u001b[0m\u001b[1m(\u001b[0m\u001b[3mNone\u001b[0m, _index_override=\u001b[1m0\u001b[0m\u001b[1m)\u001b[0m,\n",
       "                line_number=\u001b[1m4\u001b[0m\n",
       "            \u001b[1m)\u001b[0m,\n",
       "            \u001b[1mInstruction\u001b[0m\u001b[1m(\u001b[0m'RETURN_VALUE', line_number=\u001b[1m4\u001b[0m\u001b[1m)\u001b[0m\n",
       "        \u001b[1m)\u001b[0m,\n",
       "    \u001b[1m)\u001b[0m,\n",
       "    filename='/tmp/ipykernel_635/2121495508.py',\n",
       "    first_line_number=\u001b[1m1\u001b[0m,\n",
       "    name='fn',\n",
       "    stacksize=\u001b[1m1\u001b[0m,\n",
       "    type=\u001b[1mFunction\u001b[0m\u001b[1m(\u001b[0m\u001b[1m)\u001b[0m,\n",
       "    _additional_args=\u001b[1m(\u001b[0m\n",
       "        \u001b[1mConstant\u001b[0m\u001b[1m(\u001b[0m\u001b[3mFalse\u001b[0m, _index_override=\u001b[1m1\u001b[0m\u001b[1m)\u001b[0m,\n",
       "        \u001b[1mConstant\u001b[0m\u001b[1m(\u001b[0m\u001b[1m20\u001b[0m, _index_override=\u001b[1m2\u001b[0m\u001b[1m)\u001b[0m\n",
       "    \u001b[1m)\u001b[0m\n",
       "\u001b[1m)\u001b[0m\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "def fn():\n",
    "    if False:\n",
    "        x = 20\n",
    "    x = 1\n",
    "\n",
    "\n",
    "cd = CodeData.from_code(fn.__code__)\n",
    "cd"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "94f46263",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">\n",
       "<span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">CodeData</span><span style=\"font-weight: bold\">(</span>\n",
       "    <span style=\"font-weight: bold\">(</span>\n",
       "        <span style=\"font-weight: bold\">(</span>\n",
       "            <span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">Instruction</span><span style=\"font-weight: bold\">(</span><span style=\"color: #008000; text-decoration-color: #008000\">'NOP'</span>, <span style=\"color: #808000; text-decoration-color: #808000\">line_number</span>=<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2</span><span style=\"font-weight: bold\">)</span>,\n",
       "            <span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">Instruction</span><span style=\"font-weight: bold\">(</span><span style=\"color: #008000; text-decoration-color: #008000\">'LOAD_CONST'</span>, <span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">Constant</span><span style=\"font-weight: bold\">(</span><span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">1</span><span style=\"font-weight: bold\">)</span>, <span style=\"color: #808000; text-decoration-color: #808000\">line_number</span>=<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">4</span><span style=\"font-weight: bold\">)</span>,\n",
       "            <span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">Instruction</span><span style=\"font-weight: bold\">(</span><span style=\"color: #008000; text-decoration-color: #008000\">'STORE_FAST'</span>, <span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">Varname</span><span style=\"font-weight: bold\">(</span><span style=\"color: #008000; text-decoration-color: #008000\">'x'</span><span style=\"font-weight: bold\">)</span>, <span style=\"color: #808000; text-decoration-color: #808000\">line_number</span>=<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">4</span><span style=\"font-weight: bold\">)</span>,\n",
       "            <span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">Instruction</span><span style=\"font-weight: bold\">(</span><span style=\"color: #008000; text-decoration-color: #008000\">'LOAD_CONST'</span>, <span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">Constant</span><span style=\"font-weight: bold\">(</span><span style=\"color: #800080; text-decoration-color: #800080; font-style: italic\">None</span><span style=\"font-weight: bold\">)</span>, <span style=\"color: #808000; text-decoration-color: #808000\">line_number</span>=<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">4</span><span style=\"font-weight: bold\">)</span>,\n",
       "            <span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">Instruction</span><span style=\"font-weight: bold\">(</span><span style=\"color: #008000; text-decoration-color: #008000\">'RETURN_VALUE'</span>, <span style=\"color: #808000; text-decoration-color: #808000\">line_number</span>=<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">4</span><span style=\"font-weight: bold\">)</span>\n",
       "        <span style=\"font-weight: bold\">)</span>,\n",
       "    <span style=\"font-weight: bold\">)</span>,\n",
       "    <span style=\"color: #808000; text-decoration-color: #808000\">filename</span>=<span style=\"color: #008000; text-decoration-color: #008000\">'/tmp/ipykernel_635/2121495508.py'</span>,\n",
       "    <span style=\"color: #808000; text-decoration-color: #808000\">first_line_number</span>=<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">1</span>,\n",
       "    <span style=\"color: #808000; text-decoration-color: #808000\">name</span>=<span style=\"color: #008000; text-decoration-color: #008000\">'fn'</span>,\n",
       "    <span style=\"color: #808000; text-decoration-color: #808000\">stacksize</span>=<span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">1</span>,\n",
       "    <span style=\"color: #808000; text-decoration-color: #808000\">type</span>=<span style=\"color: #800080; text-decoration-color: #800080; font-weight: bold\">Function</span><span style=\"font-weight: bold\">()</span>\n",
       "<span style=\"font-weight: bold\">)</span>\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\n",
       "\u001b[1mCodeData\u001b[0m\u001b[1m(\u001b[0m\n",
       "    \u001b[1m(\u001b[0m\n",
       "        \u001b[1m(\u001b[0m\n",
       "            \u001b[1mInstruction\u001b[0m\u001b[1m(\u001b[0m'NOP', line_number=\u001b[1m2\u001b[0m\u001b[1m)\u001b[0m,\n",
       "            \u001b[1mInstruction\u001b[0m\u001b[1m(\u001b[0m'LOAD_CONST', \u001b[1mConstant\u001b[0m\u001b[1m(\u001b[0m\u001b[1m1\u001b[0m\u001b[1m)\u001b[0m, line_number=\u001b[1m4\u001b[0m\u001b[1m)\u001b[0m,\n",
       "            \u001b[1mInstruction\u001b[0m\u001b[1m(\u001b[0m'STORE_FAST', \u001b[1mVarname\u001b[0m\u001b[1m(\u001b[0m'x'\u001b[1m)\u001b[0m, line_number=\u001b[1m4\u001b[0m\u001b[1m)\u001b[0m,\n",
       "            \u001b[1mInstruction\u001b[0m\u001b[1m(\u001b[0m'LOAD_CONST', \u001b[1mConstant\u001b[0m\u001b[1m(\u001b[0m\u001b[3mNone\u001b[0m\u001b[1m)\u001b[0m, line_number=\u001b[1m4\u001b[0m\u001b[1m)\u001b[0m,\n",
       "            \u001b[1mInstruction\u001b[0m\u001b[1m(\u001b[0m'RETURN_VALUE', line_number=\u001b[1m4\u001b[0m\u001b[1m)\u001b[0m\n",
       "        \u001b[1m)\u001b[0m,\n",
       "    \u001b[1m)\u001b[0m,\n",
       "    filename='/tmp/ipykernel_635/2121495508.py',\n",
       "    first_line_number=\u001b[1m1\u001b[0m,\n",
       "    name='fn',\n",
       "    stacksize=\u001b[1m1\u001b[0m,\n",
       "    type=\u001b[1mFunction\u001b[0m\u001b[1m(\u001b[0m\u001b[1m)\u001b[0m\n",
       "\u001b[1m)\u001b[0m\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "cd.normalize()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9d84f7b2",
   "metadata": {},
   "source": [
    "### JSON Support\n",
    "\n",
    "Since the code object is now a simple data structure, we can serialize it to and from JSON. This provides a nice option if you want to analyze Python bytecode in a different language or save it on disk:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "415dc000",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">\n",
       "<span style=\"font-weight: bold\">{</span>\n",
       "    <span style=\"color: #008000; text-decoration-color: #008000\">'blocks'</span>: <span style=\"font-weight: bold\">[</span>\n",
       "        <span style=\"font-weight: bold\">[</span>\n",
       "            <span style=\"font-weight: bold\">{</span><span style=\"color: #008000; text-decoration-color: #008000\">'name'</span>: <span style=\"color: #008000; text-decoration-color: #008000\">'NOP'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'line_number'</span>: <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2</span><span style=\"font-weight: bold\">}</span>,\n",
       "            <span style=\"font-weight: bold\">{</span>\n",
       "                <span style=\"color: #008000; text-decoration-color: #008000\">'name'</span>: <span style=\"color: #008000; text-decoration-color: #008000\">'LOAD_CONST'</span>,\n",
       "                <span style=\"color: #008000; text-decoration-color: #008000\">'arg'</span>: <span style=\"font-weight: bold\">{</span><span style=\"color: #008000; text-decoration-color: #008000\">'constant'</span>: <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">1</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'_index_override'</span>: <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">3</span><span style=\"font-weight: bold\">}</span>,\n",
       "                <span style=\"color: #008000; text-decoration-color: #008000\">'line_number'</span>: <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">4</span>\n",
       "            <span style=\"font-weight: bold\">}</span>,\n",
       "            <span style=\"font-weight: bold\">{</span>\n",
       "                <span style=\"color: #008000; text-decoration-color: #008000\">'name'</span>: <span style=\"color: #008000; text-decoration-color: #008000\">'STORE_FAST'</span>,\n",
       "                <span style=\"color: #008000; text-decoration-color: #008000\">'arg'</span>: <span style=\"font-weight: bold\">{</span><span style=\"color: #008000; text-decoration-color: #008000\">'varname'</span>: <span style=\"color: #008000; text-decoration-color: #008000\">'x'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'_index_override'</span>: <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">0</span><span style=\"font-weight: bold\">}</span>,\n",
       "                <span style=\"color: #008000; text-decoration-color: #008000\">'line_number'</span>: <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">4</span>\n",
       "            <span style=\"font-weight: bold\">}</span>,\n",
       "            <span style=\"font-weight: bold\">{</span>\n",
       "                <span style=\"color: #008000; text-decoration-color: #008000\">'name'</span>: <span style=\"color: #008000; text-decoration-color: #008000\">'LOAD_CONST'</span>,\n",
       "                <span style=\"color: #008000; text-decoration-color: #008000\">'arg'</span>: <span style=\"font-weight: bold\">{</span><span style=\"color: #008000; text-decoration-color: #008000\">'constant'</span>: <span style=\"color: #800080; text-decoration-color: #800080; font-style: italic\">None</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'_index_override'</span>: <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">0</span><span style=\"font-weight: bold\">}</span>,\n",
       "                <span style=\"color: #008000; text-decoration-color: #008000\">'line_number'</span>: <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">4</span>\n",
       "            <span style=\"font-weight: bold\">}</span>,\n",
       "            <span style=\"font-weight: bold\">{</span><span style=\"color: #008000; text-decoration-color: #008000\">'name'</span>: <span style=\"color: #008000; text-decoration-color: #008000\">'RETURN_VALUE'</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'line_number'</span>: <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">4</span><span style=\"font-weight: bold\">}</span>\n",
       "        <span style=\"font-weight: bold\">]</span>\n",
       "    <span style=\"font-weight: bold\">]</span>,\n",
       "    <span style=\"color: #008000; text-decoration-color: #008000\">'filename'</span>: <span style=\"color: #008000; text-decoration-color: #008000\">'/tmp/ipykernel_635/2121495508.py'</span>,\n",
       "    <span style=\"color: #008000; text-decoration-color: #008000\">'first_line_number'</span>: <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">1</span>,\n",
       "    <span style=\"color: #008000; text-decoration-color: #008000\">'name'</span>: <span style=\"color: #008000; text-decoration-color: #008000\">'fn'</span>,\n",
       "    <span style=\"color: #008000; text-decoration-color: #008000\">'stacksize'</span>: <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">1</span>,\n",
       "    <span style=\"color: #008000; text-decoration-color: #008000\">'type'</span>: <span style=\"font-weight: bold\">{}</span>,\n",
       "    <span style=\"color: #008000; text-decoration-color: #008000\">'_additional_args'</span>: <span style=\"font-weight: bold\">[</span>\n",
       "        <span style=\"font-weight: bold\">{</span><span style=\"color: #008000; text-decoration-color: #008000\">'constant'</span>: <span style=\"color: #ff0000; text-decoration-color: #ff0000; font-style: italic\">False</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'_index_override'</span>: <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">1</span><span style=\"font-weight: bold\">}</span>,\n",
       "        <span style=\"font-weight: bold\">{</span><span style=\"color: #008000; text-decoration-color: #008000\">'constant'</span>: <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">20</span>, <span style=\"color: #008000; text-decoration-color: #008000\">'_index_override'</span>: <span style=\"color: #008080; text-decoration-color: #008080; font-weight: bold\">2</span><span style=\"font-weight: bold\">}</span>\n",
       "    <span style=\"font-weight: bold\">]</span>\n",
       "<span style=\"font-weight: bold\">}</span>\n",
       "</pre>\n"
      ],
      "text/plain": [
       "\n",
       "\u001b[1m{\u001b[0m\n",
       "    'blocks': \u001b[1m[\u001b[0m\n",
       "        \u001b[1m[\u001b[0m\n",
       "            \u001b[1m{\u001b[0m'name': 'NOP', 'line_number': \u001b[1m2\u001b[0m\u001b[1m}\u001b[0m,\n",
       "            \u001b[1m{\u001b[0m\n",
       "                'name': 'LOAD_CONST',\n",
       "                'arg': \u001b[1m{\u001b[0m'constant': \u001b[1m1\u001b[0m, '_index_override': \u001b[1m3\u001b[0m\u001b[1m}\u001b[0m,\n",
       "                'line_number': \u001b[1m4\u001b[0m\n",
       "            \u001b[1m}\u001b[0m,\n",
       "            \u001b[1m{\u001b[0m\n",
       "                'name': 'STORE_FAST',\n",
       "                'arg': \u001b[1m{\u001b[0m'varname': 'x', '_index_override': \u001b[1m0\u001b[0m\u001b[1m}\u001b[0m,\n",
       "                'line_number': \u001b[1m4\u001b[0m\n",
       "            \u001b[1m}\u001b[0m,\n",
       "            \u001b[1m{\u001b[0m\n",
       "                'name': 'LOAD_CONST',\n",
       "                'arg': \u001b[1m{\u001b[0m'constant': \u001b[3mNone\u001b[0m, '_index_override': \u001b[1m0\u001b[0m\u001b[1m}\u001b[0m,\n",
       "                'line_number': \u001b[1m4\u001b[0m\n",
       "            \u001b[1m}\u001b[0m,\n",
       "            \u001b[1m{\u001b[0m'name': 'RETURN_VALUE', 'line_number': \u001b[1m4\u001b[0m\u001b[1m}\u001b[0m\n",
       "        \u001b[1m]\u001b[0m\n",
       "    \u001b[1m]\u001b[0m,\n",
       "    'filename': '/tmp/ipykernel_635/2121495508.py',\n",
       "    'first_line_number': \u001b[1m1\u001b[0m,\n",
       "    'name': 'fn',\n",
       "    'stacksize': \u001b[1m1\u001b[0m,\n",
       "    'type': \u001b[1m{\u001b[0m\u001b[1m}\u001b[0m,\n",
       "    '_additional_args': \u001b[1m[\u001b[0m\n",
       "        \u001b[1m{\u001b[0m'constant': \u001b[3mFalse\u001b[0m, '_index_override': \u001b[1m1\u001b[0m\u001b[1m}\u001b[0m,\n",
       "        \u001b[1m{\u001b[0m'constant': \u001b[1m20\u001b[0m, '_index_override': \u001b[1m2\u001b[0m\u001b[1m}\u001b[0m\n",
       "    \u001b[1m]\u001b[0m\n",
       "\u001b[1m}\u001b[0m\n"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "code_json = cd.to_json_data()\n",
    "assert CodeData.from_json_data(code_json) == cd\n",
    "\n",
    "code_json"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6b4845a9",
   "metadata": {},
   "source": [
    "## Command Line\n",
    "\n",
    "We provide a CLI command `python-code-data` which is useful for debugging or introspecting code objects from the command line.\n",
    "\n",
    "It contains many of the same\n",
    "flags to load Python code as the default Python CLI, including from a string (`-c`),\n",
    "from a module (`-m`), or from a path (`<file name>`). It also includes a way to\n",
    "load a string from Python code to eval it first, which is useful for generating\n",
    "test cases on the CLI of program strings."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "d14d260b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "usage: python-code-data [-h] [-c cmd] [-e eval] [-m mod] [--dis] [--dis-after]\r\n",
      "                        [--source] [--no-normalize] [--json]\r\n",
      "                        [file]\r\n",
      "\r\n",
      "Inspect Python code objects.\r\n",
      "\r\n",
      "positional arguments:\r\n",
      "  file            path to Python program\r\n",
      "\r\n",
      "options:\r\n",
      "  -h, --help      show this help message and exit\r\n",
      "  -c cmd          program passed in as string\r\n",
      "  -e eval         string evalled to make program\r\n",
      "  -m mod          python library\r\n",
      "  --dis           print Python's dis analysis\r\n",
      "  --dis-after     print Python's dis analysis after round tripping to code-\r\n",
      "                  data, for testing\r\n",
      "  --source        print the source code\r\n",
      "  --no-normalize  don't normalize code data before printing\r\n",
      "  --json          Print the JSON represenation of the code data as well\r\n"
     ]
    }
   ],
   "source": [
    "! python-code-data -h"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "598010d2",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[1mCodeData\u001b[0m\u001b[1m(\u001b[0m\r\n",
      "    \u001b[1m(\u001b[0m\r\n",
      "        \u001b[1m(\u001b[0m\r\n",
      "            \u001b[1mInstruction\u001b[0m\u001b[1m(\u001b[0m'LOAD_NAME', \u001b[1mName\u001b[0m\u001b[1m(\u001b[0m'y'\u001b[1m)\u001b[0m, line_number=\u001b[1m1\u001b[0m\u001b[1m)\u001b[0m,\r\n",
      "            \u001b[1mInstruction\u001b[0m\u001b[1m(\u001b[0m'POP_JUMP_IF_FALSE', \u001b[1mJump\u001b[0m\u001b[1m(\u001b[0m\u001b[1m1\u001b[0m\u001b[1m)\u001b[0m, line_number=\u001b[1m1\u001b[0m\u001b[1m)\u001b[0m,\r\n",
      "            \u001b[1mInstruction\u001b[0m\u001b[1m(\u001b[0m'LOAD_NAME', \u001b[1mName\u001b[0m\u001b[1m(\u001b[0m'x'\u001b[1m)\u001b[0m, line_number=\u001b[1m1\u001b[0m\u001b[1m)\u001b[0m,\r\n",
      "            \u001b[1mInstruction\u001b[0m\u001b[1m(\u001b[0m'POP_TOP', line_number=\u001b[1m1\u001b[0m\u001b[1m)\u001b[0m,\r\n",
      "            \u001b[1mInstruction\u001b[0m\u001b[1m(\u001b[0m'LOAD_CONST', \u001b[1mConstant\u001b[0m\u001b[1m(\u001b[0m\u001b[3mNone\u001b[0m\u001b[1m)\u001b[0m, line_number=\u001b[1m1\u001b[0m\u001b[1m)\u001b[0m,\r\n",
      "            \u001b[1mInstruction\u001b[0m\u001b[1m(\u001b[0m'RETURN_VALUE', line_number=\u001b[1m1\u001b[0m\u001b[1m)\u001b[0m\r\n",
      "        \u001b[1m)\u001b[0m,\r\n",
      "        \u001b[1m(\u001b[0m\r\n",
      "            \u001b[1mInstruction\u001b[0m\u001b[1m(\u001b[0m'LOAD_NAME', \u001b[1mName\u001b[0m\u001b[1m(\u001b[0m'z'\u001b[1m)\u001b[0m, line_number=\u001b[1m1\u001b[0m\u001b[1m)\u001b[0m,\r\n",
      "            \u001b[1mInstruction\u001b[0m\u001b[1m(\u001b[0m'POP_TOP', line_number=\u001b[1m1\u001b[0m\u001b[1m)\u001b[0m,\r\n",
      "            \u001b[1mInstruction\u001b[0m\u001b[1m(\u001b[0m'LOAD_CONST', \u001b[1mConstant\u001b[0m\u001b[1m(\u001b[0m\u001b[3mNone\u001b[0m\u001b[1m)\u001b[0m, line_number=\u001b[1m1\u001b[0m\u001b[1m)\u001b[0m,\r\n",
      "            \u001b[1mInstruction\u001b[0m\u001b[1m(\u001b[0m'RETURN_VALUE', line_number=\u001b[1m1\u001b[0m\u001b[1m)\u001b[0m\r\n",
      "        \u001b[1m)\u001b[0m\r\n",
      "    \u001b[1m)\u001b[0m,\r\n",
      "    filename='<string>',\r\n",
      "    first_line_number=\u001b[1m1\u001b[0m,\r\n",
      "    name='<module>',\r\n",
      "    stacksize=\u001b[1m1\u001b[0m\r\n",
      "\u001b[1m)\u001b[0m\r\n"
     ]
    }
   ],
   "source": [
    "! python-code-data -c 'x if y else z'"
   ]
  }
 ],
 "metadata": {
  "jupytext": {
   "cell_metadata_filter": "-all",
   "formats": "md:myst",
   "text_representation": {
    "extension": ".md",
    "format_name": "myst",
    "format_version": 0.13,
    "jupytext_version": "1.11.5"
   }
  },
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.4"
  },
  "source_map": [
   14,
   24,
   35,
   44,
   55,
   57,
   63,
   68,
   80,
   84
  ]
 },
 "nbformat": 4,
 "nbformat_minor": 5
}