title: How to fully disassemble Python source
body: <p>I have been playing with the <code>dis</code> library to disassemble some Python source code, but I see that this does not recurse into functions or classes:</p>
  
  <pre><code>import dis
  
  source_py = "test.py"
  
  with open(source_py) as f_source:
      source_code = f_source.read()
  
  byte_code = compile(source_code, source_py, "exec")
  dis.dis(byte_code)
  </code></pre>
  
  <p>All I see are entries such as:</p>
  
  <pre><code> 54         456 LOAD_CONST              63 (&lt;code object foo at 022C9458, file "test.py", line 54&gt;)
              459 MAKE_FUNCTION            0
              462 STORE_NAME              20 (foo)
  </code></pre>
  
  <p>If the source file had a function <code>foo()</code>, I could obviously add something like the following to the sourcefile:</p>
  
  <pre><code>dis.dis(foo)
  </code></pre>
  
  <p>I cannot figure out how to do this without changing the source file and executing it. I would like to be able to extract the pertinent bytes from the compiled <code>byte_code</code> and pass them to <code>dis.dis()</code>.</p>
  
  <pre><code>def sub_byte_code(byte_code, function_or_class_name):
      sub_byte_code = xxxxxx
      dis.dis(sub_byte_code)
  </code></pre>
  
  <p>I have considered wrapping the source code and executing <code>dis.dis()</code> as follows but I do not wish to execute the script:</p>
  
  <pre><code>source_code_dis = "import dis\n%s\ndis.dis(foo)\n" % (source_code)
  exec(source_code_dis)
  </code></pre>
  
  <p>Is there perhaps a trick to calling it? e.g. <code>dis.dis(byte_code, recurse=True)</code></p>