[Python-checkins] bpo-46422: use `dis.Positions` in `dis.Instruction` (GH-30716)
isidentical
webhook-mailer at python.org
Mon Jan 24 06:09:26 EST 2022
https://github.com/python/cpython/commit/58f3d980989c7346ad792d464c1d749dcec6af63
commit: 58f3d980989c7346ad792d464c1d749dcec6af63
branch: main
author: Nikita Sobolev <mail at sobolevn.me>
committer: isidentical <isidentical at gmail.com>
date: 2022-01-24T14:09:20+03:00
summary:
bpo-46422: use `dis.Positions` in `dis.Instruction` (GH-30716)
Co-authored-by: Batuhan Taskaya <isidentical at gmail.com>
files:
A Misc/NEWS.d/next/Library/2022-01-20-10-35-50.bpo-46422.1UAEHL.rst
M Doc/library/dis.rst
M Lib/dis.py
M Lib/test/test_dis.py
diff --git a/Doc/library/dis.rst b/Doc/library/dis.rst
index ddba668088e4a..793152d9d812c 100644
--- a/Doc/library/dis.rst
+++ b/Doc/library/dis.rst
@@ -316,8 +316,30 @@ details of bytecode instructions as :class:`Instruction` instances:
``True`` if other code jumps to here, otherwise ``False``
+
+ .. data:: positions
+
+ :class:`dis.Positions` object holding the
+ start and end locations that are covered by this instruction.
+
.. versionadded:: 3.4
+ .. versionchanged:: 3.11
+
+ Field ``positions`` is added.
+
+
+.. class:: Positions
+
+ In case the information is not available, some fields might be `None`.
+
+ .. data:: lineno
+ .. data:: end_lineno
+ .. data:: col_offset
+ .. data:: end_col_offset
+
+ .. versionadded:: 3.11
+
The Python compiler currently generates the following bytecode instructions.
diff --git a/Lib/dis.py b/Lib/dis.py
index ac0c6e7f04c45..2462a8434e895 100644
--- a/Lib/dis.py
+++ b/Lib/dis.py
@@ -413,10 +413,7 @@ def _get_instructions_bytes(code, varname_from_oparg=None,
is_jump_target = offset in labels
argval = None
argrepr = ''
- try:
- positions = next(co_positions)
- except StopIteration:
- positions = None
+ positions = Positions(*next(co_positions, ()))
if arg is not None:
# Set argval to the dereferenced value of the argument when
# available, and argrepr to the string representation of argval.
diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py
index 19a4be2c4132b..ee9729ebabf4a 100644
--- a/Lib/test/test_dis.py
+++ b/Lib/test/test_dis.py
@@ -1313,6 +1313,12 @@ def test_co_positions(self):
]
self.assertEqual(positions, expected)
+ named_positions = [
+ (pos.lineno, pos.end_lineno, pos.col_offset, pos.end_col_offset)
+ for pos in positions
+ ]
+ self.assertEqual(named_positions, expected)
+
@requires_debug_ranges()
def test_co_positions_missing_info(self):
code = compile('x, y, z', '<test>', 'exec')
@@ -1320,25 +1326,27 @@ def test_co_positions_missing_info(self):
actual = dis.get_instructions(code_without_column_table)
for instruction in actual:
with self.subTest(instruction=instruction):
- start_line, end_line, start_offset, end_offset = instruction.positions
+ positions = instruction.positions
+ self.assertEqual(len(positions), 4)
if instruction.opname == "RESUME":
continue
- assert start_line == 1
- assert end_line == 1
- assert start_offset is None
- assert end_offset is None
+ self.assertEqual(positions.lineno, 1)
+ self.assertEqual(positions.end_lineno, 1)
+ self.assertIsNone(positions.col_offset)
+ self.assertIsNone(positions.end_col_offset)
code_without_endline_table = code.replace(co_endlinetable=b'')
actual = dis.get_instructions(code_without_endline_table)
for instruction in actual:
with self.subTest(instruction=instruction):
- start_line, end_line, start_offset, end_offset = instruction.positions
+ positions = instruction.positions
+ self.assertEqual(len(positions), 4)
if instruction.opname == "RESUME":
continue
- assert start_line == 1
- assert end_line is None
- assert start_offset is not None
- assert end_offset is not None
+ self.assertEqual(positions.lineno, 1)
+ self.assertIsNone(positions.end_lineno)
+ self.assertIsNotNone(positions.col_offset)
+ self.assertIsNotNone(positions.end_col_offset)
# get_instructions has its own tests above, so can rely on it to validate
# the object oriented API
diff --git a/Misc/NEWS.d/next/Library/2022-01-20-10-35-50.bpo-46422.1UAEHL.rst b/Misc/NEWS.d/next/Library/2022-01-20-10-35-50.bpo-46422.1UAEHL.rst
new file mode 100644
index 0000000000000..831f526359062
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2022-01-20-10-35-50.bpo-46422.1UAEHL.rst
@@ -0,0 +1 @@
+Use ``dis.Positions`` in ``dis.Instruction`` instead of a regular ``tuple``.
More information about the Python-checkins
mailing list