New submission from Serhiy Storchaka <storchaka+cpyt...@gmail.com>:
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 <rep...@bugs.python.org> <https://bugs.python.org/issue42152> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com