summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorYurii Karabas <1998uriyyo@gmail.com>2020-11-25 10:43:18 (GMT)
committerGitHub <noreply@github.com>2020-11-25 10:43:18 (GMT)
commit7301979b23406220510dd2c7934a21b41b647119 (patch)
tree296b337317ac71d34001c17f4b4b7bea918cbf6f /Objects
parent85c84920f511d0d73a133336daeaf715a022cd64 (diff)
downloadcpython-7301979b23406220510dd2c7934a21b41b647119.zip
cpython-7301979b23406220510dd2c7934a21b41b647119.tar.gz
cpython-7301979b23406220510dd2c7934a21b41b647119.tar.bz2
bpo-42202: Store func annotations as a tuple (GH-23316)
Reduce memory footprint and improve performance of loading modules having many func annotations. >>> sys.getsizeof({"a":"int","b":"int","return":"int"}) 232 >>> sys.getsizeof(("a","int","b","int","return","int")) 88 The tuple is converted into dict on the fly when `func.__annotations__` is accessed first. Co-authored-by: Serhiy Storchaka <storchaka@gmail.com> Co-authored-by: Inada Naoki <songofacandy@gmail.com>
Diffstat (limited to 'Objects')
-rw-r--r--Objects/funcobject.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/Objects/funcobject.c b/Objects/funcobject.c
index 9b4302a..e7961b3 100644
--- a/Objects/funcobject.c
+++ b/Objects/funcobject.c
@@ -424,6 +424,25 @@ func_get_annotations(PyFunctionObject *op, void *Py_UNUSED(ignored))
if (op->func_annotations == NULL)
return NULL;
}
+ if (PyTuple_CheckExact(op->func_annotations)) {
+ PyObject *ann_tuple = op->func_annotations;
+ PyObject *ann_dict = PyDict_New();
+ if (ann_dict == NULL) {
+ return NULL;
+ }
+
+ assert(PyTuple_GET_SIZE(ann_tuple) % 2 == 0);
+
+ for (Py_ssize_t i = 0; i < PyTuple_GET_SIZE(ann_tuple); i += 2) {
+ int err = PyDict_SetItem(ann_dict,
+ PyTuple_GET_ITEM(ann_tuple, i),
+ PyTuple_GET_ITEM(ann_tuple, i + 1));
+
+ if (err < 0)
+ return NULL;
+ }
+ Py_SETREF(op->func_annotations, ann_dict);
+ }
Py_INCREF(op->func_annotations);
return op->func_annotations;
}