diff options
author | Mark Shannon <mark@hotpy.org> | 2020-01-23 09:25:17 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-01-23 09:25:17 (GMT) |
commit | 13bc13960cc83dbd1cb5701d9a59ac9b9144b205 (patch) | |
tree | 582d8286864561b8a29be0491f837c22efd1f07e /Python/ceval.c | |
parent | f9e07e116c32b6dc4561d0bdeb452ccde13b0e7c (diff) | |
download | cpython-13bc13960cc83dbd1cb5701d9a59ac9b9144b205.zip cpython-13bc13960cc83dbd1cb5701d9a59ac9b9144b205.tar.gz cpython-13bc13960cc83dbd1cb5701d9a59ac9b9144b205.tar.bz2 |
bpo-39320: Handle unpacking of *values in compiler (GH-17984)
* Add three new bytecodes: LIST_TO_TUPLE, LIST_EXTEND, SET_UPDATE. Use them to implement star unpacking expressions.
* Remove four bytecodes BUILD_LIST_UNPACK, BUILD_TUPLE_UNPACK, BUILD_SET_UNPACK and BUILD_TUPLE_UNPACK_WITH_CALL opcodes as they are now unused.
* Update magic number and dis.rst for new bytecodes.
Diffstat (limited to 'Python/ceval.c')
-rw-r--r-- | Python/ceval.c | 87 |
1 files changed, 34 insertions, 53 deletions
diff --git a/Python/ceval.c b/Python/ceval.c index 5e58658..528ad7f 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -2621,46 +2621,46 @@ main_loop: DISPATCH(); } - case TARGET(BUILD_TUPLE_UNPACK_WITH_CALL): - case TARGET(BUILD_TUPLE_UNPACK): - case TARGET(BUILD_LIST_UNPACK): { - int convert_to_tuple = opcode != BUILD_LIST_UNPACK; - Py_ssize_t i; - PyObject *sum = PyList_New(0); - PyObject *return_value; - - if (sum == NULL) + case TARGET(LIST_TO_TUPLE): { + PyObject *list = POP(); + PyObject *tuple = PyList_AsTuple(list); + Py_DECREF(list); + if (tuple == NULL) { goto error; + } + PUSH(tuple); + DISPATCH(); + } - for (i = oparg; i > 0; i--) { - PyObject *none_val; - - none_val = _PyList_Extend((PyListObject *)sum, PEEK(i)); - if (none_val == NULL) { - if (opcode == BUILD_TUPLE_UNPACK_WITH_CALL && - _PyErr_ExceptionMatches(tstate, PyExc_TypeError)) - { - check_args_iterable(tstate, PEEK(1 + oparg), PEEK(i)); - } - Py_DECREF(sum); - goto error; + case TARGET(LIST_EXTEND): { + PyObject *iterable = POP(); + PyObject *list = PEEK(oparg); + PyObject *none_val = _PyList_Extend((PyListObject *)list, iterable); + if (none_val == NULL) { + if (_PyErr_ExceptionMatches(tstate, PyExc_TypeError) && + (iterable->ob_type->tp_iter == NULL && !PySequence_Check(iterable))) + { + PyErr_Clear(); + _PyErr_Format(tstate, PyExc_TypeError, + "Value after * must be an iterable, not %.200s", + Py_TYPE(iterable)->tp_name); } - Py_DECREF(none_val); + Py_DECREF(iterable); + goto error; } + Py_DECREF(none_val); + Py_DECREF(iterable); + DISPATCH(); + } - if (convert_to_tuple) { - return_value = PyList_AsTuple(sum); - Py_DECREF(sum); - if (return_value == NULL) - goto error; - } - else { - return_value = sum; + case TARGET(SET_UPDATE): { + PyObject *iterable = POP(); + PyObject *set = PEEK(oparg); + int err = _PySet_Update(set, iterable); + Py_DECREF(iterable); + if (err < 0) { + goto error; } - - while (oparg--) - Py_DECREF(POP()); - PUSH(return_value); DISPATCH(); } @@ -2685,25 +2685,6 @@ main_loop: DISPATCH(); } - case TARGET(BUILD_SET_UNPACK): { - Py_ssize_t i; - PyObject *sum = PySet_New(NULL); - if (sum == NULL) - goto error; - - for (i = oparg; i > 0; i--) { - if (_PySet_Update(sum, PEEK(i)) < 0) { - Py_DECREF(sum); - goto error; - } - } - - while (oparg--) - Py_DECREF(POP()); - PUSH(sum); - DISPATCH(); - } - case TARGET(BUILD_MAP): { Py_ssize_t i; PyObject *map = _PyDict_NewPresized((Py_ssize_t)oparg); |