2929import sys
3030import types
3131from collections import deque
32+ from typing import Tuple
3233
3334import xdis
3435from xdis .bytecode import Bytecode
@@ -135,6 +136,7 @@ def disco(
135136 alternate_opmap = None ,
136137 show_source = False ,
137138 is_graal = False ,
139+ methods = tuple (),
138140):
139141 """
140142 disassembles and deparses a given code block 'co'
@@ -160,7 +162,8 @@ def disco(
160162 real_out = out or sys .stdout
161163
162164 if co .co_filename and asm_format != "xasm" :
163- real_out .write (format_code_info (co , version_tuple , is_graal = is_graal ) + "\n " )
165+ if not_filtered (co , methods ):
166+ real_out .write (format_code_info (co , version_tuple , is_graal = is_graal ) + "\n " )
164167 pass
165168
166169 opc = get_opcode (version_tuple , is_pypy , alternate_opmap )
@@ -180,6 +183,7 @@ def disco(
180183 asm_format = asm_format ,
181184 dup_lines = True ,
182185 show_source = show_source ,
186+ methods = methods ,
183187 )
184188
185189
@@ -191,6 +195,7 @@ def disco_loop(
191195 dup_lines = False ,
192196 asm_format = "classic" ,
193197 show_source = False ,
198+ methods = tuple (),
194199):
195200 """Disassembles a queue of code objects. If we discover
196201 another code object which will be found in co_consts, we add
@@ -204,25 +209,26 @@ def disco_loop(
204209
205210 while len (queue ) > 0 :
206211 co = queue .popleft ()
207- if co .co_name not in ("<module>" , "?" ):
208- real_out .write ("\n " + format_code_info (co , version_tuple ) + "\n " )
209-
210- if asm_format == "dis" :
211- assert version_tuple [:2 ] == PYTHON_VERSION_TRIPLE [:2 ], (
212- "dis requires disassembly from the same Python version: "
213- f"Bytecode is for { version_tuple [:2 ]} ; Running:{ PYTHON_VERSION_TRIPLE [:2 ]} "
214- )
215- dis .disassemble (co , lasti = - 1 , file = real_out )
216- else :
217- bytecode = Bytecode (co , opc , dup_lines = dup_lines )
218- real_out .write (
219- bytecode .dis (asm_format = asm_format , show_source = show_source ) + "\n "
220- )
212+ if not_filtered (co , methods ):
213+ if co .co_name not in ("<module>" , "?" ):
214+ real_out .write ("\n " + format_code_info (co , version_tuple ) + "\n " )
215+
216+ if asm_format == "dis" :
217+ assert version_tuple [:2 ] == PYTHON_VERSION_TRIPLE [:2 ], (
218+ "dis requires disassembly from the same Python version: "
219+ f"Bytecode is for { version_tuple [:2 ]} ; Running:{ PYTHON_VERSION_TRIPLE [:2 ]} "
220+ )
221+ dis .disassemble (co , lasti = - 1 , file = real_out )
222+ else :
223+ bytecode = Bytecode (co , opc , dup_lines = dup_lines )
224+ real_out .write (
225+ bytecode .dis (asm_format = asm_format , show_source = show_source ) + "\n "
226+ )
221227
222- if version_tuple >= (3 , 11 ):
223- if bytecode .exception_entries not in (None , []):
224- exception_table = format_exception_table (bytecode , version_tuple )
225- real_out .write (exception_table + "\n " )
228+ if version_tuple >= (3 , 11 ):
229+ if bytecode .exception_entries not in (None , []):
230+ exception_table = format_exception_table (bytecode , version_tuple )
231+ real_out .write (exception_table + "\n " )
226232
227233 for c in co .co_consts :
228234 if iscode (c ):
@@ -312,6 +318,7 @@ def disassemble_file(
312318 asm_format = "classic" ,
313319 alternate_opmap = None ,
314320 show_source = False ,
321+ methods : Tuple [str ] = tuple ()
315322):
316323 """
317324 Disassemble Python byte-code file (.pyc).
@@ -383,6 +390,7 @@ def disassemble_file(
383390 alternate_opmap = alternate_opmap ,
384391 show_source = show_source ,
385392 is_graal = is_graal ,
393+ methods = methods ,
386394 )
387395 # print co.co_filename
388396 return (
@@ -396,13 +404,16 @@ def disassemble_file(
396404 sip_hash ,
397405 )
398406
407+ def not_filtered (co : types .CodeType , methods : tuple ) -> bool :
408+ return len (methods ) == 0 or co .co_name in methods
399409
400410def _test ():
401411 """Simple test program to disassemble a file."""
402412 argc = len (sys .argv )
403413 if argc == 1 :
404414 if xdis .PYTHON3 :
405415 disassemble_file (__file__ )
416+ disassemble_file (__file__ , methods = ("code_uniquify" ,))
406417 else :
407418 sys .stderr .write (f"usage: { __file__ } [-|CPython compiled file [format]]\n " )
408419 sys .exit (2 )
0 commit comments