summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorMark Shannon <mark@hotpy.org>2024-08-27 09:34:46 (GMT)
committerGitHub <noreply@github.com>2024-08-27 09:34:46 (GMT)
commit89328f7b129a6e4d7164f954b976bf45da69f0b2 (patch)
tree66ecae5b1b0736a09598bb4412bad006e5c1dab1 /Objects
parentfe85a8291d9aa11c9ce9e207c39ea0a0c35f9625 (diff)
downloadcpython-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.c17
-rw-r--r--Objects/typeobject.c2
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;