Skip to content

Commit 202be0f

Browse files
committed
gpt round 1
1 parent 6a2c6f8 commit 202be0f

File tree

3 files changed

+129
-39
lines changed

3 files changed

+129
-39
lines changed

mypyc/lib-rt/CPy.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -703,6 +703,21 @@ tuple_T3CIO CPyDict_NextValue(PyObject *dict_or_iter, CPyTagged offset);
703703
tuple_T4CIOO CPyDict_NextItem(PyObject *dict_or_iter, CPyTagged offset);
704704
int CPyMapping_Check(PyObject *obj);
705705

706+
// Unsafe dict operations (assume PyDict_CheckExact(dict) is always true)
707+
PyObject *CPyDict_GetItemUnsafe(PyObject *dict, PyObject *key);
708+
int CPyDict_SetItemUnsafe(PyObject *dict, PyObject *key, PyObject *value);
709+
PyObject *CPyDict_KeysViewUnsafe(PyObject *dict);
710+
PyObject *CPyDict_ValuesViewUnsafe(PyObject *dict);
711+
PyObject *CPyDict_ItemsViewUnsafe(PyObject *dict);
712+
PyObject *CPyDict_KeysUnsafe(PyObject *dict);
713+
PyObject *CPyDict_ValuesUnsafe(PyObject *dict);
714+
PyObject *CPyDict_ItemsUnsafe(PyObject *dict);
715+
char CPyDict_ClearUnsafe(PyObject *dict);
716+
PyObject *CPyDict_CopyUnsafe(PyObject *dict);
717+
PyObject *CPyDict_GetKeysIterUnsafe(PyObject *dict);
718+
PyObject *CPyDict_GetItemsIterUnsafe(PyObject *dict);
719+
PyObject *CPyDict_GetValuesIterUnsafe(PyObject *dict);
720+
706721
// Check that dictionary didn't change size during iteration.
707722
static inline char CPyDict_CheckSize(PyObject *dict, Py_ssize_t size) {
708723
if (!PyDict_CheckExact(dict)) {

mypyc/lib-rt/dict_ops.c

Lines changed: 96 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,7 @@
1515
// some indirections.
1616
PyObject *CPyDict_GetItem(PyObject *dict, PyObject *key) {
1717
if (PyDict_CheckExact(dict)) {
18-
PyObject *res = PyDict_GetItemWithError(dict, key);
19-
if (!res) {
20-
if (!PyErr_Occurred()) {
21-
PyErr_SetObject(PyExc_KeyError, key);
22-
}
23-
} else {
24-
Py_INCREF(res);
25-
}
26-
return res;
18+
return CPyDict_GetItemUnsafe(dict, key);
2719
} else {
2820
return PyObject_GetItem(dict, key);
2921
}
@@ -168,23 +160,13 @@ int CPyDict_Update(PyObject *dict, PyObject *stuff) {
168160

169161
int CPyDict_UpdateFromAny(PyObject *dict, PyObject *stuff) {
170162
if (PyDict_CheckExact(dict)) {
171-
return CPyDict_UpdateFromAnyUnsafe(dict, stuff)
163+
// Argh this sucks
164+
return CPyDict_UpdateFromAnyUnsafe(dict, stuff);
172165
} else {
173166
return CPyDict_UpdateGeneral(dict, stuff);
174167
}
175168
}
176169

177-
// Unsafe because it assumes `dict` is an actual dict, never a subclass.
178-
int CPyDict_UpdateFromAnyUnsafe(PyObject *dict, PyObject *stuff) {
179-
// Argh this sucks
180-
_Py_IDENTIFIER(keys);
181-
if (PyDict_Check(stuff) || _CPyObject_HasAttrId(stuff, &PyId_keys)) {
182-
return PyDict_Update(dict, stuff);
183-
} else {
184-
return PyDict_MergeFromSeq2(dict, stuff, 1);
185-
}
186-
}
187-
188170
PyObject *CPyDict_FromAny(PyObject *obj) {
189171
if (PyDict_Check(obj)) {
190172
return PyDict_Copy(obj);
@@ -494,3 +476,96 @@ tuple_T4CIOO CPyDict_NextItem(PyObject *dict_or_iter, CPyTagged offset) {
494476
int CPyMapping_Check(PyObject *obj) {
495477
return Py_TYPE(obj)->tp_flags & Py_TPFLAGS_MAPPING;
496478
}
479+
480+
// =======================
481+
// Unsafe dict operations
482+
// =======================
483+
484+
// Unsafe: assumes dict is a true dict (PyDict_CheckExact(dict) is always true)
485+
486+
int CPyDict_UpdateFromAnyUnsafe(PyObject *dict, PyObject *stuff) {
487+
// Argh this sucks
488+
_Py_IDENTIFIER(keys);
489+
if (PyDict_Check(stuff) || _CPyObject_HasAttrId(stuff, &PyId_keys)) {
490+
return PyDict_Update(dict, stuff);
491+
} else {
492+
return PyDict_MergeFromSeq2(dict, stuff, 1);
493+
}
494+
}
495+
496+
PyObject *CPyDict_GetItemUnsafe(PyObject *dict, PyObject *key) {
497+
// No type check, direct call
498+
PyObject *res = PyDict_GetItemWithError(dict, key);
499+
if (!res) {
500+
if (!PyErr_Occurred()) {
501+
PyErr_SetObject(PyExc_KeyError, key);
502+
}
503+
} else {
504+
Py_INCREF(res);
505+
}
506+
return res;
507+
}
508+
509+
int CPyDict_SetItemUnsafe(PyObject *dict, PyObject *key, PyObject *value) {
510+
// No type check, direct call
511+
return PyDict_SetItem(dict, key, value);
512+
}
513+
514+
PyObject *CPyDict_KeysViewUnsafe(PyObject *dict) {
515+
// No type check, direct call
516+
return _CPyDictView_New(dict, &PyDictKeys_Type);
517+
}
518+
519+
PyObject *CPyDict_ValuesViewUnsafe(PyObject *dict) {
520+
// No type check, direct call
521+
return _CPyDictView_New(dict, &PyDictValues_Type);
522+
}
523+
524+
PyObject *CPyDict_ItemsViewUnsafe(PyObject *dict) {
525+
// No type check, direct call
526+
return _CPyDictView_New(dict, &PyDictItems_Type);
527+
}
528+
529+
PyObject *CPyDict_KeysUnsafe(PyObject *dict) {
530+
// No type check, direct call
531+
return PyDict_Keys(dict);
532+
}
533+
534+
PyObject *CPyDict_ValuesUnsafe(PyObject *dict) {
535+
// No type check, direct call
536+
return PyDict_Values(dict);
537+
}
538+
539+
PyObject *CPyDict_ItemsUnsafe(PyObject *dict) {
540+
// No type check, direct call
541+
return PyDict_Items(dict);
542+
}
543+
544+
char CPyDict_ClearUnsafe(PyObject *dict) {
545+
// No type check, direct call
546+
PyDict_Clear(dict);
547+
return 1;
548+
}
549+
550+
PyObject *CPyDict_CopyUnsafe(PyObject *dict) {
551+
// No type check, direct call
552+
return PyDict_Copy(dict);
553+
}
554+
555+
PyObject *CPyDict_GetKeysIterUnsafe(PyObject *dict) {
556+
// No type check, direct call
557+
Py_INCREF(dict);
558+
return dict;
559+
}
560+
561+
PyObject *CPyDict_GetItemsIterUnsafe(PyObject *dict) {
562+
// No type check, direct call
563+
Py_INCREF(dict);
564+
return dict;
565+
}
566+
567+
PyObject *CPyDict_GetValuesIterUnsafe(PyObject *dict) {
568+
// No type check, direct call
569+
Py_INCREF(dict);
570+
return dict;
571+
}

mypyc/primitives/dict_ops.py

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@
7777
name="__getitem__",
7878
arg_types=[true_dict_rprimitive, object_rprimitive],
7979
return_type=object_rprimitive,
80-
c_function_name="PyDict_GetItem",
80+
c_function_name="CPyDict_GetItemUnsafe",
8181
error_kind=ERR_MAGIC,
8282
)
8383

@@ -95,7 +95,7 @@
9595
name="__setitem__",
9696
arg_types=[true_dict_rprimitive, object_rprimitive, object_rprimitive],
9797
return_type=c_int_rprimitive,
98-
c_function_name="PyDict_SetItem",
98+
c_function_name="CPyDict_SetItemUnsafe",
9999
error_kind=ERR_NEG_INT,
100100
)
101101

@@ -155,7 +155,7 @@
155155
name="update",
156156
arg_types=[true_dict_rprimitive, dict_rprimitive],
157157
return_type=c_int_rprimitive,
158-
c_function_name="CPyDict_Update",
158+
c_function_name="PyDict_Update",
159159
error_kind=ERR_NEG_INT,
160160
priority=2,
161161
)
@@ -285,7 +285,7 @@
285285
name="keys",
286286
arg_types=[true_dict_rprimitive],
287287
return_type=object_rprimitive,
288-
c_function_name="CPyDict_KeysView",
288+
c_function_name="CPyDict_KeysViewUnsafe",
289289
error_kind=ERR_MAGIC,
290290
)
291291

@@ -303,7 +303,7 @@
303303
name="values",
304304
arg_types=[true_dict_rprimitive],
305305
return_type=object_rprimitive,
306-
c_function_name="CPyDict_ValuesView",
306+
c_function_name="CPyDict_ValuesViewUnsafe",
307307
error_kind=ERR_MAGIC,
308308
)
309309

@@ -321,7 +321,7 @@
321321
name="items",
322322
arg_types=[true_dict_rprimitive],
323323
return_type=object_rprimitive,
324-
c_function_name="CPyDict_ItemsView",
324+
c_function_name="CPyDict_ItemsViewUnsafe",
325325
error_kind=ERR_MAGIC,
326326
)
327327

@@ -339,7 +339,7 @@
339339
name="clear",
340340
arg_types=[true_dict_rprimitive],
341341
return_type=bit_rprimitive,
342-
c_function_name="PyDict_Clear",
342+
c_function_name="CPyDict_ClearUnsafe",
343343
error_kind=ERR_FALSE,
344344
)
345345

@@ -357,7 +357,7 @@
357357
name="copy",
358358
arg_types=[true_dict_rprimitive],
359359
return_type=true_dict_rprimitive,
360-
c_function_name="PyDict_Copy",
360+
c_function_name="CPyDict_CopyUnsafe",
361361
error_kind=ERR_MAGIC,
362362
)
363363

@@ -374,55 +374,55 @@
374374
true_dict_keys_op = custom_op(
375375
arg_types=[true_dict_rprimitive],
376376
return_type=list_rprimitive,
377-
c_function_name="PyDict_Keys",
377+
c_function_name="CPyDict_KeysUnsafe",
378378
error_kind=ERR_MAGIC,
379379
)
380380

381381
# list(dictorsubclass.keys())
382382
dict_keys_op = custom_op(
383383
arg_types=[dict_rprimitive],
384384
return_type=list_rprimitive,
385-
c_function_name="CPyDict_Keys",
385+
c_function_name="PyDict_Keys",
386386
error_kind=ERR_MAGIC,
387387
)
388388

389389
# list(dict.values())
390390
true_dict_values_op = custom_op(
391391
arg_types=[true_dict_rprimitive],
392392
return_type=list_rprimitive,
393-
c_function_name="PyDict_Values",
393+
c_function_name="CPyDict_ValuesUnsafe",
394394
error_kind=ERR_MAGIC,
395395
)
396396

397397
# list(dictorsubclass.values())
398398
dict_values_op = custom_op(
399399
arg_types=[dict_rprimitive],
400400
return_type=list_rprimitive,
401-
c_function_name="CPyDict_Values",
401+
c_function_name="PyDict_Values",
402402
error_kind=ERR_MAGIC,
403403
)
404404

405405
# list(dict.items())
406406
true_dict_items_op = custom_op(
407-
arg_types=[dict_rprimitive],
407+
arg_types=[true_dict_rprimitive],
408408
return_type=list_rprimitive,
409-
c_function_name="PyDict_Items",
409+
c_function_name="CPyDict_ItemsUnsafe",
410410
error_kind=ERR_MAGIC,
411411
)
412412

413413
# list(dictorsubclass.items())
414414
dict_items_op = custom_op(
415415
arg_types=[dict_rprimitive],
416416
return_type=list_rprimitive,
417-
c_function_name="CPyDict_Items",
417+
c_function_name="PyDict_Items",
418418
error_kind=ERR_MAGIC,
419419
)
420420

421421
# PyDict_Next() fast iteration
422422
true_dict_key_iter_op = custom_op(
423423
arg_types=[true_dict_rprimitive],
424424
return_type=object_rprimitive,
425-
c_function_name="CPyDict_GetKeysIter",
425+
c_function_name="CPyDict_GetKeysIterUnsafe",
426426
error_kind=ERR_MAGIC,
427427
)
428428

@@ -437,7 +437,7 @@
437437
true_dict_value_iter_op = custom_op(
438438
arg_types=[true_dict_rprimitive],
439439
return_type=object_rprimitive,
440-
c_function_name="CPyDict_GetValuesIter",
440+
c_function_name="CPyDict_GetValuesIterUnsafe",
441441
error_kind=ERR_MAGIC,
442442
)
443443

@@ -451,7 +451,7 @@
451451
true_dict_item_iter_op = custom_op(
452452
arg_types=[true_dict_rprimitive],
453453
return_type=object_rprimitive,
454-
c_function_name="CPyDict_GetItemsIter",
454+
c_function_name="CPyDict_GetItemsIterUnsafe",
455455
error_kind=ERR_MAGIC,
456456
)
457457

0 commit comments

Comments
 (0)