Commit c483a729 authored by Kevin Modzelewski's avatar Kevin Modzelewski Committed by Kevin Modzelewski

Whoops I broke unpackIntoArray

parent 50c43972
...@@ -315,41 +315,53 @@ static void _checkUnpackingLength(i64 expected, i64 given) { ...@@ -315,41 +315,53 @@ static void _checkUnpackingLength(i64 expected, i64 given) {
} }
extern "C" Box** unpackIntoArray(Box* obj, int64_t expected_size, Box** out_keep_alive) { extern "C" Box** unpackIntoArray(Box* obj, int64_t expected_size, Box** out_keep_alive) {
if (obj->cls != tuple_cls && obj->cls != list_cls) {
Box* converted = PySequence_Fast(obj, "Invalid type for tuple unpacking");
if (!converted)
throwCAPIException();
*out_keep_alive = converted;
obj = converted;
} else {
*out_keep_alive = incref(obj);
}
if (obj->cls == tuple_cls) { if (obj->cls == tuple_cls) {
BoxedTuple* t = static_cast<BoxedTuple*>(obj); BoxedTuple* t = static_cast<BoxedTuple*>(obj);
auto got_size = t->size(); auto got_size = t->size();
if (expected_size != got_size)
Py_DECREF(*out_keep_alive);
_checkUnpackingLength(expected_size, got_size); _checkUnpackingLength(expected_size, got_size);
*out_keep_alive = incref(t);
for (auto e : *t) for (auto e : *t)
Py_INCREF(e); Py_INCREF(e);
return &t->elts[0]; return &t->elts[0];
} else { } else if (obj->cls == list_cls) {
assert(obj->cls == list_cls); assert(obj->cls == list_cls);
BoxedList* l = static_cast<BoxedList*>(obj); BoxedList* l = static_cast<BoxedList*>(obj);
auto got_size = l->size; auto got_size = l->size;
if (expected_size != got_size)
Py_DECREF(*out_keep_alive);
_checkUnpackingLength(expected_size, got_size); _checkUnpackingLength(expected_size, got_size);
*out_keep_alive = incref(l);
for (size_t i = 0; i < l->size; i++) for (size_t i = 0; i < l->size; i++)
Py_INCREF(l->elts->elts[i]); Py_INCREF(l->elts->elts[i]);
return &l->elts->elts[0]; return &l->elts->elts[0];
} else {
BoxedTuple* keep_alive = BoxedTuple::create(expected_size);
AUTO_DECREF(keep_alive);
int i = 0;
for (auto e : obj->pyElements()) {
if (i >= expected_size) {
Py_DECREF(e);
_checkUnpackingLength(expected_size, i + 1);
// unreachable:
abort();
}
keep_alive->elts[i] = e;
i++;
}
_checkUnpackingLength(expected_size, i);
*out_keep_alive = incref(keep_alive);
for (auto e : *keep_alive)
Py_INCREF(e);
return &keep_alive->elts[0];
} }
abort();
} }
static void clear_slots(PyTypeObject* type, PyObject* self) noexcept { static void clear_slots(PyTypeObject* type, PyObject* self) noexcept {
......
# expected: reffail
# should_error # should_error
# Int not iterable: # Int not iterable:
a, b, c = 1 a, b, c = 1
# expected: reffail
# Test the behavior of tuple unpacking in the face of exceptions being thrown at certain points. # Test the behavior of tuple unpacking in the face of exceptions being thrown at certain points.
# - If an exception gets thrown in the "unpack to a given size" part, none of the targets get set # - If an exception gets thrown in the "unpack to a given size" part, none of the targets get set
# - If setting a target throws an exception, then the previous targets had been set, but not the future ones # - If setting a target throws an exception, then the previous targets had been set, but not the future ones
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment