]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-104686: Fix tracing for decorated classes (#104708)
authorJelle Zijlstra <jelle.zijlstra@gmail.com>
Sun, 21 May 2023 23:20:19 +0000 (16:20 -0700)
committerGitHub <noreply@github.com>
Sun, 21 May 2023 23:20:19 +0000 (16:20 -0700)
Lib/test/test_sys_settrace.py
Python/compile.c

index 0571919066bb739835e0549ad2bee7bcdc215b8b..5603c3cdbf3c5e1db754c9a51c2dca0d7243fdf7 100644 (file)
@@ -1524,6 +1524,52 @@ class TraceTestCase(unittest.TestCase):
              (3, 'return'),
              (1, 'return')])
 
+    def test_class_creation_with_decorator(self):
+        def func():
+            def decorator(arg):
+                def _dec(c):
+                    return c
+                return _dec
+
+            @decorator(6)
+            @decorator(
+                len([8]),
+            )
+            class MyObject:
+                pass
+
+        self.run_and_compare(func, [
+            (0, 'call'),
+            (1, 'line'),
+            (6, 'line'),
+            (1, 'call'),
+            (2, 'line'),
+            (4, 'line'),
+            (4, 'return'),
+            (7, 'line'),
+            (8, 'line'),
+            (7, 'line'),
+            (1, 'call'),
+            (2, 'line'),
+            (4, 'line'),
+            (4, 'return'),
+            (10, 'line'),
+            (6, 'call'),
+            (6, 'line'),
+            (11, 'line'),
+            (11, 'return'),
+            (7, 'line'),
+            (2, 'call'),
+            (3, 'line'),
+            (3, 'return'),
+            (6, 'line'),
+            (2, 'call'),
+            (3, 'line'),
+            (3, 'return'),
+            (10, 'line'),
+            (10, 'return'),
+        ])
+
     @support.cpython_only
     def test_no_line_event_after_creating_generator(self):
         # Spurious line events before call events only show up with C tracer
index cfe8224a7e27c63eabb282921c87d481f9342b26..e4dc9729b694b0b4a78fc20453f425806d67399d 100644 (file)
@@ -2486,6 +2486,10 @@ compiler_class_body(struct compiler *c, stmt_ty s, int firstlineno)
     }
 
     /* 2. load the 'build_class' function */
+
+    // these instructions should be attributed to the class line,
+    // not a decorator line
+    loc = LOC(s);
     ADDOP(c, loc, PUSH_NULL);
     ADDOP(c, loc, LOAD_BUILD_CLASS);