mirror of
https://github.com/python/cpython.git
synced 2025-08-04 17:08:35 +00:00
gh-111262: Add PyDict_Pop() function (#112028)
_PyDict_Pop_KnownHash(): remove the default value and the return type becomes an int. Co-authored-by: Stefan Behnel <stefan_ml@behnel.de> Co-authored-by: Antoine Pitrou <pitrou@free.fr>
This commit is contained in:
parent
f44d6ff6e0
commit
4f04172c92
15 changed files with 338 additions and 76 deletions
|
@ -1087,19 +1087,9 @@ bounded_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwds
|
|||
The cache dict holds one reference to the link.
|
||||
We created one other reference when the link was created.
|
||||
The linked list only has borrowed references. */
|
||||
popresult = _PyDict_Pop_KnownHash(self->cache, link->key,
|
||||
link->hash, Py_None);
|
||||
if (popresult == Py_None) {
|
||||
/* Getting here means that the user function call or another
|
||||
thread has already removed the old key from the dictionary.
|
||||
This link is now an orphan. Since we don't want to leave the
|
||||
cache in an inconsistent state, we don't restore the link. */
|
||||
Py_DECREF(popresult);
|
||||
Py_DECREF(link);
|
||||
Py_DECREF(key);
|
||||
return result;
|
||||
}
|
||||
if (popresult == NULL) {
|
||||
int res = _PyDict_Pop_KnownHash((PyDictObject*)self->cache, link->key,
|
||||
link->hash, &popresult);
|
||||
if (res < 0) {
|
||||
/* An error arose while trying to remove the oldest key (the one
|
||||
being evicted) from the cache. We restore the link to its
|
||||
original position as the oldest link. Then we allow the
|
||||
|
@ -1110,10 +1100,22 @@ bounded_lru_cache_wrapper(lru_cache_object *self, PyObject *args, PyObject *kwds
|
|||
Py_DECREF(result);
|
||||
return NULL;
|
||||
}
|
||||
if (res == 0) {
|
||||
/* Getting here means that the user function call or another
|
||||
thread has already removed the old key from the dictionary.
|
||||
This link is now an orphan. Since we don't want to leave the
|
||||
cache in an inconsistent state, we don't restore the link. */
|
||||
assert(popresult == NULL);
|
||||
Py_DECREF(link);
|
||||
Py_DECREF(key);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Keep a reference to the old key and old result to prevent their
|
||||
ref counts from going to zero during the update. That will
|
||||
prevent potentially arbitrary object clean-up code (i.e. __del__)
|
||||
from running while we're still adjusting the links. */
|
||||
assert(popresult != NULL);
|
||||
oldkey = link->key;
|
||||
oldresult = link->result;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue