diff options
author | Mark Shannon <mark@hotpy.org> | 2024-08-27 09:34:46 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-08-27 09:34:46 (GMT) |
commit | 89328f7b129a6e4d7164f954b976bf45da69f0b2 (patch) | |
tree | 66ecae5b1b0736a09598bb4412bad006e5c1dab1 /Objects | |
parent | fe85a8291d9aa11c9ce9e207c39ea0a0c35f9625 (diff) | |
download | cpython-89328f7b129a6e4d7164f954b976bf45da69f0b2.zip cpython-89328f7b129a6e4d7164f954b976bf45da69f0b2.tar.gz cpython-89328f7b129a6e4d7164f954b976bf45da69f0b2.tar.bz2 |
GH-115775: Use `__static_attributes__` to initialize shared keys (GH-118468)
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/dictobject.c | 17 | ||||
-rw-r--r-- | Objects/typeobject.c | 2 |
2 files changed, 17 insertions, 2 deletions
diff --git a/Objects/dictobject.c b/Objects/dictobject.c index a30b3e3..b81ed18 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -6559,9 +6559,10 @@ dictvalues_reversed(PyObject *self, PyObject *Py_UNUSED(ignored)) /* Returns NULL if cannot allocate a new PyDictKeysObject, but does not set an error */ PyDictKeysObject * -_PyDict_NewKeysForClass(void) +_PyDict_NewKeysForClass(PyHeapTypeObject *cls) { PyInterpreterState *interp = _PyInterpreterState_GET(); + PyDictKeysObject *keys = new_keys_object( interp, NEXT_LOG2_SHARED_KEYS_MAX_SIZE, 1); if (keys == NULL) { @@ -6573,6 +6574,20 @@ _PyDict_NewKeysForClass(void) keys->dk_usable = SHARED_KEYS_MAX_SIZE; keys->dk_kind = DICT_KEYS_SPLIT; } + if (cls->ht_type.tp_dict) { + PyObject *attrs = PyDict_GetItem(cls->ht_type.tp_dict, &_Py_ID(__static_attributes__)); + if (attrs != NULL && PyTuple_Check(attrs)) { + for (Py_ssize_t i = 0; i < PyTuple_GET_SIZE(attrs); i++) { + PyObject *key = PyTuple_GET_ITEM(attrs, i); + Py_hash_t hash; + if (PyUnicode_CheckExact(key) && (hash = unicode_get_hash(key)) != -1) { + if (insert_split_key(keys, key, hash) == DKIX_EMPTY) { + break; + } + } + } + } + } return keys; } diff --git a/Objects/typeobject.c b/Objects/typeobject.c index f74d5122..c3a8fb5 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -8334,7 +8334,7 @@ type_ready_managed_dict(PyTypeObject *type) } PyHeapTypeObject* et = (PyHeapTypeObject*)type; if (et->ht_cached_keys == NULL) { - et->ht_cached_keys = _PyDict_NewKeysForClass(); + et->ht_cached_keys = _PyDict_NewKeysForClass(et); if (et->ht_cached_keys == NULL) { PyErr_NoMemory(); return -1; |