Nuitka
The Python compiler
Loading...
Searching...
No Matches
HelpersDictionariesGenerated.c
1// Copyright 2025, Kay Hayen, mailto:kay.hayen@gmail.com find license text at end of file
2
3/* This file is included from another C file, help IDEs to still parse it on its own. */
4#ifdef __IDE_ONLY__
5#include "nuitka/prelude.h"
6#endif
7
8/* WARNING, this code is GENERATED. Modify the template HelperDictionaryCopy.c.j2 instead! */
9
10PyObject *DICT_COPY(PyThreadState *tstate, PyObject *dict_value) {
11#if _NUITKA_EXPERIMENTAL_DISABLE_DICT_OPT
12 CHECK_OBJECT(dict_value);
13 assert(PyDict_CheckExact(dict_value));
14
15 return PyDict_Copy(dict_value);
16#else
17 PyObject *result;
18 Py_BEGIN_CRITICAL_SECTION(dict_value);
19
20 CHECK_OBJECT(dict_value);
21 assert(PyDict_CheckExact(dict_value));
22
23 if (((PyDictObject *)dict_value)->ma_used == 0) {
24 result = MAKE_DICT_EMPTY(tstate);
25 } else {
26 PyDictObject *dict_mp = (PyDictObject *)dict_value;
27
28#if PYTHON_VERSION < 0x300
29 // For Python3, this can be done much faster in the same way as it is
30 // done in parameter parsing.
31 result = _PyDict_NewPresized(dict_mp->ma_used);
32
33 for (Py_ssize_t i = 0; i <= dict_mp->ma_mask; i++) {
34 PyDictEntry *entry = &dict_mp->ma_table[i];
35
36 if (entry->me_value != NULL) {
37 PyObject *key = entry->me_key;
38
39 PyObject *value = entry->me_value;
40
41 NUITKA_MAY_BE_UNUSED int res = PyDict_SetItem(result, key, value);
42 assert(res == 0);
43 }
44 }
45#else
46 /* Python 3 */
47 if (_PyDict_HasSplitTable(dict_mp)) {
48 PyDictObject *result_mp = _Nuitka_AllocatePyDictObject(tstate);
49 assert(result_mp != NULL);
50 result = (PyObject *)result_mp;
51
52#if PYTHON_VERSION < 0x3b0
53 Py_ssize_t size = DK_ENTRIES_SIZE(dict_mp->ma_keys);
54#else
55 Py_ssize_t size = dict_mp->ma_keys->dk_nentries + dict_mp->ma_keys->dk_usable;
56#endif
57
58#if PYTHON_VERSION < 0x3d0
59 PyDictValues *new_values = _Nuitka_PyDict_new_values(size);
60 assert(new_values != NULL);
61
62#if PYTHON_VERSION >= 0x3b0
63 // Need to preserve values prefix.
64 size_t prefix_size = ((uint8_t *)new_values)[-1];
65 memcpy((char *)new_values - prefix_size, (char *)dict_mp->ma_values - prefix_size, prefix_size - 1);
66#endif
67#else
68 PyDictValues *new_values = _Nuitka_PyDict_copy_values(dict_mp->ma_values);
69#endif
70
71 result_mp->ma_values = new_values;
72 result_mp->ma_keys = dict_mp->ma_keys;
73 result_mp->ma_used = dict_mp->ma_used;
74
75 // This is a manual reference count for the keys.
76#ifdef Py_REF_DEBUG
77 _Py_RefTotal++;
78#endif
79 dict_mp->ma_keys->dk_refcnt += 1;
80
81 for (Py_ssize_t i = 0; i < size; i++) {
82 if (DK_VALUE(dict_mp, i)) {
83 PyObject *value = DK_VALUE(dict_mp, i);
84
85 DK_VALUE(result_mp, i) = value;
86 Py_INCREF(value);
87
88 } else {
89 DK_VALUE(result_mp, i) = NULL;
90 }
91 }
92
93 Nuitka_GC_Track(result_mp);
94 } else
95#if PYTHON_VERSION >= 0x360
96 // Fast dictionary copy if it has at least 2/3 space usage. This is most relevant
97 // for the DICT_COPY, where it might even be the intention to trigger a shrink with
98 // a fresh copy.
99 if (dict_mp->ma_values == NULL && IS_COMPACT(dict_mp)) {
100 assert(dict_mp->ma_values == NULL);
101 assert(dict_mp->ma_keys->dk_refcnt == 1);
102
103 PyDictObject *result_mp = _Nuitka_AllocatePyDictObject(tstate);
104 result = (PyObject *)result_mp;
105
106 result_mp->ma_values = NULL;
107 result_mp->ma_used = dict_mp->ma_used;
108
109 Py_ssize_t keys_size = _Nuitka_Py_PyDict_KeysSize(dict_mp->ma_keys);
110 result_mp->ma_keys = _Nuitka_AllocatePyDictKeysObject(tstate, keys_size);
111 assert(result_mp->ma_keys);
112
113 memcpy(result_mp->ma_keys, dict_mp->ma_keys, keys_size);
114
115 // Take reference of all keys and values.
116#if PYTHON_VERSION < 0x3b0
117 PyDictKeyEntry *entries = DK_ENTRIES(result_mp->ma_keys);
118 Py_ssize_t size = DK_ENTRIES_SIZE(result_mp->ma_keys);
119
120 for (Py_ssize_t i = 0; i < size; i++) {
121 PyDictKeyEntry *entry = &entries[i];
122 PyObject *value = entry->me_value;
123
124 if (value != NULL) {
125 PyObject *key = entry->me_key;
126
127 Py_INCREF(key);
128
129 Py_INCREF(value);
130 }
131 }
132#else
133 PyObject **key_ptr, **value_ptr;
134 size_t entry_size;
135
136 bool is_unicode = DK_IS_UNICODE(result_mp->ma_keys);
137
138 if (is_unicode) {
139 PyDictUnicodeEntry *ep0 = DK_UNICODE_ENTRIES(result_mp->ma_keys);
140
141 key_ptr = &ep0->me_key;
142 value_ptr = &ep0->me_value;
143 entry_size = sizeof(PyDictUnicodeEntry) / sizeof(PyObject *);
144 } else {
145 PyDictKeyEntry *ep0 = DK_ENTRIES(result_mp->ma_keys);
146
147 key_ptr = &ep0->me_key;
148 value_ptr = &ep0->me_value;
149 entry_size = sizeof(PyDictKeyEntry) / sizeof(PyObject *);
150 }
151
152 Py_ssize_t size = DK_ENTRIES_SIZE(result_mp->ma_keys);
153
154 for (Py_ssize_t i = 0; i < size; i++) {
155 PyObject *value = *value_ptr;
156
157 if (value != NULL) {
158
159 Py_INCREF(value);
160 PyObject *key = *key_ptr;
161 Py_INCREF(key);
162 }
163
164 value_ptr += entry_size;
165 key_ptr += entry_size;
166 }
167#endif
168
169 // The new keys are an object counted.
170#ifdef Py_REF_DEBUG
171 _Py_RefTotal++;
172#endif
173
174 Nuitka_GC_Track(result_mp);
175 } else
176#endif
177 {
178 result = _PyDict_NewPresized(dict_mp->ma_used);
179
180#if PYTHON_VERSION < 0x3b0
181 Py_ssize_t size = DK_ENTRIES_SIZE(dict_mp->ma_keys);
182
183 for (Py_ssize_t i = 0; i < size; i++) {
184 PyDictKeyEntry *entry = &DK_ENTRIES(dict_mp->ma_keys)[i];
185 PyObject *value = entry->me_value;
186
187 if (value != NULL) {
188 PyObject *key = entry->me_key;
189 CHECK_OBJECT(key);
190
191 CHECK_OBJECT(value);
192
193 NUITKA_MAY_BE_UNUSED int res = PyDict_SetItem(result, key, value);
194 assert(res == 0);
195 }
196 }
197#else
198 Py_ssize_t pos = 0;
199 PyObject *key, *value;
200
201 while (Nuitka_DictNext((PyObject *)dict_mp, &pos, &key, &value)) {
202 CHECK_OBJECT(key);
203 CHECK_OBJECT(value);
204
205 CHECK_OBJECT(value);
206
207 NUITKA_MAY_BE_UNUSED int res = PyDict_SetItem(result, key, value);
208 assert(res == 0);
209 }
210#endif
211 }
212#endif
213 }
214
215 Py_END_CRITICAL_SECTION();
216 return result;
217#endif
218}
219
220PyObject *DEEP_COPY_DICT(PyThreadState *tstate, PyObject *dict_value) {
221 PyObject *result;
222
223#if _NUITKA_EXPERIMENTAL_DISABLE_DICT_OPT
224 CHECK_OBJECT(dict_value);
225 assert(PyDict_CheckExact(dict_value));
226
227 result = DICT_COPY(tstate, dict_value);
228
229 Py_ssize_t pos = 0;
230 PyObject *key, *value;
231
232 while (Nuitka_DictNext(dict_value, &pos, &key, &value)) {
233 PyObject *dict_value_copy = DEEP_COPY(tstate, value);
234
235 if (dict_value_copy != value) {
236 DICT_SET_ITEM(result, key, value);
237 }
238 }
239#else
240 Py_BEGIN_CRITICAL_SECTION(dict_value);
241
242 CHECK_OBJECT(dict_value);
243 assert(PyDict_CheckExact(dict_value));
244
245 if (((PyDictObject *)dict_value)->ma_used == 0) {
246 result = MAKE_DICT_EMPTY(tstate);
247 } else {
248 PyDictObject *dict_mp = (PyDictObject *)dict_value;
249
250#if PYTHON_VERSION < 0x300
251 // For Python3, this can be done much faster in the same way as it is
252 // done in parameter parsing.
253 result = _PyDict_NewPresized(dict_mp->ma_used);
254
255 for (Py_ssize_t i = 0; i <= dict_mp->ma_mask; i++) {
256 PyDictEntry *entry = &dict_mp->ma_table[i];
257
258 if (entry->me_value != NULL) {
259 PyObject *key = entry->me_key;
260
261 PyObject *value = entry->me_value;
262 value = DEEP_COPY(tstate, value);
263
264 NUITKA_MAY_BE_UNUSED int res = PyDict_SetItem(result, key, value);
265 assert(res == 0);
266
267 Py_DECREF(value);
268 }
269 }
270#else
271 /* Python 3 */
272 if (_PyDict_HasSplitTable(dict_mp)) {
273 PyDictObject *result_mp = _Nuitka_AllocatePyDictObject(tstate);
274 assert(result_mp != NULL);
275 result = (PyObject *)result_mp;
276
277#if PYTHON_VERSION < 0x3b0
278 Py_ssize_t size = DK_ENTRIES_SIZE(dict_mp->ma_keys);
279#else
280 Py_ssize_t size = dict_mp->ma_keys->dk_nentries + dict_mp->ma_keys->dk_usable;
281#endif
282
283#if PYTHON_VERSION < 0x3d0
284 PyDictValues *new_values = _Nuitka_PyDict_new_values(size);
285 assert(new_values != NULL);
286
287#if PYTHON_VERSION >= 0x3b0
288 // Need to preserve values prefix.
289 size_t prefix_size = ((uint8_t *)new_values)[-1];
290 memcpy((char *)new_values - prefix_size, (char *)dict_mp->ma_values - prefix_size, prefix_size - 1);
291#endif
292#else
293 PyDictValues *new_values = _Nuitka_PyDict_copy_values(dict_mp->ma_values);
294#endif
295
296 result_mp->ma_values = new_values;
297 result_mp->ma_keys = dict_mp->ma_keys;
298 result_mp->ma_used = dict_mp->ma_used;
299
300 // This is a manual reference count for the keys.
301#ifdef Py_REF_DEBUG
302 _Py_RefTotal++;
303#endif
304 dict_mp->ma_keys->dk_refcnt += 1;
305
306 for (Py_ssize_t i = 0; i < size; i++) {
307 if (DK_VALUE(dict_mp, i)) {
308 PyObject *value = DK_VALUE(dict_mp, i);
309 value = DEEP_COPY(tstate, value);
310
311 DK_VALUE(result_mp, i) = value;
312
313 } else {
314 DK_VALUE(result_mp, i) = NULL;
315 }
316 }
317
318 Nuitka_GC_Track(result_mp);
319 } else
320#if PYTHON_VERSION >= 0x360
321 // Fast dictionary copy if it has at least 2/3 space usage. This is most relevant
322 // for the DICT_COPY, where it might even be the intention to trigger a shrink with
323 // a fresh copy.
324 if (dict_mp->ma_values == NULL && IS_COMPACT(dict_mp)) {
325 assert(dict_mp->ma_values == NULL);
326 assert(dict_mp->ma_keys->dk_refcnt == 1);
327
328 PyDictObject *result_mp = _Nuitka_AllocatePyDictObject(tstate);
329 result = (PyObject *)result_mp;
330
331 result_mp->ma_values = NULL;
332 result_mp->ma_used = dict_mp->ma_used;
333
334 Py_ssize_t keys_size = _Nuitka_Py_PyDict_KeysSize(dict_mp->ma_keys);
335 result_mp->ma_keys = _Nuitka_AllocatePyDictKeysObject(tstate, keys_size);
336 assert(result_mp->ma_keys);
337
338 memcpy(result_mp->ma_keys, dict_mp->ma_keys, keys_size);
339
340 // Take reference of all keys and values.
341#if PYTHON_VERSION < 0x3b0
342 PyDictKeyEntry *entries = DK_ENTRIES(result_mp->ma_keys);
343 Py_ssize_t size = DK_ENTRIES_SIZE(result_mp->ma_keys);
344
345 for (Py_ssize_t i = 0; i < size; i++) {
346 PyDictKeyEntry *entry = &entries[i];
347 PyObject *value = entry->me_value;
348
349 if (value != NULL) {
350 PyObject *key = entry->me_key;
351
352 Py_INCREF(key);
353
354 value = DEEP_COPY(tstate, value);
355
356 entry->me_value = value;
357 }
358 }
359#else
360 PyObject **key_ptr, **value_ptr;
361 size_t entry_size;
362
363 bool is_unicode = DK_IS_UNICODE(result_mp->ma_keys);
364
365 if (is_unicode) {
366 PyDictUnicodeEntry *ep0 = DK_UNICODE_ENTRIES(result_mp->ma_keys);
367
368 key_ptr = &ep0->me_key;
369 value_ptr = &ep0->me_value;
370 entry_size = sizeof(PyDictUnicodeEntry) / sizeof(PyObject *);
371 } else {
372 PyDictKeyEntry *ep0 = DK_ENTRIES(result_mp->ma_keys);
373
374 key_ptr = &ep0->me_key;
375 value_ptr = &ep0->me_value;
376 entry_size = sizeof(PyDictKeyEntry) / sizeof(PyObject *);
377 }
378
379 Py_ssize_t size = DK_ENTRIES_SIZE(result_mp->ma_keys);
380
381 for (Py_ssize_t i = 0; i < size; i++) {
382 PyObject *value = *value_ptr;
383
384 if (value != NULL) {
385 value = DEEP_COPY(tstate, value);
386 *value_ptr = value;
387 PyObject *key = *key_ptr;
388 Py_INCREF(key);
389 }
390
391 value_ptr += entry_size;
392 key_ptr += entry_size;
393 }
394#endif
395
396 // The new keys are an object counted.
397#ifdef Py_REF_DEBUG
398 _Py_RefTotal++;
399#endif
400
401 Nuitka_GC_Track(result_mp);
402 } else
403#endif
404 {
405 result = _PyDict_NewPresized(dict_mp->ma_used);
406
407#if PYTHON_VERSION < 0x3b0
408 Py_ssize_t size = DK_ENTRIES_SIZE(dict_mp->ma_keys);
409
410 for (Py_ssize_t i = 0; i < size; i++) {
411 PyDictKeyEntry *entry = &DK_ENTRIES(dict_mp->ma_keys)[i];
412 PyObject *value = entry->me_value;
413
414 if (value != NULL) {
415 PyObject *key = entry->me_key;
416 CHECK_OBJECT(key);
417
418 CHECK_OBJECT(value);
419
420 value = DEEP_COPY(tstate, value);
421
422 NUITKA_MAY_BE_UNUSED int res = PyDict_SetItem(result, key, value);
423 assert(res == 0);
424
425 Py_DECREF(value);
426 }
427 }
428#else
429 Py_ssize_t pos = 0;
430 PyObject *key, *value;
431
432 while (Nuitka_DictNext((PyObject *)dict_mp, &pos, &key, &value)) {
433 CHECK_OBJECT(key);
434 CHECK_OBJECT(value);
435
436 CHECK_OBJECT(value);
437
438 value = DEEP_COPY(tstate, value);
439
440 NUITKA_MAY_BE_UNUSED int res = PyDict_SetItem(result, key, value);
441 assert(res == 0);
442
443 Py_DECREF(value);
444 }
445#endif
446 }
447#endif
448 }
449
450 Py_END_CRITICAL_SECTION();
451#endif
452
453 return result;
454}
455
456// Helper for function calls with star dict arguments. */
457static PyObject *COPY_DICT_KW(PyThreadState *tstate, PyObject *dict_value) {
458 PyObject *result;
459 bool had_kw_error = false;
460
461#if _NUITKA_EXPERIMENTAL_DISABLE_DICT_OPT
462 CHECK_OBJECT(dict_value);
463 assert(PyDict_CheckExact(dict_value));
464
465 result = DICT_COPY(tstate, dict_value);
466
467 Py_ssize_t pos = 0;
468 PyObject *key, *value;
469
470 while (Nuitka_DictNext(dict_value, &pos, &key, &value)) {
471 if (unlikely(!checkKeywordType(key))) {
472 had_kw_error = true;
473 }
474 }
475#else
476 Py_BEGIN_CRITICAL_SECTION(dict_value);
477
478 CHECK_OBJECT(dict_value);
479 assert(PyDict_CheckExact(dict_value));
480
481 if (((PyDictObject *)dict_value)->ma_used == 0) {
482 result = MAKE_DICT_EMPTY(tstate);
483 } else {
484 PyDictObject *dict_mp = (PyDictObject *)dict_value;
485
486#if PYTHON_VERSION < 0x300
487 // For Python3, this can be done much faster in the same way as it is
488 // done in parameter parsing.
489 result = _PyDict_NewPresized(dict_mp->ma_used);
490
491 for (Py_ssize_t i = 0; i <= dict_mp->ma_mask; i++) {
492 PyDictEntry *entry = &dict_mp->ma_table[i];
493
494 if (entry->me_value != NULL) {
495 PyObject *key = entry->me_key;
496 if (unlikely(!checkKeywordType(key))) {
497 had_kw_error = true;
498 }
499
500 PyObject *value = entry->me_value;
501
502 NUITKA_MAY_BE_UNUSED int res = PyDict_SetItem(result, key, value);
503 assert(res == 0);
504 }
505 }
506#else
507 /* Python 3 */
508 if (_PyDict_HasSplitTable(dict_mp)) {
509 PyDictObject *result_mp = _Nuitka_AllocatePyDictObject(tstate);
510 assert(result_mp != NULL);
511 result = (PyObject *)result_mp;
512
513#if PYTHON_VERSION < 0x3b0
514 Py_ssize_t size = DK_ENTRIES_SIZE(dict_mp->ma_keys);
515#else
516 Py_ssize_t size = dict_mp->ma_keys->dk_nentries + dict_mp->ma_keys->dk_usable;
517#endif
518#if PYTHON_VERSION < 0x3b0
519 for (Py_ssize_t i = 0; i < size; i++) {
520 PyDictKeyEntry *entry = &DK_ENTRIES(dict_mp->ma_keys)[i];
521
522 if (entry->me_value != NULL) {
523 PyObject *key = entry->me_key;
524 if (unlikely(!checkKeywordType(key))) {
525 had_kw_error = true;
526 }
527 }
528#else
529 Py_ssize_t pos = 0;
530 PyObject *key, *_value;
531
532 while (Nuitka_DictNext((PyObject *)dict_mp, &pos, &key, &_value)) {
533 CHECK_OBJECT(key);
534 CHECK_OBJECT(_value);
535
536 if (unlikely(!checkKeywordType(key))) {
537 had_kw_error = true;
538 }
539#endif
540 }
541
542#if PYTHON_VERSION < 0x3d0
543 PyDictValues *new_values = _Nuitka_PyDict_new_values(size);
544 assert(new_values != NULL);
545
546#if PYTHON_VERSION >= 0x3b0
547 // Need to preserve values prefix.
548 size_t prefix_size = ((uint8_t *)new_values)[-1];
549 memcpy((char *)new_values - prefix_size, (char *)dict_mp->ma_values - prefix_size, prefix_size - 1);
550#endif
551#else
552 PyDictValues *new_values = _Nuitka_PyDict_copy_values(dict_mp->ma_values);
553#endif
554
555 result_mp->ma_values = new_values;
556 result_mp->ma_keys = dict_mp->ma_keys;
557 result_mp->ma_used = dict_mp->ma_used;
558
559 // This is a manual reference count for the keys.
560#ifdef Py_REF_DEBUG
561 _Py_RefTotal++;
562#endif
563 dict_mp->ma_keys->dk_refcnt += 1;
564
565 for (Py_ssize_t i = 0; i < size; i++) {
566 if (DK_VALUE(dict_mp, i)) {
567 PyObject *value = DK_VALUE(dict_mp, i);
568
569 DK_VALUE(result_mp, i) = value;
570 Py_INCREF(value);
571
572 } else {
573 DK_VALUE(result_mp, i) = NULL;
574 }
575 }
576
577 Nuitka_GC_Track(result_mp);
578 } else
579#if PYTHON_VERSION >= 0x360
580 // Fast dictionary copy if it has at least 2/3 space usage. This is most relevant
581 // for the DICT_COPY, where it might even be the intention to trigger a shrink with
582 // a fresh copy.
583 if (dict_mp->ma_values == NULL && IS_COMPACT(dict_mp)) {
584 assert(dict_mp->ma_values == NULL);
585 assert(dict_mp->ma_keys->dk_refcnt == 1);
586
587 PyDictObject *result_mp = _Nuitka_AllocatePyDictObject(tstate);
588 result = (PyObject *)result_mp;
589
590 result_mp->ma_values = NULL;
591 result_mp->ma_used = dict_mp->ma_used;
592
593 Py_ssize_t keys_size = _Nuitka_Py_PyDict_KeysSize(dict_mp->ma_keys);
594 result_mp->ma_keys = _Nuitka_AllocatePyDictKeysObject(tstate, keys_size);
595 assert(result_mp->ma_keys);
596
597 memcpy(result_mp->ma_keys, dict_mp->ma_keys, keys_size);
598
599 // Take reference of all keys and values.
600#if PYTHON_VERSION < 0x3b0
601 PyDictKeyEntry *entries = DK_ENTRIES(result_mp->ma_keys);
602 Py_ssize_t size = DK_ENTRIES_SIZE(result_mp->ma_keys);
603
604 for (Py_ssize_t i = 0; i < size; i++) {
605 PyDictKeyEntry *entry = &entries[i];
606 PyObject *value = entry->me_value;
607
608 if (value != NULL) {
609 PyObject *key = entry->me_key;
610 if (unlikely(!checkKeywordType(key))) {
611 had_kw_error = true;
612 }
613 Py_INCREF(key);
614
615 Py_INCREF(value);
616 }
617 }
618#else
619 PyObject **key_ptr, **value_ptr;
620 size_t entry_size;
621
622 bool is_unicode = DK_IS_UNICODE(result_mp->ma_keys);
623
624 if (is_unicode) {
625 PyDictUnicodeEntry *ep0 = DK_UNICODE_ENTRIES(result_mp->ma_keys);
626
627 key_ptr = &ep0->me_key;
628 value_ptr = &ep0->me_value;
629 entry_size = sizeof(PyDictUnicodeEntry) / sizeof(PyObject *);
630 } else {
631 PyDictKeyEntry *ep0 = DK_ENTRIES(result_mp->ma_keys);
632
633 key_ptr = &ep0->me_key;
634 value_ptr = &ep0->me_value;
635 entry_size = sizeof(PyDictKeyEntry) / sizeof(PyObject *);
636 }
637
638 Py_ssize_t size = DK_ENTRIES_SIZE(result_mp->ma_keys);
639
640 for (Py_ssize_t i = 0; i < size; i++) {
641 PyObject *value = *value_ptr;
642
643 if (value != NULL) {
644
645 Py_INCREF(value);
646 PyObject *key = *key_ptr;
647 if (is_unicode == false) {
648 if (unlikely(!checkKeywordType(key))) {
649 had_kw_error = true;
650 }
651 }
652 Py_INCREF(key);
653 }
654
655 value_ptr += entry_size;
656 key_ptr += entry_size;
657 }
658#endif
659
660 // The new keys are an object counted.
661#ifdef Py_REF_DEBUG
662 _Py_RefTotal++;
663#endif
664
665 Nuitka_GC_Track(result_mp);
666 } else
667#endif
668 {
669 result = _PyDict_NewPresized(dict_mp->ma_used);
670
671#if PYTHON_VERSION < 0x3b0
672 Py_ssize_t size = DK_ENTRIES_SIZE(dict_mp->ma_keys);
673
674 for (Py_ssize_t i = 0; i < size; i++) {
675 PyDictKeyEntry *entry = &DK_ENTRIES(dict_mp->ma_keys)[i];
676 PyObject *value = entry->me_value;
677
678 if (value != NULL) {
679 PyObject *key = entry->me_key;
680 CHECK_OBJECT(key);
681
682 if (unlikely(!checkKeywordType(key))) {
683 had_kw_error = true;
684 }
685
686 CHECK_OBJECT(value);
687
688 NUITKA_MAY_BE_UNUSED int res = PyDict_SetItem(result, key, value);
689 assert(res == 0);
690 }
691 }
692#else
693 Py_ssize_t pos = 0;
694 PyObject *key, *value;
695
696 while (Nuitka_DictNext((PyObject *)dict_mp, &pos, &key, &value)) {
697 CHECK_OBJECT(key);
698 CHECK_OBJECT(value);
699
700 if (unlikely(!checkKeywordType(key))) {
701 had_kw_error = true;
702 }
703
704 CHECK_OBJECT(value);
705
706 NUITKA_MAY_BE_UNUSED int res = PyDict_SetItem(result, key, value);
707 assert(res == 0);
708 }
709#endif
710 }
711#endif
712 }
713
714 Py_END_CRITICAL_SECTION();
715#endif
716
717 if (unlikely(had_kw_error)) {
718 Py_DECREF(result);
719 return NULL;
720 }
721
722 return result;
723}
724
725// Part of "Nuitka", an optimizing Python compiler that is compatible and
726// integrates with CPython, but also works on its own.
727//
728// Licensed under the Apache License, Version 2.0 (the "License");
729// you may not use this file except in compliance with the License.
730// You may obtain a copy of the License at
731//
732// http://www.apache.org/licenses/LICENSE-2.0
733//
734// Unless required by applicable law or agreed to in writing, software
735// distributed under the License is distributed on an "AS IS" BASIS,
736// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
737// See the License for the specific language governing permissions and
738// limitations under the License.