summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorBrandt Bucher <brandt@python.org>2021-11-11 06:56:22 (GMT)
committerGitHub <noreply@github.com>2021-11-11 06:56:22 (GMT)
commit9178f533ff5ea7462a2ca22cfa67afd78dad433b (patch)
tree2341d2dbc7fbee0585e0d37a04c07b07c8036d57 /Lib
parent1cbaa505d007e11c4a1f0d2073d72b6c02c7147c (diff)
downloadcpython-9178f533ff5ea7462a2ca22cfa67afd78dad433b.zip
cpython-9178f533ff5ea7462a2ca22cfa67afd78dad433b.tar.gz
cpython-9178f533ff5ea7462a2ca22cfa67afd78dad433b.tar.bz2
bpo-45636: Merge all numeric operators (GH-29482)
Diffstat (limited to 'Lib')
-rw-r--r--Lib/dis.py4
-rw-r--r--Lib/importlib/_bootstrap_external.py1
-rw-r--r--Lib/opcode.py75
-rw-r--r--Lib/test/test_compile.py38
-rw-r--r--Lib/test/test_dis.py18
-rw-r--r--Lib/test/test_peepholer.py2
6 files changed, 74 insertions, 64 deletions
diff --git a/Lib/dis.py b/Lib/dis.py
index 8b429b5..ac0c6e7 100644
--- a/Lib/dis.py
+++ b/Lib/dis.py
@@ -7,6 +7,7 @@ import io
from opcode import *
from opcode import __all__ as _opcodes_all
+from opcode import _nb_ops
__all__ = ["code_info", "dis", "disassemble", "distb", "disco",
"findlinestarts", "findlabels", "show_code",
@@ -27,6 +28,7 @@ MAKE_FUNCTION = opmap['MAKE_FUNCTION']
MAKE_FUNCTION_FLAGS = ('defaults', 'kwdefaults', 'annotations', 'closure')
LOAD_CONST = opmap['LOAD_CONST']
+BINARY_OP = opmap['BINARY_OP']
def _try_compile(source, name):
"""Attempts to compile the given source, first as an expression and
@@ -446,6 +448,8 @@ def _get_instructions_bytes(code, varname_from_oparg=None,
elif op == MAKE_FUNCTION:
argrepr = ', '.join(s for i, s in enumerate(MAKE_FUNCTION_FLAGS)
if arg & (1<<i))
+ elif op == BINARY_OP:
+ _, argrepr = _nb_ops[arg]
yield Instruction(opname[op], op,
arg, argval, argrepr,
offset, starts_line, is_jump_target, positions)
diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py
index e492dc2..f6f54af6 100644
--- a/Lib/importlib/_bootstrap_external.py
+++ b/Lib/importlib/_bootstrap_external.py
@@ -366,6 +366,7 @@ _code_type = type(_write_atomic.__code__)
# Python 3.11a1 3461 (JUMP_ABSOLUTE must jump backwards)
# Python 3.11a2 3462 (bpo-44511: remove COPY_DICT_WITHOUT_KEYS, change
# MATCH_CLASS and MATCH_KEYS, and add COPY)
+# Python 3.11a3 3463 (Merge numeric BINARY_*/INPLACE_* into BINARY_OP)
#
# MAGIC must change whenever the bytecode emitted by the compiler may no
diff --git a/Lib/opcode.py b/Lib/opcode.py
index 66d5ca7..940e169 100644
--- a/Lib/opcode.py
+++ b/Lib/opcode.py
@@ -67,20 +67,9 @@ def_op('UNARY_NEGATIVE', 11)
def_op('UNARY_NOT', 12)
def_op('UNARY_INVERT', 15)
-def_op('BINARY_MATRIX_MULTIPLY', 16)
-def_op('INPLACE_MATRIX_MULTIPLY', 17)
-def_op('BINARY_POWER', 19)
-def_op('BINARY_MULTIPLY', 20)
-
-def_op('BINARY_MODULO', 22)
-def_op('BINARY_ADD', 23)
-def_op('BINARY_SUBTRACT', 24)
def_op('BINARY_SUBSCR', 25)
-def_op('BINARY_FLOOR_DIVIDE', 26)
-def_op('BINARY_TRUE_DIVIDE', 27)
-def_op('INPLACE_FLOOR_DIVIDE', 28)
-def_op('INPLACE_TRUE_DIVIDE', 29)
+
def_op('GET_LEN', 30)
def_op('MATCH_MAPPING', 31)
def_op('MATCH_SEQUENCE', 32)
@@ -95,21 +84,11 @@ def_op('GET_AITER', 50)
def_op('GET_ANEXT', 51)
def_op('BEFORE_ASYNC_WITH', 52)
def_op('BEFORE_WITH', 53)
-
def_op('END_ASYNC_FOR', 54)
-def_op('INPLACE_ADD', 55)
-def_op('INPLACE_SUBTRACT', 56)
-def_op('INPLACE_MULTIPLY', 57)
-def_op('INPLACE_MODULO', 59)
def_op('STORE_SUBSCR', 60)
def_op('DELETE_SUBSCR', 61)
-def_op('BINARY_LSHIFT', 62)
-def_op('BINARY_RSHIFT', 63)
-def_op('BINARY_AND', 64)
-def_op('BINARY_XOR', 65)
-def_op('BINARY_OR', 66)
-def_op('INPLACE_POWER', 67)
+
def_op('GET_ITER', 68)
def_op('GET_YIELD_FROM_ITER', 69)
def_op('PRINT_EXPR', 70)
@@ -117,11 +96,6 @@ def_op('LOAD_BUILD_CLASS', 71)
def_op('YIELD_FROM', 72)
def_op('GET_AWAITABLE', 73)
def_op('LOAD_ASSERTION_ERROR', 74)
-def_op('INPLACE_LSHIFT', 75)
-def_op('INPLACE_RSHIFT', 76)
-def_op('INPLACE_AND', 77)
-def_op('INPLACE_XOR', 78)
-def_op('INPLACE_OR', 79)
def_op('LIST_TO_TUPLE', 82)
def_op('RETURN_VALUE', 83)
@@ -167,6 +141,7 @@ def_op('CONTAINS_OP', 118)
def_op('RERAISE', 119)
def_op('COPY', 120)
jabs_op('JUMP_IF_NOT_EXC_MATCH', 121)
+def_op('BINARY_OP', 122)
def_op('LOAD_FAST', 124) # Local variable number
haslocal.append(124)
@@ -219,15 +194,43 @@ def_op('CALL_METHOD_KW', 166)
del def_op, name_op, jrel_op, jabs_op
+_nb_ops = [
+ ("NB_ADD", "+"),
+ ("NB_AND", "&"),
+ ("NB_FLOOR_DIVIDE", "//"),
+ ("NB_LSHIFT", "<<"),
+ ("NB_MATRIX_MULTIPLY", "@"),
+ ("NB_MULTIPLY", "*"),
+ ("NB_REMAINDER", "%"),
+ ("NB_OR", "|"),
+ ("NB_POWER", "**"),
+ ("NB_RSHIFT", ">>"),
+ ("NB_SUBTRACT", "-"),
+ ("NB_TRUE_DIVIDE", "/"),
+ ("NB_XOR", "^"),
+ ("NB_INPLACE_ADD", "+="),
+ ("NB_INPLACE_AND", "&="),
+ ("NB_INPLACE_FLOOR_DIVIDE", "//="),
+ ("NB_INPLACE_LSHIFT", "<<="),
+ ("NB_INPLACE_MATRIX_MULTIPLY", "@="),
+ ("NB_INPLACE_MULTIPLY", "*="),
+ ("NB_INPLACE_REMAINDER", "%="),
+ ("NB_INPLACE_OR", "|="),
+ ("NB_INPLACE_POWER", "**="),
+ ("NB_INPLACE_RSHIFT", ">>="),
+ ("NB_INPLACE_SUBTRACT", "-="),
+ ("NB_INPLACE_TRUE_DIVIDE", "/="),
+ ("NB_INPLACE_XOR", "^="),
+]
+
_specialized_instructions = [
- "BINARY_ADD_ADAPTIVE",
- "BINARY_ADD_INT",
- "BINARY_ADD_FLOAT",
- "BINARY_ADD_UNICODE",
- "BINARY_ADD_UNICODE_INPLACE_FAST",
- "BINARY_MULTIPLY_ADAPTIVE",
- "BINARY_MULTIPLY_INT",
- "BINARY_MULTIPLY_FLOAT",
+ "BINARY_OP_ADAPTIVE",
+ "BINARY_OP_ADD_INT",
+ "BINARY_OP_ADD_FLOAT",
+ "BINARY_OP_ADD_UNICODE",
+ "BINARY_OP_INPLACE_ADD_UNICODE",
+ "BINARY_OP_MULTIPLY_INT",
+ "BINARY_OP_MULTIPLY_FLOAT",
"BINARY_SUBSCR_ADAPTIVE",
"BINARY_SUBSCR_LIST_INT",
"BINARY_SUBSCR_TUPLE_INT",
diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py
index 495a223..f72c7ca 100644
--- a/Lib/test/test_compile.py
+++ b/Lib/test/test_compile.py
@@ -1048,15 +1048,17 @@ class TestSourcePositions(unittest.TestCase):
return code, ast_tree
def assertOpcodeSourcePositionIs(self, code, opcode,
- line, end_line, column, end_column):
+ line, end_line, column, end_column, occurrence=1):
for instr, position in zip(dis.Bytecode(code), code.co_positions()):
if instr.opname == opcode:
- self.assertEqual(position[0], line)
- self.assertEqual(position[1], end_line)
- self.assertEqual(position[2], column)
- self.assertEqual(position[3], end_column)
- return
+ occurrence -= 1
+ if not occurrence:
+ self.assertEqual(position[0], line)
+ self.assertEqual(position[1], end_line)
+ self.assertEqual(position[2], column)
+ self.assertEqual(position[3], end_column)
+ return
self.fail(f"Opcode {opcode} not found in code")
@@ -1077,12 +1079,12 @@ class TestSourcePositions(unittest.TestCase):
compiled_code, _ = self.check_positions_against_ast(snippet)
- self.assertOpcodeSourcePositionIs(compiled_code, 'INPLACE_SUBTRACT',
+ self.assertOpcodeSourcePositionIs(compiled_code, 'BINARY_OP',
line=10_000 + 2, end_line=10_000 + 2,
- column=2, end_column=8)
- self.assertOpcodeSourcePositionIs(compiled_code, 'INPLACE_ADD',
+ column=2, end_column=8, occurrence=1)
+ self.assertOpcodeSourcePositionIs(compiled_code, 'BINARY_OP',
line=10_000 + 4, end_line=10_000 + 4,
- column=2, end_column=9)
+ column=2, end_column=9, occurrence=2)
def test_multiline_expression(self):
snippet = """\
@@ -1110,14 +1112,14 @@ f(
compiled_code, _ = self.check_positions_against_ast(snippet)
self.assertOpcodeSourcePositionIs(compiled_code, 'BINARY_SUBSCR',
line=1, end_line=1, column=13, end_column=21)
- self.assertOpcodeSourcePositionIs(compiled_code, 'BINARY_MULTIPLY',
- line=1, end_line=1, column=9, end_column=21)
- self.assertOpcodeSourcePositionIs(compiled_code, 'BINARY_ADD',
- line=1, end_line=1, column=9, end_column=26)
- self.assertOpcodeSourcePositionIs(compiled_code, 'BINARY_MATRIX_MULTIPLY',
- line=1, end_line=1, column=4, end_column=27)
- self.assertOpcodeSourcePositionIs(compiled_code, 'BINARY_SUBTRACT',
- line=1, end_line=1, column=0, end_column=27)
+ self.assertOpcodeSourcePositionIs(compiled_code, 'BINARY_OP',
+ line=1, end_line=1, column=9, end_column=21, occurrence=1)
+ self.assertOpcodeSourcePositionIs(compiled_code, 'BINARY_OP',
+ line=1, end_line=1, column=9, end_column=26, occurrence=2)
+ self.assertOpcodeSourcePositionIs(compiled_code, 'BINARY_OP',
+ line=1, end_line=1, column=4, end_column=27, occurrence=3)
+ self.assertOpcodeSourcePositionIs(compiled_code, 'BINARY_OP',
+ line=1, end_line=1, column=0, end_column=27, occurrence=4)
class TestExpressionStackSize(unittest.TestCase):
diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py
index d0435e4..3b8ebb5 100644
--- a/Lib/test/test_dis.py
+++ b/Lib/test/test_dis.py
@@ -156,7 +156,7 @@ dis_bug1333982 = """\
%3d 12 LOAD_CONST 3 (1)
-%3d 14 BINARY_ADD
+%3d 14 BINARY_OP 0 (+)
16 CALL_FUNCTION 1
18 RAISE_VARARGS 1
""" % (bug1333982.__code__.co_firstlineno + 1,
@@ -226,7 +226,7 @@ expr_str = "x + 1"
dis_expr_str = """\
1 0 LOAD_NAME 0 (x)
2 LOAD_CONST 0 (1)
- 4 BINARY_ADD
+ 4 BINARY_OP 0 (+)
6 RETURN_VALUE
"""
@@ -235,7 +235,7 @@ simple_stmt_str = "x = x + 1"
dis_simple_stmt_str = """\
1 0 LOAD_NAME 0 (x)
2 LOAD_CONST 0 (1)
- 4 BINARY_ADD
+ 4 BINARY_OP 0 (+)
6 STORE_NAME 0 (x)
8 LOAD_CONST 1 (None)
10 RETURN_VALUE
@@ -291,7 +291,7 @@ dis_compound_stmt_str = """\
3 >> 6 LOAD_NAME 0 (x)
8 LOAD_CONST 1 (1)
- 10 INPLACE_ADD
+ 10 BINARY_OP 13 (+=)
12 STORE_NAME 0 (x)
2 14 JUMP_ABSOLUTE 3 (to 6)
@@ -302,7 +302,7 @@ dis_traceback = """\
%3d 2 LOAD_CONST 1 (1)
4 LOAD_CONST 2 (0)
- --> 6 BINARY_TRUE_DIVIDE
+ --> 6 BINARY_OP 11 (/)
8 POP_TOP
%3d 10 LOAD_FAST 1 (tb)
@@ -485,7 +485,7 @@ Disassembly of <code object <listcomp> at 0x..., file "%s", line %d>:
6 STORE_FAST 1 (z)
8 LOAD_DEREF 2 (x)
10 LOAD_FAST 1 (z)
- 12 BINARY_ADD
+ 12 BINARY_OP 0 (+)
14 LIST_APPEND 2
16 JUMP_ABSOLUTE 2 (to 4)
>> 18 RETURN_VALUE
@@ -602,7 +602,7 @@ class DisTests(unittest.TestCase):
s = ['''\
%*d LOAD_FAST 0 (x)
%*d LOAD_CONST 1 (1)
- %*d BINARY_ADD
+ %*d BINARY_OP 0 (+)
%*d STORE_FAST 0 (x)
''' % (w, 8*i, w, 8*i + 2, w, 8*i + 4, w, 8*i + 6)
for i in range(count)]
@@ -1080,7 +1080,7 @@ expected_opinfo_jumpy = [
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=62, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=64, starts_line=13, is_jump_target=False, positions=None),
Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=1, argrepr='1', offset=66, starts_line=None, is_jump_target=False, positions=None),
- Instruction(opname='INPLACE_SUBTRACT', opcode=56, arg=None, argval=None, argrepr='', offset=68, starts_line=None, is_jump_target=False, positions=None),
+ Instruction(opname='BINARY_OP', opcode=122, arg=23, argval=23, argrepr='-=', offset=68, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='STORE_FAST', opcode=125, arg=0, argval='i', argrepr='i', offset=70, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='LOAD_FAST', opcode=124, arg=0, argval='i', argrepr='i', offset=72, starts_line=14, is_jump_target=False, positions=None),
Instruction(opname='LOAD_CONST', opcode=100, arg=3, argval=6, argrepr='6', offset=74, starts_line=None, is_jump_target=False, positions=None),
@@ -1101,7 +1101,7 @@ expected_opinfo_jumpy = [
Instruction(opname='NOP', opcode=9, arg=None, argval=None, argrepr='', offset=104, starts_line=20, is_jump_target=True, positions=None),
Instruction(opname='LOAD_CONST', opcode=100, arg=5, argval=1, argrepr='1', offset=106, starts_line=21, is_jump_target=False, positions=None),
Instruction(opname='LOAD_CONST', opcode=100, arg=7, argval=0, argrepr='0', offset=108, starts_line=None, is_jump_target=False, positions=None),
- Instruction(opname='BINARY_TRUE_DIVIDE', opcode=27, arg=None, argval=None, argrepr='', offset=110, starts_line=None, is_jump_target=False, positions=None),
+ Instruction(opname='BINARY_OP', opcode=122, arg=11, argval=11, argrepr='/', offset=110, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='POP_TOP', opcode=1, arg=None, argval=None, argrepr='', offset=112, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='JUMP_FORWARD', opcode=110, arg=14, argval=144, argrepr='to 144', offset=114, starts_line=None, is_jump_target=False, positions=None),
Instruction(opname='PUSH_EXC_INFO', opcode=35, arg=None, argval=None, argrepr='', offset=116, starts_line=None, is_jump_target=False, positions=None),
diff --git a/Lib/test/test_peepholer.py b/Lib/test/test_peepholer.py
index 9478c47..7086a42b 100644
--- a/Lib/test/test_peepholer.py
+++ b/Lib/test/test_peepholer.py
@@ -424,7 +424,7 @@ class TestTranforms(BytecodeTestCase):
def g()->1+1:
pass
return g
- self.assertNotInBytecode(f, 'BINARY_ADD')
+ self.assertNotInBytecode(f, 'BINARY_OP')
self.check_lnotab(f)
def test_constant_folding(self):