This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: dis.Bytecode objects should be comparable
Type: enhancement Stage: patch review
Components: Library (Lib) Versions: Python 3.9
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: BTaskaya, steven.daprano
Priority: normal Keywords: patch

Created on 2020-03-08 12:15 by BTaskaya, last changed 2022-04-11 14:59 by admin.

Pull Requests
URL Status Linked Edit
PR 18849 open BTaskaya, 2020-03-08 12:19
Messages (3)
msg363656 - (view) Author: Batuhan Taskaya (BTaskaya) * (Python committer) Date: 2020-03-08 12:15
import dis
>>> dis.Bytecode("print(1)") == dis.Bytecode("print(1)")
False
msg363661 - (view) Author: Steven D'Aprano (steven.daprano) * (Python committer) Date: 2020-03-08 13:32
What does it mean for two Bytecode objects to be equal?

I know what equality means for ints: they have the same numeric value.

I know what equality means for strings: they have the same sequence of Unicode code points.

I have no concept of what it would mean for two Bytecode objects to be equal or unequal. Your patch compares the tuple:

    (codeobj, first_line, current_offset)

but why do you compare those rather than, say, the source code, or the disassembled byte code, or something else?

Before I read your patch, I guested that you would have defined `__eq__` as `self.dis() == other.dis()`.
msg363663 - (view) Author: Batuhan Taskaya (BTaskaya) * (Python committer) Date: 2020-03-08 14:01
Code objects themselves supports equality comparisons, 

>>> compile("print(1)", "<stdin>", "eval") == compile("print(1)", "<stdin>", "eval")
True

So this patch basically compares the underlying code objects with 2 Bytecode specific attribute, first_line and current_offset. So these objects will be equal

>>> import dis
>>> dis.Bytecode("print(1)") == dis.Bytecode("print(1)")
True

but these won't
>>> dis.Bytecode("print(1)") == dis.Bytecode("print(1)", first_line=2)
False
>>> dis.Bytecode("print(1)") == dis.Bytecode("print(1)", current_offset=12)
False

A simple example that would be problamatic in .dis() method is code objects that contains other code objects

import dis

source = "def x(a, b): print(1)"
print(dis.Bytecode(source).dis())
print(dis.Bytecode(source).dis())
print(dis.Bytecode(source).dis() == dis.Bytecode(source).dis())

  1           0 LOAD_CONST               0 (<code object x at !!0x7fd76239aee0!!, file "<disassembly>", line 1>)
              2 LOAD_CONST               1 ('x')
              4 MAKE_FUNCTION            0
              6 STORE_NAME               0 (x)
              8 LOAD_CONST               2 (None)
             10 RETURN_VALUE

  1           0 LOAD_CONST               0 (<code object x at !!0x7fd7623b76c0!!, file "<disassembly>", line 1>)
              2 LOAD_CONST               1 ('x')
              4 MAKE_FUNCTION            0
              6 STORE_NAME               0 (x)
              8 LOAD_CONST               2 (None)
             10 RETURN_VALUE

False
History
Date User Action Args
2022-04-11 14:59:27adminsetgithub: 84083
2020-03-08 14:01:08BTaskayasetmessages: + msg363663
2020-03-08 13:32:30steven.dapranosetnosy: + steven.daprano
messages: + msg363661
2020-03-08 12:19:34BTaskayasetkeywords: + patch
stage: patch review
pull_requests: + pull_request18206
2020-03-08 12:15:59BTaskayacreate