DISPATCH();
}
- TARGET_WITH_IMPL(BUILD_MAP_UNPACK_WITH_CALL, _build_map_unpack)
- TARGET(BUILD_MAP_UNPACK)
- _build_map_unpack: {
- int with_call = opcode == BUILD_MAP_UNPACK_WITH_CALL;
- int num_maps;
- int i;
- PyObject *sum = PyDict_New();
- if (sum == NULL)
+ TARGET(SETUP_ANNOTATIONS) {
+ _Py_IDENTIFIER(__annotations__);
+ int err;
+ PyObject *ann_dict;
+ if (f->f_locals == NULL) {
+ PyErr_Format(PyExc_SystemError,
+ "no locals found when setting up annotations");
goto error;
- if (with_call) {
- num_maps = oparg & 0xff;
}
- else {
- num_maps = oparg;
+ /* check if __annotations__ in locals()... */
+ if (PyDict_CheckExact(f->f_locals)) {
+ ann_dict = _PyDict_GetItemId(f->f_locals,
+ &PyId___annotations__);
+ if (ann_dict == NULL) {
+ /* ...if not, create a new one */
+ ann_dict = PyDict_New();
+ if (ann_dict == NULL) {
+ goto error;
+ }
+ err = _PyDict_SetItemId(f->f_locals,
+ &PyId___annotations__, ann_dict);
+ Py_DECREF(ann_dict);
+ if (err != 0) {
+ goto error;
+ }
+ }
}
-
- for (i = num_maps; i > 0; i--) {
- PyObject *arg = PEEK(i);
- if (with_call) {
- PyObject *intersection = _PyDictView_Intersect(sum, arg);
-
- if (intersection == NULL) {
- if (PyErr_ExceptionMatches(PyExc_AttributeError) ||
- !PyMapping_Check(arg)) {
- int function_location = (oparg>>8) & 0xff;
- PyObject *func = (
- PEEK(function_location + num_maps));
- PyErr_Format(PyExc_TypeError,
- "%.200s%.200s argument after ** "
- "must be a mapping, not %.200s",
- PyEval_GetFuncName(func),
- PyEval_GetFuncDesc(func),
- arg->ob_type->tp_name);
- }
- Py_DECREF(sum);
+ else {
+ /* do the same if locals() is not a dict */
+ PyObject *ann_str = _PyUnicode_FromId(&PyId___annotations__);
+ if (ann_str == NULL) {
- break;
++ goto error;
+ }
+ ann_dict = PyObject_GetItem(f->f_locals, ann_str);
+ if (ann_dict == NULL) {
+ if (!PyErr_ExceptionMatches(PyExc_KeyError)) {
goto error;
}
-
- if (PySet_GET_SIZE(intersection)) {
- Py_ssize_t idx = 0;
- PyObject *key;
- int function_location = (oparg>>8) & 0xff;
- PyObject *func = PEEK(function_location + num_maps);
- Py_hash_t hash;
- _PySet_NextEntry(intersection, &idx, &key, &hash);
- if (!PyUnicode_Check(key)) {
- PyErr_Format(PyExc_TypeError,
- "%.200s%.200s keywords must be strings",
- PyEval_GetFuncName(func),
- PyEval_GetFuncDesc(func));
- } else {
- PyErr_Format(PyExc_TypeError,
- "%.200s%.200s got multiple "
- "values for keyword argument '%U'",
- PyEval_GetFuncName(func),
- PyEval_GetFuncDesc(func),
- key);
- }
- Py_DECREF(intersection);
- Py_DECREF(sum);
+ PyErr_Clear();
+ ann_dict = PyDict_New();
+ if (ann_dict == NULL) {
+ goto error;
+ }
+ err = PyObject_SetItem(f->f_locals, ann_str, ann_dict);
+ Py_DECREF(ann_dict);
+ if (err != 0) {
goto error;
}
- Py_DECREF(intersection);
}
+ else {
+ Py_DECREF(ann_dict);
+ }
+ }
+ DISPATCH();
+ }
+
+ TARGET(BUILD_CONST_KEY_MAP) {
+ Py_ssize_t i;
+ PyObject *map;
+ PyObject *keys = TOP();
+ if (!PyTuple_CheckExact(keys) ||
+ PyTuple_GET_SIZE(keys) != (Py_ssize_t)oparg) {
+ PyErr_SetString(PyExc_SystemError,
+ "bad BUILD_CONST_KEY_MAP keys argument");
+ goto error;
+ }
+ map = _PyDict_NewPresized((Py_ssize_t)oparg);
+ if (map == NULL) {
+ goto error;
+ }
+ for (i = oparg; i > 0; i--) {
+ int err;
+ PyObject *key = PyTuple_GET_ITEM(keys, oparg - i);
+ PyObject *value = PEEK(i + 1);
+ err = PyDict_SetItem(map, key, value);
+ if (err != 0) {
+ Py_DECREF(map);
+ goto error;
+ }
+ }
+
+ Py_DECREF(POP());
+ while (oparg--) {
+ Py_DECREF(POP());
+ }
+ PUSH(map);
+ DISPATCH();
+ }
+
+ TARGET(BUILD_MAP_UNPACK) {
+ Py_ssize_t i;
+ PyObject *sum = PyDict_New();
+ if (sum == NULL)
+ goto error;
+ for (i = oparg; i > 0; i--) {
+ PyObject *arg = PEEK(i);
if (PyDict_Update(sum, arg) < 0) {
if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
- if (with_call) {
- int function_location = (oparg>>8) & 0xff;
- PyObject *func = PEEK(function_location + num_maps);
- PyErr_Format(PyExc_TypeError,
- "%.200s%.200s argument after ** "
- "must be a mapping, not %.200s",
- PyEval_GetFuncName(func),
- PyEval_GetFuncDesc(func),
- arg->ob_type->tp_name);
+ PyErr_Format(PyExc_TypeError,
+ "'%.200s' object is not a mapping",
+ arg->ob_type->tp_name);
+ }
+ Py_DECREF(sum);
+ goto error;
+ }
+ }
+
+ while (oparg--)
+ Py_DECREF(POP());
+ PUSH(sum);
+ DISPATCH();
+ }
+
+ TARGET(BUILD_MAP_UNPACK_WITH_CALL) {
+ Py_ssize_t i;
+ PyObject *sum = PyDict_New();
+ if (sum == NULL)
+ goto error;
+
+ for (i = oparg; i > 0; i--) {
+ PyObject *arg = PEEK(i);
+ if (_PyDict_MergeEx(sum, arg, 2) < 0) {
+ PyObject *func = PEEK(2 + oparg);
+ if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s%.200s argument after ** "
+ "must be a mapping, not %.200s",
+ PyEval_GetFuncName(func),
+ PyEval_GetFuncDesc(func),
+ arg->ob_type->tp_name);
+ }
+ else if (PyErr_ExceptionMatches(PyExc_KeyError)) {
+ PyObject *exc, *val, *tb;
+ PyErr_Fetch(&exc, &val, &tb);
+ if (val && PyTuple_Check(val) && PyTuple_GET_SIZE(val) == 1) {
+ PyObject *key = PyTuple_GET_ITEM(val, 0);
+ if (!PyUnicode_Check(key)) {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s%.200s keywords must be strings",
+ PyEval_GetFuncName(func),
+ PyEval_GetFuncDesc(func));
+ } else {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s%.200s got multiple "
+ "values for keyword argument '%U'",
+ PyEval_GetFuncName(func),
+ PyEval_GetFuncDesc(func),
+ key);
+ }
+ Py_XDECREF(exc);
+ Py_XDECREF(val);
+ Py_XDECREF(tb);
}
else {
- PyErr_Format(PyExc_TypeError,
- "'%.200s' object is not a mapping",
- arg->ob_type->tp_name);
+ PyErr_Restore(exc, val, tb);
}
}
Py_DECREF(sum);