From e3a009b548e2a0b4b4e158ea8ce758142f7a8a67 Mon Sep 17 00:00:00 2001 From: Locked-chess-official <13140752715@163.com> Date: Thu, 30 Oct 2025 13:49:50 +0800 Subject: [PATCH 1/4] NameError new attribute op --- Include/cpython/pyerrors.h | 1 + Include/internal/pycore_ceval.h | 4 ++-- Lib/test/test_traceback.py | 13 +++++++++++++ Lib/traceback.py | 14 +++++++++----- Objects/exceptions.c | 10 ++++++++-- Python/bytecodes.c | 6 +++--- Python/ceval.c | 26 +++++++++++++++++++------- Python/executor_cases.c.h | 6 +++--- Python/generated_cases.c.h | 25 ++++++++++++++++--------- 9 files changed, 74 insertions(+), 31 deletions(-) diff --git a/Include/cpython/pyerrors.h b/Include/cpython/pyerrors.h index 6b63d304b0d929..df38143668ea5b 100644 --- a/Include/cpython/pyerrors.h +++ b/Include/cpython/pyerrors.h @@ -75,6 +75,7 @@ typedef struct { typedef struct { PyException_HEAD PyObject *name; + PyObject *op; } PyNameErrorObject; typedef struct { diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h index 102a378f8f08bc..6c3b5e986a19bc 100644 --- a/Include/internal/pycore_ceval.h +++ b/Include/internal/pycore_ceval.h @@ -293,8 +293,8 @@ PyAPI_FUNC(int) _PyEval_CheckExceptStarTypeValid(PyThreadState *tstate, PyObject PyAPI_FUNC(int) _PyEval_CheckExceptTypeValid(PyThreadState *tstate, PyObject* right); PyAPI_FUNC(int) _PyEval_ExceptionGroupMatch(_PyInterpreterFrame *, PyObject* exc_value, PyObject *match_type, PyObject **match, PyObject **rest); PyAPI_FUNC(void) _PyEval_FormatAwaitableError(PyThreadState *tstate, PyTypeObject *type, int oparg); -PyAPI_FUNC(void) _PyEval_FormatExcCheckArg(PyThreadState *tstate, PyObject *exc, const char *format_str, PyObject *obj); -PyAPI_FUNC(void) _PyEval_FormatExcUnbound(PyThreadState *tstate, PyCodeObject *co, int oparg); +PyAPI_FUNC(void) _PyEval_FormatExcCheckArg(PyThreadState *tstate, PyObject *exc, const char *format_str, PyObject *obj, PyObject* op); +PyAPI_FUNC(void) _PyEval_FormatExcUnbound(PyThreadState *tstate, PyCodeObject *co, int oparg, int op_type); PyAPI_FUNC(void) _PyEval_FormatKwargsError(PyThreadState *tstate, PyObject *func, PyObject *kwargs); PyAPI_FUNC(PyObject *) _PyEval_ImportFrom(PyThreadState *, PyObject *, PyObject *); PyAPI_FUNC(PyObject *) _PyEval_ImportName(PyThreadState *, _PyInterpreterFrame *, PyObject *, PyObject *, PyObject *); diff --git a/Lib/test/test_traceback.py b/Lib/test/test_traceback.py index bf57867a8715c0..fac2854f69239c 100644 --- a/Lib/test/test_traceback.py +++ b/Lib/test/test_traceback.py @@ -4648,6 +4648,19 @@ def func(): actual = self.get_suggestion(func) self.assertIn("'ZeroDivisionError'?", actual) + def test_name_error_ignore_suggestions_from_builtins_in_deleting(self): + try: + exec("del next") + except NameError: + msg = traceback.format_exc() + self.assertNotIn("anext", msg) + + def func(): + del next + + actual = self.get_suggestion(func) + self.assertNotIn("anext", actual) + def test_name_error_suggestions_with_non_string_candidates(self): def func(): abc = 1 diff --git a/Lib/traceback.py b/Lib/traceback.py index 9b4b8c7d566fe8..64deab47837a5c 100644 --- a/Lib/traceback.py +++ b/Lib/traceback.py @@ -1674,11 +1674,15 @@ def _compute_suggestion_error(exc_value, tb, wrong_name): while tb.tb_next is not None: tb = tb.tb_next frame = tb.tb_frame - d = ( - list(frame.f_locals) - + list(frame.f_globals) - + list(frame.f_builtins) - ) + if getattr(exc_value, "op", "getting") == "deleting": + d = (list(frame.f_locals) + + list(frame.f_globals)) + else: + d = ( + list(frame.f_locals) + + list(frame.f_globals) + + list(frame.f_builtins) + ) d = [x for x in d if isinstance(x, str)] # Check first if we are in a method and the instance diff --git a/Objects/exceptions.c b/Objects/exceptions.c index 244d8f39e2bae5..af0cf691777015 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -2506,8 +2506,9 @@ PyNameErrorObject_CAST(PyObject *self) static int NameError_init(PyObject *op, PyObject *args, PyObject *kwds) { - static char *kwlist[] = {"name", NULL}; + static char *kwlist[] = {"name", "op", NULL}; PyObject *name = NULL; + PyObject* op_type = NULL; if (BaseException_init(op, args, NULL) == -1) { return -1; @@ -2518,7 +2519,7 @@ NameError_init(PyObject *op, PyObject *args, PyObject *kwds) return -1; } if (!PyArg_ParseTupleAndKeywords(empty_tuple, kwds, "|$O:NameError", kwlist, - &name)) { + &name ,&op_type)) { Py_DECREF(empty_tuple); return -1; } @@ -2526,6 +2527,7 @@ NameError_init(PyObject *op, PyObject *args, PyObject *kwds) PyNameErrorObject *self = PyNameErrorObject_CAST(op); Py_XSETREF(self->name, Py_XNewRef(name)); + Py_XSETREF(self->op, Py_XNewRef(op_type)); return 0; } @@ -2535,6 +2537,7 @@ NameError_clear(PyObject *op) { PyNameErrorObject *self = PyNameErrorObject_CAST(op); Py_CLEAR(self->name); + Py_CLEAR(self->op); return BaseException_clear(op); } @@ -2551,11 +2554,14 @@ NameError_traverse(PyObject *op, visitproc visit, void *arg) { PyNameErrorObject *self = PyNameErrorObject_CAST(op); Py_VISIT(self->name); + Py_VISIT(self->op); return BaseException_traverse(op, visit, arg); } static PyMemberDef NameError_members[] = { {"name", _Py_T_OBJECT, offsetof(PyNameErrorObject, name), 0, PyDoc_STR("name")}, + {"op", _Py_T_OBJECT, offsetof(PyNameErrorObject, op), 0, + PyDoc_STR("operation that caused the NameError ('getting' or 'deleting')")}, {NULL} /* Sentinel */ }; diff --git a/Python/bytecodes.c b/Python/bytecodes.c index 6ebd9ebdfce1bb..7f111b1678c967 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -1917,7 +1917,7 @@ dummy_func( // Fortunately we don't need its superpower. PyObject *oldobj = PyCell_SwapTakeRef((PyCellObject *)cell, NULL); if (oldobj == NULL) { - _PyEval_FormatExcUnbound(tstate, _PyFrame_GetCode(frame), oparg); + _PyEval_FormatExcUnbound(tstate, _PyFrame_GetCode(frame), oparg, 1); ERROR_NO_POP(); } Py_DECREF(oldobj); @@ -1939,7 +1939,7 @@ dummy_func( PyCellObject *cell = (PyCellObject *)PyStackRef_AsPyObjectBorrow(GETLOCAL(oparg)); value_o = PyCell_GetRef(cell); if (value_o == NULL) { - _PyEval_FormatExcUnbound(tstate, _PyFrame_GetCode(frame), oparg); + _PyEval_FormatExcUnbound(tstate, _PyFrame_GetCode(frame), oparg, 0); ERROR_NO_POP(); } } @@ -1951,7 +1951,7 @@ dummy_func( PyCellObject *cell = (PyCellObject *)PyStackRef_AsPyObjectBorrow(GETLOCAL(oparg)); value = _PyCell_GetStackRef(cell); if (PyStackRef_IsNull(value)) { - _PyEval_FormatExcUnbound(tstate, _PyFrame_GetCode(frame), oparg); + _PyEval_FormatExcUnbound(tstate, _PyFrame_GetCode(frame), oparg, 0); ERROR_IF(true); } } diff --git a/Python/ceval.c b/Python/ceval.c index 7ec5abf5a76bd9..0fcef99e1b4fe9 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -3320,7 +3320,7 @@ _PyEval_FormatKwargsError(PyThreadState *tstate, PyObject *func, PyObject *kwarg void _PyEval_FormatExcCheckArg(PyThreadState *tstate, PyObject *exc, - const char *format_str, PyObject *obj) + const char *format_str, PyObject *obj, PyObject *op) { const char *obj_str; @@ -3342,25 +3342,35 @@ _PyEval_FormatExcCheckArg(PyThreadState *tstate, PyObject *exc, // NameError anyway. (void)PyObject_SetAttr(exc, &_Py_ID(name), obj); } + if (((PyNameErrorObject*)exc)->op == NULL) { + (void)PyObject_SetAttrString(exc, "op", op); + } } PyErr_SetRaisedException(exc); } } void -_PyEval_FormatExcUnbound(PyThreadState *tstate, PyCodeObject *co, int oparg) +_PyEval_FormatExcUnbound(PyThreadState *tstate, PyCodeObject *co, int oparg, int op_type) { PyObject *name; + PyObject* op; + if (op_type == 0) { + op = PyUnicode_FromString("getting"); + } + else { + op = PyUnicode_FromString("deleting"); + } /* Don't stomp existing exception */ if (_PyErr_Occurred(tstate)) return; name = PyTuple_GET_ITEM(co->co_localsplusnames, oparg); if (oparg < PyUnstable_Code_GetFirstFree(co)) { _PyEval_FormatExcCheckArg(tstate, PyExc_UnboundLocalError, - UNBOUNDLOCAL_ERROR_MSG, name); + UNBOUNDLOCAL_ERROR_MSG, name, op); } else { _PyEval_FormatExcCheckArg(tstate, PyExc_NameError, - UNBOUNDFREE_ERROR_MSG, name); + UNBOUNDFREE_ERROR_MSG, name, op); } } @@ -3453,6 +3463,7 @@ _PyEval_GetANext(PyObject *aiter) void _PyEval_LoadGlobalStackRef(PyObject *globals, PyObject *builtins, PyObject *name, _PyStackRef *writeto) { + PyObject* op = PyUnicode_FromString("getting"); if (PyDict_CheckExact(globals) && PyDict_CheckExact(builtins)) { _PyDict_LoadGlobalStackRef((PyDictObject *)globals, (PyDictObject *)builtins, @@ -3461,7 +3472,7 @@ _PyEval_LoadGlobalStackRef(PyObject *globals, PyObject *builtins, PyObject *name /* _PyDict_LoadGlobal() returns NULL without raising * an exception if the key doesn't exist */ _PyEval_FormatExcCheckArg(PyThreadState_GET(), PyExc_NameError, - NAME_ERROR_MSG, name); + NAME_ERROR_MSG, name, op); } } else { @@ -3481,7 +3492,7 @@ _PyEval_LoadGlobalStackRef(PyObject *globals, PyObject *builtins, PyObject *name if (res == NULL) { _PyEval_FormatExcCheckArg( PyThreadState_GET(), PyExc_NameError, - NAME_ERROR_MSG, name); + NAME_ERROR_MSG, name, op); *writeto = PyStackRef_NULL; return; } @@ -3519,6 +3530,7 @@ _PyEval_LoadName(PyThreadState *tstate, _PyInterpreterFrame *frame, PyObject *na { PyObject *value; + PyObject* op = PyUnicode_FromString("getting"); if (frame->f_locals == NULL) { _PyErr_SetString(tstate, PyExc_SystemError, "no locals found"); @@ -3542,7 +3554,7 @@ _PyEval_LoadName(PyThreadState *tstate, _PyInterpreterFrame *frame, PyObject *na if (value == NULL) { _PyEval_FormatExcCheckArg( tstate, PyExc_NameError, - NAME_ERROR_MSG, name); + NAME_ERROR_MSG, name, op); } return value; } diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index 9ce0a9f8a4d87b..be1b634527680b 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -2625,7 +2625,7 @@ PyObject *oldobj = PyCell_SwapTakeRef((PyCellObject *)cell, NULL); if (oldobj == NULL) { _PyFrame_SetStackPointer(frame, stack_pointer); - _PyEval_FormatExcUnbound(tstate, _PyFrame_GetCode(frame), oparg); + _PyEval_FormatExcUnbound(tstate, _PyFrame_GetCode(frame), oparg, 1); stack_pointer = _PyFrame_GetStackPointer(frame); JUMP_TO_ERROR(); } @@ -2657,7 +2657,7 @@ value_o = PyCell_GetRef(cell); if (value_o == NULL) { _PyFrame_SetStackPointer(frame, stack_pointer); - _PyEval_FormatExcUnbound(tstate, _PyFrame_GetCode(frame), oparg); + _PyEval_FormatExcUnbound(tstate, _PyFrame_GetCode(frame), oparg, 0); stack_pointer = _PyFrame_GetStackPointer(frame); JUMP_TO_ERROR(); } @@ -2686,7 +2686,7 @@ stack_pointer += 1; assert(WITHIN_STACK_BOUNDS()); _PyFrame_SetStackPointer(frame, stack_pointer); - _PyEval_FormatExcUnbound(tstate, _PyFrame_GetCode(frame), oparg); + _PyEval_FormatExcUnbound(tstate, _PyFrame_GetCode(frame), oparg, 0); stack_pointer = _PyFrame_GetStackPointer(frame); JUMP_TO_ERROR(); } diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index 79328a7b725613..7c6ad3e553cabd 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -5172,7 +5172,7 @@ PyObject *oldobj = PyCell_SwapTakeRef((PyCellObject *)cell, NULL); if (oldobj == NULL) { _PyFrame_SetStackPointer(frame, stack_pointer); - _PyEval_FormatExcUnbound(tstate, _PyFrame_GetCode(frame), oparg); + _PyEval_FormatExcUnbound(tstate, _PyFrame_GetCode(frame), oparg, 1); stack_pointer = _PyFrame_GetStackPointer(frame); JUMP_TO_LABEL(error); } @@ -5187,6 +5187,7 @@ int opcode = DELETE_FAST; (void)(opcode); #endif + PyObject* op = PyUnicode_FromString("deleting"); frame->instr_ptr = next_instr; next_instr += 1; INSTRUCTION_STATS(DELETE_FAST); @@ -5195,7 +5196,8 @@ _PyFrame_SetStackPointer(frame, stack_pointer); _PyEval_FormatExcCheckArg(tstate, PyExc_UnboundLocalError, UNBOUNDLOCAL_ERROR_MSG, - PyTuple_GetItem(_PyFrame_GetCode(frame)->co_localsplusnames, oparg) + PyTuple_GetItem(_PyFrame_GetCode(frame)->co_localsplusnames, oparg), + op ); stack_pointer = _PyFrame_GetStackPointer(frame); JUMP_TO_LABEL(error); @@ -5213,6 +5215,7 @@ int opcode = DELETE_GLOBAL; (void)(opcode); #endif + PyObject* op = PyUnicode_FromString("deleting"); frame->instr_ptr = next_instr; next_instr += 1; INSTRUCTION_STATS(DELETE_GLOBAL); @@ -5226,7 +5229,7 @@ if (err == 0) { _PyFrame_SetStackPointer(frame, stack_pointer); _PyEval_FormatExcCheckArg(tstate, PyExc_NameError, - NAME_ERROR_MSG, name); + NAME_ERROR_MSG, name, op); stack_pointer = _PyFrame_GetStackPointer(frame); JUMP_TO_LABEL(error); } @@ -5238,6 +5241,7 @@ int opcode = DELETE_NAME; (void)(opcode); #endif + PyObject* op = PyUnicode_FromString("deleting"); frame->instr_ptr = next_instr; next_instr += 1; INSTRUCTION_STATS(DELETE_NAME); @@ -5258,7 +5262,8 @@ _PyFrame_SetStackPointer(frame, stack_pointer); _PyEval_FormatExcCheckArg(tstate, PyExc_NameError, NAME_ERROR_MSG, - name); + name, + op); stack_pointer = _PyFrame_GetStackPointer(frame); JUMP_TO_LABEL(error); } @@ -8858,7 +8863,7 @@ stack_pointer += 1; assert(WITHIN_STACK_BOUNDS()); _PyFrame_SetStackPointer(frame, stack_pointer); - _PyEval_FormatExcUnbound(tstate, _PyFrame_GetCode(frame), oparg); + _PyEval_FormatExcUnbound(tstate, _PyFrame_GetCode(frame), oparg, 0); stack_pointer = _PyFrame_GetStackPointer(frame); JUMP_TO_LABEL(error); } @@ -8945,6 +8950,7 @@ int opcode = LOAD_FAST_CHECK; (void)(opcode); #endif + PyObject* op = PyUnicode_FromString("getting"); frame->instr_ptr = next_instr; next_instr += 1; INSTRUCTION_STATS(LOAD_FAST_CHECK); @@ -8954,7 +8960,7 @@ _PyFrame_SetStackPointer(frame, stack_pointer); _PyEval_FormatExcCheckArg(tstate, PyExc_UnboundLocalError, UNBOUNDLOCAL_ERROR_MSG, - PyTuple_GetItem(_PyFrame_GetCode(frame)->co_localsplusnames, oparg) + PyTuple_GetItem(_PyFrame_GetCode(frame)->co_localsplusnames, oparg), op ); stack_pointer = _PyFrame_GetStackPointer(frame); JUMP_TO_LABEL(error); @@ -9015,7 +9021,7 @@ value_o = PyCell_GetRef(cell); if (value_o == NULL) { _PyFrame_SetStackPointer(frame, stack_pointer); - _PyEval_FormatExcUnbound(tstate, _PyFrame_GetCode(frame), oparg); + _PyEval_FormatExcUnbound(tstate, _PyFrame_GetCode(frame), oparg, 0); stack_pointer = _PyFrame_GetStackPointer(frame); JUMP_TO_LABEL(error); } @@ -9037,6 +9043,7 @@ int opcode = LOAD_FROM_DICT_OR_GLOBALS; (void)(opcode); #endif + PyObject* op = PyUnicode_FromString("getting"); frame->instr_ptr = next_instr; next_instr += 1; INSTRUCTION_STATS(LOAD_FROM_DICT_OR_GLOBALS); @@ -9069,7 +9076,7 @@ if (!_PyErr_Occurred(tstate)) { _PyFrame_SetStackPointer(frame, stack_pointer); _PyEval_FormatExcCheckArg(tstate, PyExc_NameError, - NAME_ERROR_MSG, name); + NAME_ERROR_MSG, name, op); stack_pointer = _PyFrame_GetStackPointer(frame); } JUMP_TO_LABEL(error); @@ -9093,7 +9100,7 @@ _PyFrame_SetStackPointer(frame, stack_pointer); _PyEval_FormatExcCheckArg( tstate, PyExc_NameError, - NAME_ERROR_MSG, name); + NAME_ERROR_MSG, name, op); stack_pointer = _PyFrame_GetStackPointer(frame); JUMP_TO_LABEL(error); } From 11636f9ad5fb5d5c726070f2bc7ecc1ca15517e6 Mon Sep 17 00:00:00 2001 From: Locked-chess-official <13140752715@163.com> Date: Thu, 30 Oct 2025 14:01:27 +0800 Subject: [PATCH 2/4] fix in jit --- Python/executor_cases.c.h | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index be1b634527680b..2b50cf1da64499 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -72,11 +72,13 @@ _PyStackRef value; oparg = CURRENT_OPARG(); _PyStackRef value_s = GETLOCAL(oparg); + PyObject* op = PyUnicode_FromString("getting"); if (PyStackRef_IsNull(value_s)) { _PyFrame_SetStackPointer(frame, stack_pointer); _PyEval_FormatExcCheckArg(tstate, PyExc_UnboundLocalError, UNBOUNDLOCAL_ERROR_MSG, - PyTuple_GetItem(_PyFrame_GetCode(frame)->co_localsplusnames, oparg) + PyTuple_GetItem(_PyFrame_GetCode(frame)->co_localsplusnames, oparg), + op ); stack_pointer = _PyFrame_GetStackPointer(frame); JUMP_TO_ERROR(); @@ -2197,6 +2199,7 @@ oparg = CURRENT_OPARG(); PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); PyObject *ns = LOCALS(); + PyObject* op = PyUnicode_FromString("deleting"); int err; if (ns == NULL) { _PyFrame_SetStackPointer(frame, stack_pointer); @@ -2212,7 +2215,8 @@ _PyFrame_SetStackPointer(frame, stack_pointer); _PyEval_FormatExcCheckArg(tstate, PyExc_NameError, NAME_ERROR_MSG, - name); + name, + op); stack_pointer = _PyFrame_GetStackPointer(frame); JUMP_TO_ERROR(); } @@ -2413,6 +2417,7 @@ case _DELETE_GLOBAL: { oparg = CURRENT_OPARG(); PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); + PyObject* op = PyUnicode_FromString("deleting"); _PyFrame_SetStackPointer(frame, stack_pointer); int err = PyDict_Pop(GLOBALS(), name, NULL); stack_pointer = _PyFrame_GetStackPointer(frame); @@ -2422,7 +2427,7 @@ if (err == 0) { _PyFrame_SetStackPointer(frame, stack_pointer); _PyEval_FormatExcCheckArg(tstate, PyExc_NameError, - NAME_ERROR_MSG, name); + NAME_ERROR_MSG, name, op); stack_pointer = _PyFrame_GetStackPointer(frame); JUMP_TO_ERROR(); } @@ -2587,11 +2592,13 @@ case _DELETE_FAST: { oparg = CURRENT_OPARG(); _PyStackRef v = GETLOCAL(oparg); + PyObject* op = PyUnicode_FromString("deleting"); if (PyStackRef_IsNull(v)) { _PyFrame_SetStackPointer(frame, stack_pointer); _PyEval_FormatExcCheckArg(tstate, PyExc_UnboundLocalError, UNBOUNDLOCAL_ERROR_MSG, - PyTuple_GetItem(_PyFrame_GetCode(frame)->co_localsplusnames, oparg) + PyTuple_GetItem(_PyFrame_GetCode(frame)->co_localsplusnames, oparg), + op ); stack_pointer = _PyFrame_GetStackPointer(frame); JUMP_TO_ERROR(); From 236a627cb6469b492c05760237b8602b274bee94 Mon Sep 17 00:00:00 2001 From: Locked-chess-official <13140752715@163.com> Date: Thu, 30 Oct 2025 16:09:35 +0800 Subject: [PATCH 3/4] fix keyword in NameError --- Objects/exceptions.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Objects/exceptions.c b/Objects/exceptions.c index af0cf691777015..8f7f8146ff3287 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -2518,7 +2518,7 @@ NameError_init(PyObject *op, PyObject *args, PyObject *kwds) if (!empty_tuple) { return -1; } - if (!PyArg_ParseTupleAndKeywords(empty_tuple, kwds, "|$O:NameError", kwlist, + if (!PyArg_ParseTupleAndKeywords(empty_tuple, kwds, "|$OO:NameError", kwlist, &name ,&op_type)) { Py_DECREF(empty_tuple); return -1; From a629dd6d3a8bd7bea98ee639bf61956e62403646 Mon Sep 17 00:00:00 2001 From: Locked-chess-official <13140752715@163.com> Date: Fri, 31 Oct 2025 08:31:55 +0800 Subject: [PATCH 4/4] add News --- .../2025-10-31-08-31-39.gh-issue-138890.QL4TYz.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2025-10-31-08-31-39.gh-issue-138890.QL4TYz.rst diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-10-31-08-31-39.gh-issue-138890.QL4TYz.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-10-31-08-31-39.gh-issue-138890.QL4TYz.rst new file mode 100644 index 00000000000000..fcd1f878af9db6 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-10-31-08-31-39.gh-issue-138890.QL4TYz.rst @@ -0,0 +1 @@ +Add "NameError.op" to avoid suggesting builtins name in deleting