Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 585c93d

Browse files
Issue #26733: Disassembling a class now disassembles class and static methods.
Patch by Xiang Zhang.
1 parent 21ce717 commit 585c93d

4 files changed

Lines changed: 60 additions & 8 deletions

File tree

Doc/library/dis.rst

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -139,11 +139,11 @@ operation is being performed, so the intermediate analysis object isn't useful:
139139
Disassemble the *x* object. *x* can denote either a module, a class, a
140140
method, a function, a generator, a code object, a string of source code or
141141
a byte sequence of raw bytecode. For a module, it disassembles all functions.
142-
For a class, it disassembles all methods. For a code object or sequence of
143-
raw bytecode, it prints one line per bytecode instruction. Strings are first
144-
compiled to code objects with the :func:`compile` built-in function before being
145-
disassembled. If no object is provided, this function disassembles the last
146-
traceback.
142+
For a class, it disassembles all methods (including class and static methods).
143+
For a code object or sequence of raw bytecode, it prints one line per bytecode
144+
instruction. Strings are first compiled to code objects with the :func:`compile`
145+
built-in function before being disassembled. If no object is provided, this
146+
function disassembles the last traceback.
147147

148148
The disassembly is written as text to the supplied *file* argument if
149149
provided and to ``sys.stdout`` otherwise.

Lib/dis.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
"get_instructions", "Instruction", "Bytecode"] + _opcodes_all
1414
del _opcodes_all
1515

16-
_have_code = (types.MethodType, types.FunctionType, types.CodeType, type)
16+
_have_code = (types.MethodType, types.FunctionType, types.CodeType,
17+
classmethod, staticmethod, type)
1718

1819
def _try_compile(source, name):
1920
"""Attempts to compile the given source, first as an expression and

Lib/test/test_dis.py

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,14 @@ class _C:
3030
def __init__(self, x):
3131
self.x = x == 1
3232

33+
@staticmethod
34+
def sm(x):
35+
x = x == 1
36+
37+
@classmethod
38+
def cm(cls, x):
39+
cls.x = x == 1
40+
3341
dis_c_instance_method = """\
3442
%3d 0 LOAD_FAST 1 (x)
3543
3 LOAD_CONST 1 (1)
@@ -50,6 +58,37 @@ def __init__(self, x):
5058
18 RETURN_VALUE
5159
"""
5260

61+
dis_c_class_method = """\
62+
%3d 0 LOAD_FAST 1 (x)
63+
3 LOAD_CONST 1 (1)
64+
6 COMPARE_OP 2 (==)
65+
9 LOAD_FAST 0 (cls)
66+
12 STORE_ATTR 0 (x)
67+
15 LOAD_CONST 0 (None)
68+
18 RETURN_VALUE
69+
""" % (_C.cm.__code__.co_firstlineno + 2,)
70+
71+
dis_c_static_method = """\
72+
%3d 0 LOAD_FAST 0 (x)
73+
3 LOAD_CONST 1 (1)
74+
6 COMPARE_OP 2 (==)
75+
9 STORE_FAST 0 (x)
76+
12 LOAD_CONST 0 (None)
77+
15 RETURN_VALUE
78+
""" % (_C.sm.__code__.co_firstlineno + 2,)
79+
80+
# Class disassembling info has an extra newline at end.
81+
dis_c = """\
82+
Disassembly of %s:
83+
%s
84+
Disassembly of %s:
85+
%s
86+
Disassembly of %s:
87+
%s
88+
""" % (_C.__init__.__name__, dis_c_instance_method,
89+
_C.cm.__name__, dis_c_class_method,
90+
_C.sm.__name__, dis_c_static_method)
91+
5392
def _f(a):
5493
print(a)
5594
return 1
@@ -311,13 +350,22 @@ def test_disassemble_str(self):
311350
def test_disassemble_bytes(self):
312351
self.do_disassembly_test(_f.__code__.co_code, dis_f_co_code)
313352

314-
def test_disassemble_method(self):
353+
def test_disassemble_class(self):
354+
self.do_disassembly_test(_C, dis_c)
355+
356+
def test_disassemble_instance_method(self):
315357
self.do_disassembly_test(_C(1).__init__, dis_c_instance_method)
316358

317-
def test_disassemble_method_bytes(self):
359+
def test_disassemble_instance_method_bytes(self):
318360
method_bytecode = _C(1).__init__.__code__.co_code
319361
self.do_disassembly_test(method_bytecode, dis_c_instance_method_bytes)
320362

363+
def test_disassemble_static_method(self):
364+
self.do_disassembly_test(_C.sm, dis_c_static_method)
365+
366+
def test_disassemble_class_method(self):
367+
self.do_disassembly_test(_C.cm, dis_c_class_method)
368+
321369
def test_disassemble_generator(self):
322370
gen_func_disas = self.get_disassembly(_g) # Disassemble generator function
323371
gen_disas = self.get_disassembly(_g(1)) # Disassemble generator itself

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,9 @@ Core and Builtins
107107
Library
108108
-------
109109

110+
- Issue #26733: Disassembling a class now disassembles class and static methods.
111+
Patch by Xiang Zhang.
112+
110113
- Issue #26801: Fix error handling in :func:`shutil.get_terminal_size`, catch
111114
:exc:`AttributeError` instead of :exc:`NameError`. Patch written by Emanuel
112115
Barry.

0 commit comments

Comments
 (0)