summaryrefslogtreecommitdiff
path: root/Python/ceval.c
diff options
context:
space:
mode:
authorMark Shannon <mark@hotpy.org>2020-01-23 09:25:17 +0000
committerGitHub <noreply@github.com>2020-01-23 09:25:17 +0000
commit13bc13960cc83dbd1cb5701d9a59ac9b9144b205 (patch)
tree582d8286864561b8a29be0491f837c22efd1f07e /Python/ceval.c
parentf9e07e116c32b6dc4561d0bdeb452ccde13b0e7c (diff)
downloadcpython-git-13bc13960cc83dbd1cb5701d9a59ac9b9144b205.tar.gz
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.c87
1 files changed, 34 insertions, 53 deletions
diff --git a/Python/ceval.c b/Python/ceval.c
index 5e586589e9..528ad7fdd1 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);