Skip to content

Commit cf57114

Browse files
committed
optimize this
1 parent 7583b6d commit cf57114

File tree

4 files changed

+59
-39
lines changed

4 files changed

+59
-39
lines changed

src/capi/abstract.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2464,4 +2464,34 @@ extern "C" Py_ssize_t PyNumber_AsSsize_t(PyObject* item, PyObject* err) noexcept
24642464
Py_DECREF(value);
24652465
return result;
24662466
}
2467+
2468+
extern "C" int PyObject_SetItem(PyObject* o, PyObject* key, PyObject* value) noexcept {
2469+
PyMappingMethods* m;
2470+
2471+
if (o == NULL || key == NULL || value == NULL) {
2472+
null_error();
2473+
return -1;
2474+
}
2475+
m = o->cls->tp_as_mapping;
2476+
if (m && m->mp_ass_subscript)
2477+
return m->mp_ass_subscript(o, key, value);
2478+
2479+
if (o->cls->tp_as_sequence) {
2480+
if (PyIndex_Check(key)) {
2481+
Py_ssize_t key_value;
2482+
key_value = PyNumber_AsSsize_t(key, PyExc_IndexError);
2483+
if (key_value == -1 && PyErr_Occurred())
2484+
return -1;
2485+
return PySequence_SetItem(o, key_value, value);
2486+
} else if (o->cls->tp_as_sequence->sq_ass_item) {
2487+
type_error("sequence index must be "
2488+
"integer, not '%.200s'",
2489+
key);
2490+
return -1;
2491+
}
2492+
}
2493+
2494+
type_error("'%.200s' object does not support item assignment", o);
2495+
return -1;
2496+
}
24672497
}

src/runtime/capi.cpp

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -472,16 +472,6 @@ extern "C" PyObject* PyObject_GetItem(PyObject* o, PyObject* key) noexcept {
472472
return getitemInternal<ExceptionStyle::CAPI>(o, key);
473473
}
474474

475-
extern "C" int PyObject_SetItem(PyObject* o, PyObject* key, PyObject* v) noexcept {
476-
try {
477-
setitem(o, key, v);
478-
return 0;
479-
} catch (ExcInfo e) {
480-
setCAPIException(e);
481-
return -1;
482-
}
483-
}
484-
485475
extern "C" int PyObject_DelItem(PyObject* o, PyObject* key) noexcept {
486476
try {
487477
delitem(o, key);

src/runtime/dict.cpp

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -258,30 +258,6 @@ extern "C" PyObject* PyDict_New() noexcept {
258258
return new BoxedDict();
259259
}
260260

261-
// We don't assume that dicts passed to PyDict are necessarily dicts, since there are a couple places
262-
// that we provide dict-like objects instead of proper dicts.
263-
// The performance should hopefully be comparable to the CPython fast case, since we can use
264-
// runtimeICs.
265-
extern "C" int PyDict_SetItem(PyObject* mp, PyObject* _key, PyObject* _item) noexcept {
266-
ASSERT(PyDict_Check(mp) || mp->cls == attrwrapper_cls, "%s", getTypeName(mp));
267-
268-
assert(mp);
269-
Box* b = static_cast<Box*>(mp);
270-
Box* key = static_cast<Box*>(_key);
271-
Box* item = static_cast<Box*>(_item);
272-
273-
assert(key);
274-
assert(item);
275-
276-
try {
277-
setitem(b, key, item);
278-
} catch (ExcInfo e) {
279-
setCAPIException(e);
280-
return -1;
281-
}
282-
return 0;
283-
}
284-
285261
extern "C" int PyDict_SetItemString(PyObject* mp, const char* key, PyObject* item) noexcept {
286262
Box* key_s;
287263
try {
@@ -383,6 +359,33 @@ Box* dictSetitem(BoxedDict* self, Box* k, Box* v) {
383359
return None;
384360
}
385361

362+
// We don't assume that dicts passed to PyDict are necessarily dicts, since there are a couple places
363+
// that we provide dict-like objects instead of proper dicts.
364+
// The performance should hopefully be comparable to the CPython fast case, since we can use
365+
// runtimeICs.
366+
extern "C" int PyDict_SetItem(PyObject* mp, PyObject* _key, PyObject* _item) noexcept {
367+
ASSERT(PyDict_Check(mp) || mp->cls == attrwrapper_cls, "%s", getTypeName(mp));
368+
369+
assert(mp);
370+
Box* b = static_cast<Box*>(mp);
371+
Box* key = static_cast<Box*>(_key);
372+
Box* item = static_cast<Box*>(_item);
373+
374+
assert(key);
375+
assert(item);
376+
377+
try {
378+
if (PyDict_Check(mp))
379+
dictSetitem((BoxedDict*)b, key, item);
380+
else
381+
setitem(b, key, item);
382+
} catch (ExcInfo e) {
383+
setCAPIException(e);
384+
return -1;
385+
}
386+
return 0;
387+
}
388+
386389
Box* dictDelitem(BoxedDict* self, Box* k) {
387390
if (!PyDict_Check(self))
388391
raiseExcHelper(TypeError, "descriptor '__delitem__' requires a 'dict' object but received a '%s'",

src/runtime/list.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1244,11 +1244,8 @@ extern "C" int PyList_SetSlice(PyObject* a, Py_ssize_t ilow, Py_ssize_t ihigh, P
12441244
ASSERT(PyList_Check(l), "%s", l->cls->tp_name);
12451245

12461246
try {
1247-
BoxedSlice* slice = (BoxedSlice*)createSlice(boxInt(ilow), boxInt(ihigh), None);
1248-
if (v)
1249-
listSetitemSlice(l, slice, v);
1250-
else
1251-
listDelitemSlice(l, slice);
1247+
adjustNegativeIndicesOnObject(l, &ilow, &ihigh);
1248+
listSetitemSliceInt64(l, ilow, ihigh, 1, v);
12521249
return 0;
12531250
} catch (ExcInfo e) {
12541251
setCAPIException(e);

0 commit comments

Comments
 (0)