New submission from Serhiy Storchaka <[email protected]>:
It was common to use the code PyDict_GetItem(dict, key) == NULL to check
whether the key is in the dict. PyDict_GetItem() returns borrowed reference, so
no clean up is needed. And if we need to check only existence of the key, we do
not need to store a value.
But PyDict_GetItem() which suppresses all internal exceptions is considered not
safe, so PyDict_GetItemWithError() should be used. The code looks like:
if (PyDict_GetItemWithError(dict, key) == NULL) {
if (PyErr_Occurred()) {
goto error;
}
// does not have the key
}
else {
// has the key
}
It can be written with using PyDict_Contains():
int r = PyDict_Contains(dict, key);
if (r < 0) {
goto error;
}
if (r == 0) {
// does not have the key
}
else {
// has the key
}
Advantages:
* It is more clear expression of what we do.
* It is more simple and efficient in PyPy, because it has to keep borrowed
references and track their lifetime.
* It may be more efficient in CPython, because calling PyErr_Occurred() has
small but non-zero cost.
* PyErr_Occurred() would not be fooled by exception raised before. So you can
use this code even if an exception is set.
Disadvantages:
* You need to use an int variable.
In some cases, when this check is used in combinations with PyDict_SetItem(),
the code can be replaced with PyDict_SetDefault(), which is bot more terse and
efficient. And when it is used in combinations with PyDict_DelItem(), the code
can be replaced with _PyDict_Pop().
The proposed patch makes the code using PyDict_Contains() and
PyDict_SetDefault() if appropriate. All use cases for _PyDict_Pop() were
already covered by previous changes.
----------
components: +Interpreter Core
nosy: +methane, vstinner
title: Use PyDict_Contains() and PyDict_SetDefault() instead of
PyDict_GetItemIdWithError -> Use PyDict_Contains() and PyDict_SetDefault()
instead of PyDict_GetItemWithError()
type: -> enhancement
versions: +Python 3.10
_______________________________________
Python tracker <[email protected]>
<https://bugs.python.org/issue42152>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com