summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorDennis Sweeney <36520290+sweeneyde@users.noreply.github.com>2022-04-28 04:36:34 (GMT)
committerGitHub <noreply@github.com>2022-04-28 04:36:34 (GMT)
commit37c6db60f9ac62b8a80bf04a8146274756ee0da0 (patch)
tree29cc3ac65b9ee6d2246f4efbdf23767749fbd9bd /Lib
parent407c3afe1986f4c43cb0e68e28b90da30eebd738 (diff)
downloadcpython-37c6db60f9ac62b8a80bf04a8146274756ee0da0.zip
cpython-37c6db60f9ac62b8a80bf04a8146274756ee0da0.tar.gz
cpython-37c6db60f9ac62b8a80bf04a8146274756ee0da0.tar.bz2
gh-91869: Fix tracing of specialized instructions with extended args (GH-91945)
Diffstat (limited to 'Lib')
-rw-r--r--Lib/importlib/_bootstrap_external.py2
-rw-r--r--Lib/opcode.py3
-rw-r--r--Lib/test/test_sys_settrace.py42
3 files changed, 46 insertions, 1 deletions
diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py
index 71e1e24..5f67226 100644
--- a/Lib/importlib/_bootstrap_external.py
+++ b/Lib/importlib/_bootstrap_external.py
@@ -416,7 +416,7 @@ _code_type = type(_write_atomic.__code__)
# Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array
# in PC/launcher.c must also be updated.
-MAGIC_NUMBER = (3493).to_bytes(2, 'little') + b'\r\n'
+MAGIC_NUMBER = (3494).to_bytes(2, 'little') + b'\r\n'
_RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c
diff --git a/Lib/opcode.py b/Lib/opcode.py
index 9ee0683..6c38627 100644
--- a/Lib/opcode.py
+++ b/Lib/opcode.py
@@ -264,6 +264,9 @@ _specializations = {
"COMPARE_OP_INT_JUMP",
"COMPARE_OP_STR_JUMP",
],
+ "EXTENDED_ARG": [
+ "EXTENDED_ARG_QUICK",
+ ],
"JUMP_BACKWARD": [
"JUMP_BACKWARD_QUICK",
],
diff --git a/Lib/test/test_sys_settrace.py b/Lib/test/test_sys_settrace.py
index 85d6bdf..b1c8f6f 100644
--- a/Lib/test/test_sys_settrace.py
+++ b/Lib/test/test_sys_settrace.py
@@ -2432,5 +2432,47 @@ output.append(4)
output.append(5)
+class TestExtendedArgs(unittest.TestCase):
+
+ def setUp(self):
+ self.addCleanup(sys.settrace, sys.gettrace())
+ sys.settrace(None)
+
+ def count_traces(self, func):
+ # warmup
+ for _ in range(20):
+ func()
+
+ counts = {"call": 0, "line": 0, "return": 0}
+ def trace(frame, event, arg):
+ counts[event] += 1
+ return trace
+
+ sys.settrace(trace)
+ func()
+ sys.settrace(None)
+
+ return counts
+
+ def test_trace_unpack_long_sequence(self):
+ ns = {}
+ code = "def f():\n (" + "y,\n "*300 + ") = range(300)"
+ exec(code, ns)
+ counts = self.count_traces(ns["f"])
+ self.assertEqual(counts, {'call': 1, 'line': 301, 'return': 1})
+
+ def test_trace_lots_of_globals(self):
+ code = """if 1:
+ def f():
+ return (
+ {}
+ )
+ """.format("\n+\n".join(f"var{i}\n" for i in range(1000)))
+ ns = {f"var{i}": i for i in range(1000)}
+ exec(code, ns)
+ counts = self.count_traces(ns["f"])
+ self.assertEqual(counts, {'call': 1, 'line': 2000, 'return': 1})
+
+
if __name__ == "__main__":
unittest.main()