Skip to content

Commit 891f65e

Browse files
committed
Sync with trepan3k
1 parent 4d5e729 commit 891f65e

1 file changed

Lines changed: 44 additions & 23 deletions

File tree

trepan/lib/bytecode.py

Lines changed: 44 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# -*- coding: utf-8 -*-
2-
# Copyright (C) 2009, 2012-2013 Rocky Bernstein <rocky@gnu.org>
2+
#
3+
# Copyright (C) 2009, 2012-2013, 2020, 2023-2024 Rocky Bernstein
4+
# <rocky@gnu.org>
35
#
46
# This program is free software: you can redistribute it and/or modify
57
# it under the terms of the GNU General Public License as published by
@@ -13,29 +15,34 @@
1315
#
1416
# You should have received a copy of the GNU General Public License
1517
# along with this program. If not, see <http://www.gnu.org/licenses/>.
16-
'''Bytecode instruction routines'''
18+
"""Bytecode instruction routines"""
19+
20+
import re
21+
22+
from opcode import HAVE_ARGUMENT, opname
23+
from xdis import PYTHON_VERSION_TRIPLE, get_opcode_module
1724

18-
import dis, re
19-
from opcode import opname, HAVE_ARGUMENT
25+
opcode_module = get_opcode_module(PYTHON_VERSION_TRIPLE)
2026

2127

2228
def op_at_code_loc(code, loc):
2329
try:
2430
op = ord(code[loc])
2531
except IndexError:
26-
return 'got IndexError'
32+
return "got IndexError"
2733
return opname[op]
2834

2935

3036
def op_at_frame(frame, loc=None):
3137
code = frame.f_code.co_code
32-
if loc is None: loc = frame.f_lasti
38+
if loc is None:
39+
loc = frame.f_lasti
3340
return op_at_code_loc(code, loc)
3441

3542

3643
def next_opcode(code, offset):
37-
'''Return the next opcode and offset as a tuple. Tuple (-100,
38-
-1000) is returned when reaching the end.'''
44+
"""Return the next opcode and offset as a tuple. Tuple (-100,
45+
-1000) is returned when reaching the end."""
3946
n = len(code)
4047
while offset < n:
4148
c = code[offset]
@@ -51,8 +58,9 @@ def next_opcode(code, offset):
5158

5259

5360
def next_linestart(co, offset, count=1):
54-
linestarts = dict(dis.findlinestarts(co))
5561
code = co.co_code
62+
63+
linestarts = dict(opcode_module.findlinestarts(co))
5664
# n = len(code)
5765
# contains_cond_jump = False
5866
for op, offset in next_opcode(code, offset):
@@ -62,13 +70,15 @@ def next_linestart(co, offset, count=1):
6270
return linestarts[offset]
6371
pass
6472
pass
73+
6574
return -1000
6675

6776

6877
def stmt_contains_opcode(co, lineno, query_opcode):
69-
linestarts = dict(dis.findlinestarts(co))
78+
linestarts = dict(opcode_module.findlinestarts(co))
7079
code = co.co_code
7180
found_start = False
81+
offset = 0
7282
for offset, start_line in list(linestarts.items()):
7383
if start_line == lineno:
7484
found_start = True
@@ -77,40 +87,50 @@ def stmt_contains_opcode(co, lineno, query_opcode):
7787
if not found_start:
7888
return False
7989
for op, offset in next_opcode(code, offset):
80-
if -1000 == offset or linestarts.get(offset): return False
90+
if -1000 == offset or linestarts.get(offset):
91+
return False
8192
opcode = opname[op]
8293
# debug: print opcode
8394
if query_opcode == opcode:
8495
return True
8596
pass
8697
return False
8798

88-
_re_def_str = r'^\s*def\s'
99+
100+
_re_def_str = r"^\s*def\s"
89101
_re_def = re.compile(_re_def_str)
90102

91103

92104
def is_def_stmt(line, frame):
93105
"""Return True if we are looking at a def statement"""
94106
# Should really also check that operand of 'LOAD_CONST' is a code object
95-
return (line and _re_def.match(line) and op_at_frame(frame)=='LOAD_CONST'
96-
and stmt_contains_opcode(frame.f_code, frame.f_lineno,
97-
'MAKE_FUNCTION'))
107+
return (
108+
line
109+
and _re_def.match(line)
110+
and op_at_frame(frame) == "LOAD_CONST"
111+
and stmt_contains_opcode(frame.f_code, frame.f_lineno, "MAKE_FUNCTION")
112+
)
113+
98114

99-
_re_class = re.compile(r'^\s*class\s')
115+
_re_class = re.compile(r"^\s*class\s")
100116

101117

102118
def is_class_def(line, frame):
103119
"""Return True if we are looking at a class definition statement"""
104-
return (line and _re_class.match(line)
105-
and stmt_contains_opcode(frame.f_code, frame.f_lineno,
106-
'BUILD_CLASS'))
120+
return (
121+
line
122+
and _re_class.match(line)
123+
and stmt_contains_opcode(frame.f_code, frame.f_lineno, "BUILD_CLASS")
124+
)
125+
107126

108127
# Demo stuff above
109-
if __name__=='__main__':
128+
if __name__ == "__main__":
110129
import inspect
111130

112131
def sqr(x):
113132
return x * x
133+
114134
frame = inspect.currentframe()
115135
co = frame.f_code
116136
lineno = frame.f_lineno
@@ -134,13 +154,14 @@ def double(x):
134154
print("op at frame, position 2: %s" % op_at_frame(frame, 2))
135155
print("def statement: x=5?: %s" % is_def_stmt('x=5', frame))
136156
# Not a "def" statement because frame is wrong spot
137-
print(is_def_stmt('def foo():', frame))
157+
print(is_def_stmt("def foo():", frame))
138158

139159
class Foo:
140160
pass
161+
141162
lineno = frame.f_lineno
142-
print('contains BUILD_CLASS %s' % stmt_contains_opcode(co, lineno-2,
163+
print("contains BUILD_CLASS %s" % stmt_contains_opcode(co, lineno-2,
143164
'BUILD_CLASS'))
144-
print('contains BUILD_CLASS %s' % stmt_contains_opcode(co, lineno,
165+
print("contains BUILD_CLASS %s" % stmt_contains_opcode(co, lineno,
145166
'BUILD_CLASS'))
146167
pass

0 commit comments

Comments
 (0)