From 4b2ec1e815f2dcd85c4ced868ae46909abfcdad9 Mon Sep 17 00:00:00 2001 From: PuQing Date: Sun, 22 Jun 2025 18:48:29 +0800 Subject: [PATCH 1/8] fix instructions in __annotate__ have incorrect code positions --- Python/codegen.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Python/codegen.c b/Python/codegen.c index 27fe8e1957b2fe..317b2e881e6818 100644 --- a/Python/codegen.c +++ b/Python/codegen.c @@ -686,13 +686,14 @@ codegen_setup_annotations_scope(compiler *c, location loc, PyObject *value_with_fake_globals = PyLong_FromLong(_Py_ANNOTATE_FORMAT_VALUE_WITH_FAKE_GLOBALS); assert(!SYMTABLE_ENTRY(c)->ste_has_docstring); _Py_DECLARE_STR(format, ".format"); - ADDOP_I(c, loc, LOAD_FAST, 0); - ADDOP_LOAD_CONST(c, loc, value_with_fake_globals); - ADDOP_I(c, loc, COMPARE_OP, (Py_GT << 5) | compare_masks[Py_GT]); + + ADDOP_I(c, NO_LOCATION, LOAD_FAST, 0); + ADDOP_LOAD_CONST(c, NO_LOCATION, value_with_fake_globals); + ADDOP_I(c, NO_LOCATION, COMPARE_OP, (Py_GT << 5) | compare_masks[Py_GT]); NEW_JUMP_TARGET_LABEL(c, body); - ADDOP_JUMP(c, loc, POP_JUMP_IF_FALSE, body); - ADDOP_I(c, loc, LOAD_COMMON_CONSTANT, CONSTANT_NOTIMPLEMENTEDERROR); - ADDOP_I(c, loc, RAISE_VARARGS, 1); + ADDOP_JUMP(c, NO_LOCATION, POP_JUMP_IF_FALSE, body); + ADDOP_I(c, NO_LOCATION, LOAD_COMMON_CONSTANT, CONSTANT_NOTIMPLEMENTEDERROR); + ADDOP_I(c, NO_LOCATION, RAISE_VARARGS, 1); USE_LABEL(c, body); return SUCCESS; } @@ -751,7 +752,7 @@ codegen_deferred_annotations_body(compiler *c, location loc, assert(PyList_CheckExact(conditional_annotation_indices)); assert(annotations_len == PyList_Size(conditional_annotation_indices)); - ADDOP_I(c, loc, BUILD_MAP, 0); // stack now contains + ADDOP_I(c, NO_LOCATION, BUILD_MAP, 0); // stack now contains for (Py_ssize_t i = 0; i < annotations_len; i++) { PyObject *ptr = PyList_GET_ITEM(deferred_anno, i); From 35246e7432732370c403b2d206706c639243fdfd Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Sun, 22 Jun 2025 10:47:28 +0000 Subject: [PATCH 2/8] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20blu?= =?UTF-8?q?rb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../2025-06-22-10-47-27.gh-issue-135700.0qdtCl.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2025-06-22-10-47-27.gh-issue-135700.0qdtCl.rst diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-06-22-10-47-27.gh-issue-135700.0qdtCl.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-06-22-10-47-27.gh-issue-135700.0qdtCl.rst new file mode 100644 index 00000000000000..6b1b9ddea2ab79 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-06-22-10-47-27.gh-issue-135700.0qdtCl.rst @@ -0,0 +1 @@ +Fix instructions in __annotate__ have incorrect code positions From 97bddb8db22404525eaab805fdedfd06b8e2842a Mon Sep 17 00:00:00 2001 From: PuQing Date: Sun, 22 Jun 2025 20:13:25 +0800 Subject: [PATCH 3/8] Update Misc/NEWS.d/next/Core_and_Builtins/2025-06-22-10-47-27.gh-issue-135700.0qdtCl.rst Co-authored-by: sobolevn --- .../2025-06-22-10-47-27.gh-issue-135700.0qdtCl.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-06-22-10-47-27.gh-issue-135700.0qdtCl.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-06-22-10-47-27.gh-issue-135700.0qdtCl.rst index 6b1b9ddea2ab79..dec0f3291c5125 100644 --- a/Misc/NEWS.d/next/Core_and_Builtins/2025-06-22-10-47-27.gh-issue-135700.0qdtCl.rst +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-06-22-10-47-27.gh-issue-135700.0qdtCl.rst @@ -1 +1 @@ -Fix instructions in __annotate__ have incorrect code positions +Fix instructions positions in :attr:`~object.__annotate__`. From 4de616a9355df2eab9ecf934b10cd8a60f91b441 Mon Sep 17 00:00:00 2001 From: PuQing Date: Sun, 22 Jun 2025 23:08:09 +0800 Subject: [PATCH 4/8] add unit tests Co-authored-by: Irit Katriel <1055913+iritkatriel@users.noreply.github.com> Co-authored-by: Frank Hoffmann <15r10nk@users.noreply.github.com> --- Lib/test/test_pdb.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index 6b74e21ad73d1a..e8bcc3e3beeabc 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -3816,6 +3816,31 @@ def bar(): self.assertIn('-> pass', lines) self.assertIn('(Pdb) 42', lines) + def test_issue135700(self): + """https://github.com/python/cpython/issues/135700""" + module_code = """\ + 22 + + class ClassVar: + pass + __dataclass_fields__: ClassVar + """ + with open("testmod.py", "w") as f: + f.write(module_code) + self.addCleanup(os_helper.unlink, "testmod.py") + + script = """ + import testmod + print(testmod.__annotations__) + """ + commands = """ + b testmod.py:1 + c + c + """ + result = self.run_pdb_script(script, commands) + self.assertNotIn("(1)__annotate__()", result[0]) + def test_step_into_botframe(self): # gh-125422 # pdb should not be able to step into the botframe (bdb.py) From a297926bc6340a32acddac959c5342e493ba75a1 Mon Sep 17 00:00:00 2001 From: PuQing Date: Sun, 13 Jul 2025 12:22:53 +0800 Subject: [PATCH 5/8] Update Lib/test/test_pdb.py Co-authored-by: Irit Katriel <1055913+iritkatriel@users.noreply.github.com> --- Lib/test/test_pdb.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index e8bcc3e3beeabc..b1a6509738c970 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -3817,7 +3817,7 @@ def bar(): self.assertIn('(Pdb) 42', lines) def test_issue135700(self): - """https://github.com/python/cpython/issues/135700""" + # See gh-135700 module_code = """\ 22 From 5820ce81b73aa04af1afd48f0ff4ae2f2e4b2e42 Mon Sep 17 00:00:00 2001 From: PuQing Date: Sun, 13 Jul 2025 20:01:25 +0800 Subject: [PATCH 6/8] fix codegen in annotations --- Lib/test/test_pdb.py | 8 ++++---- Python/codegen.c | 24 +++++++++++++++--------- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/Lib/test/test_pdb.py b/Lib/test/test_pdb.py index b1a6509738c970..ac693039f26d82 100644 --- a/Lib/test/test_pdb.py +++ b/Lib/test/test_pdb.py @@ -3818,21 +3818,21 @@ def bar(): def test_issue135700(self): # See gh-135700 - module_code = """\ + module_code = textwrap.dedent("""\ 22 class ClassVar: pass __dataclass_fields__: ClassVar - """ + """) with open("testmod.py", "w") as f: f.write(module_code) self.addCleanup(os_helper.unlink, "testmod.py") - script = """ + script = textwrap.dedent(""" import testmod print(testmod.__annotations__) - """ + """) commands = """ b testmod.py:1 c diff --git a/Python/codegen.c b/Python/codegen.c index 317b2e881e6818..4e4a467cff89d9 100644 --- a/Python/codegen.c +++ b/Python/codegen.c @@ -788,7 +788,7 @@ codegen_deferred_annotations_body(compiler *c, location loc, ADDOP_I(c, LOC(st), COPY, 2); ADDOP_LOAD_CONST_NEW(c, LOC(st), mangled); // stack now contains - ADDOP(c, loc, STORE_SUBSCR); + ADDOP(c, LOC(st), STORE_SUBSCR); // stack now contains USE_LABEL(c, not_set); @@ -823,7 +823,14 @@ codegen_process_deferred_annotations(compiler *c, location loc) PySTEntryObject *ste = SYMTABLE_ENTRY(c); assert(ste->ste_annotation_block != NULL); void *key = (void *)((uintptr_t)ste->ste_id + 1); - if (codegen_setup_annotations_scope(c, loc, key, + + // Get the first annotation location + PyObject* ptr = PyList_GET_ITEM(deferred_anno, 0); + stmt_ty st = (stmt_ty)PyLong_AsVoidPtr(ptr); + if (st == NULL) { + goto error; + } + if (codegen_setup_annotations_scope(c, LOC(st), key, ste->ste_annotation_block->ste_name) < 0) { goto error; } @@ -836,12 +843,11 @@ codegen_process_deferred_annotations(compiler *c, location loc) Py_DECREF(deferred_anno); Py_DECREF(conditional_annotation_indices); - RETURN_IF_ERROR(codegen_leave_annotations_scope(c, loc)); + RETURN_IF_ERROR(codegen_leave_annotations_scope(c, LOC(st))); RETURN_IF_ERROR(codegen_nameop( - c, loc, + c, LOC(st), ste->ste_type == ClassBlock ? &_Py_ID(__annotate_func__) : &_Py_ID(__annotate__), Store)); - if (need_separate_block) { RETURN_IF_ERROR(_PyCompile_EndAnnotationSetup(c)); } @@ -868,8 +874,8 @@ int _PyCodegen_Module(compiler *c, location loc, asdl_stmt_seq *stmts, bool is_interactive) { if (SYMTABLE_ENTRY(c)->ste_has_conditional_annotations) { - ADDOP_I(c, loc, BUILD_SET, 0); - ADDOP_N(c, loc, STORE_NAME, &_Py_ID(__conditional_annotations__), names); + ADDOP_I(c, NO_LOCATION, BUILD_SET, 0); + ADDOP_N(c, NO_LOCATION, STORE_NAME, &_Py_ID(__conditional_annotations__), names); } return codegen_body(c, loc, stmts, is_interactive); } @@ -1562,8 +1568,8 @@ codegen_class_body(compiler *c, stmt_ty s, int firstlineno) ADDOP_N_IN_SCOPE(c, loc, STORE_DEREF, &_Py_ID(__classdict__), cellvars); } if (SYMTABLE_ENTRY(c)->ste_has_conditional_annotations) { - ADDOP_I(c, loc, BUILD_SET, 0); - ADDOP_N_IN_SCOPE(c, loc, STORE_DEREF, &_Py_ID(__conditional_annotations__), cellvars); + ADDOP_I(c, NO_LOCATION, BUILD_SET, 0); + ADDOP_N_IN_SCOPE(c, NO_LOCATION, STORE_DEREF, &_Py_ID(__conditional_annotations__), cellvars); } /* compile the body proper */ RETURN_IF_ERROR_IN_SCOPE(c, codegen_body(c, loc, s->v.ClassDef.body, false)); From 850601ab0ee81561a819c710187073c387ab34c2 Mon Sep 17 00:00:00 2001 From: PuQing Date: Sun, 13 Jul 2025 20:45:00 +0800 Subject: [PATCH 7/8] add empty check --- Python/codegen.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Python/codegen.c b/Python/codegen.c index 4e4a467cff89d9..164f42f8b05fee 100644 --- a/Python/codegen.c +++ b/Python/codegen.c @@ -825,6 +825,9 @@ codegen_process_deferred_annotations(compiler *c, location loc) void *key = (void *)((uintptr_t)ste->ste_id + 1); // Get the first annotation location + if (PyList_GET_SIZE(deferred_anno) == 0) { + goto error; + } PyObject* ptr = PyList_GET_ITEM(deferred_anno, 0); stmt_ty st = (stmt_ty)PyLong_AsVoidPtr(ptr); if (st == NULL) { From 0e14a6d9152eb83257c670a2fd2fa229e0e2ccfd Mon Sep 17 00:00:00 2001 From: PuQing Date: Sun, 13 Jul 2025 21:05:43 +0800 Subject: [PATCH 8/8] assert deferred_anno is not empty --- Python/codegen.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Python/codegen.c b/Python/codegen.c index 164f42f8b05fee..57802cc941082f 100644 --- a/Python/codegen.c +++ b/Python/codegen.c @@ -13,6 +13,7 @@ */ #include "Python.h" +#include "listobject.h" #include "opcode.h" #include "pycore_ast.h" // _PyAST_GetDocString() #define NEED_OPCODE_TABLES @@ -825,9 +826,7 @@ codegen_process_deferred_annotations(compiler *c, location loc) void *key = (void *)((uintptr_t)ste->ste_id + 1); // Get the first annotation location - if (PyList_GET_SIZE(deferred_anno) == 0) { - goto error; - } + assert(PyList_GET_SIZE(deferred_anno) > 0); PyObject* ptr = PyList_GET_ITEM(deferred_anno, 0); stmt_ty st = (stmt_ty)PyLong_AsVoidPtr(ptr); if (st == NULL) {