2727from io import StringIO
2828from linecache import getline
2929from types import CodeType
30- from typing import Iterable , Iterator , Optional , Tuple , Union
30+ from typing import Iterable , Iterator , Optional , Tuple
3131
3232from xdis .cross_dis import (
3333 format_code_info ,
@@ -454,15 +454,8 @@ def next_offset(op: int, opc, offset: int) -> int:
454454
455455
456456def get_instructions_bytes (
457- bytecode ,
457+ code_object ,
458458 opc ,
459- varnames = None ,
460- names = None ,
461- constants = None ,
462- cells = None ,
463- linestarts = None ,
464- line_offset = 0 ,
465- exception_entries = None ,
466459):
467460 """
468461 Iterate over the instructions in a bytecode string.
@@ -472,7 +465,20 @@ def get_instructions_bytes(
472465 e.g., variable names, constants, can be specified using optional
473466 arguments.
474467 """
468+
469+ bytecode : bytes = code_object .co_code
470+ constants : tuple = code_object .co_consts
471+ names : tuple = code_object .co_names
472+ varnames : tuple = code_object .co_varnames
473+ cells : tuple = code_object .co_cells if hasattr (code_object , "co_cells" ) else tuple ()
474+ exception_entries = code_object .exception_entries if hasattr (code_object , "exception_entries" ) else tuple ()
475+ # freevars: tuple = code_object.co_freevars
476+
475477 labels = opc .findlabels (bytecode , opc )
478+ if hasattr (opc , "findlinestarts" ):
479+ line_starts = dict (opc .findlinestarts (code_object , dup_lines = True ))
480+ else :
481+ line_starts = None
476482
477483 # PERFORMANCE FIX: Build exception labels ONCE, not on every iteration
478484 # The old code was O(n^2) because it rebuilt the same list every call to
@@ -497,7 +503,7 @@ def get_instructions_bytes(
497503 names = names ,
498504 constants = constants ,
499505 cells = cells ,
500- linestarts = linestarts ,
506+ linestarts = line_starts ,
501507 line_offset = 0 ,
502508 exception_entries = exception_entries ,
503509 labels = labels ,
@@ -552,17 +558,7 @@ def __init__(
552558
553559 def __iter__ (self ):
554560 co = self .codeobj
555- return get_instructions_bytes (
556- co .co_code ,
557- self .opc ,
558- co .co_varnames ,
559- co .co_names ,
560- co .co_consts ,
561- self ._cell_names ,
562- self ._linestarts ,
563- line_offset = self ._line_offset ,
564- exception_entries = self .exception_entries ,
565- )
561+ return get_instructions_bytes (co , self .opc )
566562
567563 def __repr__ (self ) -> str :
568564 return f"{ self .__class__ .__name__ } ({ self ._original_object !r} )"
@@ -596,10 +592,8 @@ def dis(
596592 offset = - 1
597593 output = StringIO ()
598594 if self .opc .version_tuple > (2 , 0 ):
599- cells = self ._cell_names
600595 line_starts = self ._linestarts
601596 else :
602- cells = None
603597 line_starts = None
604598
605599 first_line_number = co .co_firstlineno if hasattr (co , "co_firstlineno" ) else None
@@ -610,17 +604,8 @@ def dis(
610604 if isinstance (filename , UnicodeForPython3 ):
611605 filename = str (filename )
612606
613- if isinstance (co .co_code , str ):
614- co_code = co .co_code .encode ('latin-1' )
615- else :
616- co_code = co .co_code
617-
618607 self .disassemble_bytes (
619- co_code ,
620- varnames = co .co_varnames ,
621- names = co .co_names ,
622- constants = co .co_consts ,
623- cells = cells ,
608+ co ,
624609 line_starts = line_starts ,
625610 line_offset = self ._line_offset ,
626611 file = output ,
@@ -629,7 +614,6 @@ def dis(
629614 filename = filename ,
630615 show_source = show_source ,
631616 first_line_number = first_line_number ,
632- exception_entries = self .exception_entries ,
633617 )
634618 return output .getvalue ()
635619
@@ -647,20 +631,15 @@ def distb(self, tb=None) -> None:
647631
648632 def disassemble_bytes (
649633 self ,
650- bytecode : Union [ CodeType , bytes , str ] ,
634+ code_object : CodeType ,
651635 lasti : int = - 1 ,
652- varnames = None ,
653- names = None ,
654- constants = None ,
655- cells = None ,
656636 line_starts = None ,
657637 file = sys .stdout ,
658638 line_offset = 0 ,
659639 asm_format = "classic" ,
660640 filename : Optional [str ] = None ,
661641 show_source = True ,
662642 first_line_number : Optional [int ] = None ,
663- exception_entries = None ,
664643 ) -> list :
665644 # Omit the line number column entirely if we have no line number info
666645 show_lineno = line_starts is not None or self .opc .version_tuple < (2 , 3 )
@@ -703,17 +682,7 @@ def show_source_text(line_number: Optional[int]) -> None:
703682 else :
704683 get_instructions_fn = get_instructions_bytes
705684
706- for instr in get_instructions_fn (
707- bytecode ,
708- self .opc ,
709- varnames ,
710- names ,
711- constants ,
712- cells ,
713- line_starts ,
714- line_offset = line_offset ,
715- exception_entries = exception_entries ,
716- ):
685+ for instr in get_instructions_fn (code_object , self .opc ):
717686 # Python 1.x into early 2.0 uses SET_LINENO
718687 if last_was_set_lineno :
719688 instr = Instruction (
@@ -789,7 +758,7 @@ def show_source_text(line_number: Optional[int]) -> None:
789758 new_source_line = show_lineno and (
790759 extended_arg_starts_line
791760 or instr .starts_line is not None
792- and instr .offset > 0
761+ and instr .offset >= 0
793762 )
794763 if new_source_line :
795764 file .write ("\n " )
@@ -833,7 +802,7 @@ def show_source_text(line_number: Optional[int]) -> None:
833802 pass
834803 return instructions
835804
836- def get_instructions (self , x , first_line = None ):
805+ def get_instructions (self , x ):
837806 """Iterator for the opcodes in methods, functions or code
838807
839808 Generates a series of Instruction named tuples giving the details of
@@ -845,22 +814,7 @@ def get_instructions(self, x, first_line=None):
845814 the disassembled code object.
846815 """
847816 co = get_code_object (x )
848- cell_names = co .co_cellvars + co .co_freevars
849- line_starts = dict (self .opc .findlinestarts (co ))
850- if first_line is not None :
851- line_offset = first_line - co .co_firstlineno
852- else :
853- line_offset = 0
854- return get_instructions_bytes (
855- co .co_code ,
856- self .opc ,
857- co .co_varnames ,
858- co .co_names ,
859- co .co_consts ,
860- cell_names ,
861- line_starts ,
862- line_offset ,
863- )
817+ return get_instructions_bytes (co .co_code , self .opc )
864818
865819
866820def list2bytecode (
0 commit comments