|
3 | 3 | #include "Python.h"
|
4 | 4 | #include "pycore_abstract.h" // _PyIndex_Check()
|
5 | 5 | #include "pycore_ceval.h" // _PyEval_GetBuiltin()
|
| 6 | +#include "pycore_dict.h" // _PyDictViewObject |
6 | 7 | #include "pycore_pyatomic_ft_wrappers.h"
|
7 | 8 | #include "pycore_interp.h" // PyInterpreterState.list
|
8 | 9 | #include "pycore_list.h" // struct _Py_list_freelist, _PyListIterObject
|
@@ -1295,6 +1296,30 @@ list_extend_set(PyListObject *self, PySetObject *other)
|
1295 | 1296 | return 0;
|
1296 | 1297 | }
|
1297 | 1298 |
|
| 1299 | +static int |
| 1300 | +list_extend_dict(PyListObject *self, PyDictObject *dict, int which_item) |
| 1301 | +{ |
| 1302 | + // which_item: 0 for keys and 1 for values |
| 1303 | + Py_ssize_t m = Py_SIZE(self); |
| 1304 | + Py_ssize_t n = PyDict_GET_SIZE(dict); |
| 1305 | + if (list_resize(self, m + n) < 0) { |
| 1306 | + return -1; |
| 1307 | + } |
| 1308 | + |
| 1309 | + PyObject **dest = self->ob_item + m; |
| 1310 | + Py_ssize_t pos = 0; |
| 1311 | + PyObject *keyvalue[2]; |
| 1312 | + while (_PyDict_Next((PyObject *)dict, &pos, &keyvalue[0], &keyvalue[1], NULL)) { |
| 1313 | + PyObject *obj = keyvalue[which_item]; |
| 1314 | + Py_INCREF(obj); |
| 1315 | + *dest = obj; |
| 1316 | + dest++; |
| 1317 | + } |
| 1318 | + |
| 1319 | + Py_SET_SIZE(self, m + n); |
| 1320 | + return 0; |
| 1321 | +} |
| 1322 | + |
1298 | 1323 | static int
|
1299 | 1324 | _list_extend(PyListObject *self, PyObject *iterable)
|
1300 | 1325 | {
|
@@ -1322,6 +1347,18 @@ _list_extend(PyListObject *self, PyObject *iterable)
|
1322 | 1347 | res = list_extend_set(self, (PySetObject *)iterable);
|
1323 | 1348 | Py_END_CRITICAL_SECTION2();
|
1324 | 1349 | }
|
| 1350 | + else if (Py_IS_TYPE(iterable, &PyDictKeys_Type)) { |
| 1351 | + PyDictObject *dict = ((_PyDictViewObject *)iterable)->dv_dict; |
| 1352 | + Py_BEGIN_CRITICAL_SECTION2(self, dict); |
| 1353 | + res = list_extend_dict(self, dict, 0 /*keys*/); |
| 1354 | + Py_END_CRITICAL_SECTION2(); |
| 1355 | + } |
| 1356 | + else if (Py_IS_TYPE(iterable, &PyDictValues_Type)) { |
| 1357 | + PyDictObject *dict = ((_PyDictViewObject *)iterable)->dv_dict; |
| 1358 | + Py_BEGIN_CRITICAL_SECTION2(self, dict); |
| 1359 | + res = list_extend_dict(self, dict, 1 /*values*/); |
| 1360 | + Py_END_CRITICAL_SECTION2(); |
| 1361 | + } |
1325 | 1362 | else {
|
1326 | 1363 | Py_BEGIN_CRITICAL_SECTION(self);
|
1327 | 1364 | res = list_extend_iter_lock_held(self, iterable);
|
|
0 commit comments