-
-
Notifications
You must be signed in to change notification settings - Fork 33.5k
gh-138890: Add clearer message when deleting builtins with del
#139078
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Python/generated_cases.c.h
Outdated
| UNBOUNDLOCAL_ERROR_MSG, | ||
| PyTuple_GetItem(_PyFrame_GetCode(frame)->co_localsplusnames, oparg) | ||
| ); | ||
| name = PyTuple_GetItem(_PyFrame_GetCode(frame)->co_localsplusnames, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe it is better no to break the declaration and the assignment?
Python/bytecodes.c
Outdated
| PyTuple_GetItem(_PyFrame_GetCode(frame)->co_localsplusnames, oparg) | ||
| ); | ||
| PyObject *name; | ||
| name = PyTuple_GetItem(_PyFrame_GetCode(frame)->co_localsplusnames, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PyTuple_GetItem can fail. We should be able to expect that it can't, so let's use PyTuple_GET_ITEM.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't we leave this as is? This seems like an unrelated change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, the new usage of PyTuple_GetItem is potentially dangerous. Initially, it was used alongside _PyEval_FormatExcCheckArg, which would safely check for NULL to propagate exceptions during the lookup. Now, we're calling PyMapping_HasKeyWithError with a potentially NULL argument, which isn't safe. There are two solutions:
- Use
PyTuple_GET_ITEM, which prevents failure entirely. This can possibly crash if someone messed with the code object, but that's possible already. - Check the result of
PyTuple_GetItembefore callingPyMapping_HasKeyWithError.
My suggestion was choosing the former, but I missed that we were using PyTuple_GetItem initially. I think you're right that we should continue using that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, the new usage of PyTuple_GetItem is potentially dangerous
I missed that we were using PyTuple_GetItem initially. I think you're right that we should continue using that.
So what should we do? Do we leave this as is?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's do this:
Check the result of
PyTuple_GetItembefore callingPyMapping_HasKeyWithError.
Misc/NEWS.d/next/Core_and_Builtins/2025-09-18-01-13-22.gh-issue-138890.x2QKfy.rst
Outdated
Show resolved
Hide resolved
Try to fit C code in reasonable width
terryjreedy
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The other two tests also assume that the user correctly typed the intended name and meant to delete a builtin rather than a masking use. I think this will be true less than half the time.
| def f(): | ||
| del all | ||
|
|
||
| with self.assertRaisesRegex(UnboundLocalError, "cannot delete builtin 'all'"): | ||
| f() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Within a function it does not matter whether a name not in a global statement is or is not in globals or builtins. It only matters that it is an unbound local. Leave this case alone.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we do so, should we also revert changes in DELETE_FAST implementation?
Uh oh!
There was an error while loading. Please reload this page.