|
128 | 128 | from mypyc.primitives.bytes_ops import bytes_compare |
129 | 129 | from mypyc.primitives.dict_ops import ( |
130 | 130 | dict_build_op, |
| 131 | + dict_copy, |
| 132 | + dict_copy_op, |
131 | 133 | dict_new_op, |
132 | 134 | dict_ssize_t_size_op, |
133 | 135 | dict_update_in_display_op, |
@@ -806,19 +808,40 @@ def _construct_varargs( |
806 | 808 | return value, self._create_dict([], [], line) |
807 | 809 | elif len(args) == 2 and args[1][1] == ARG_STAR2: |
808 | 810 | # fn(*args, **kwargs) |
| 811 | + # TODO: extend to cover(*args, **k, **w, **a, **r, **g, **s) |
809 | 812 | if is_tuple_rprimitive(value.type) or isinstance(value.type, RTuple): |
810 | 813 | star_result = value |
811 | 814 | elif is_list_rprimitive(value.type): |
812 | 815 | star_result = self.primitive_op(list_tuple_op, [value], line) |
813 | 816 | else: |
814 | 817 | star_result = self.primitive_op(sequence_tuple_op, [value], line) |
815 | | - continue |
| 818 | + |
| 819 | + star2_arg = args[1] |
| 820 | + star2_value = star2_arg[0] |
| 821 | + if is_dict_rprimitive(star2_value.type): |
| 822 | + star2_fastpath_op = dict_copy_op |
| 823 | + else: |
| 824 | + star2_fastpath_op = dict_copy |
| 825 | + return star_result, self.primitive_op( |
| 826 | + star2_fastpath_op, [star2_value], line |
| 827 | + ) |
816 | 828 | # elif ...: TODO extend this to optimize fn(*args, k=1, **kwargs) case |
817 | 829 | # TODO optimize this case using the length utils - currently in review |
818 | 830 | star_result = self.new_list_op(star_values, line) |
819 | 831 | self.primitive_op(list_extend_op, [star_result, value], line) |
820 | 832 | elif kind == ARG_STAR2: |
821 | 833 | if star2_result is None: |
| 834 | + if len(args) == 1: |
| 835 | + # early exit with fastpath if the only arg is ARG_STAR2 |
| 836 | + # TODO: can we maintain an empty tuple in memory and just reuse it again and again? |
| 837 | + if is_dict_rprimitive(value.type): |
| 838 | + star2_fastpath_op = dict_copy_op |
| 839 | + else: |
| 840 | + star2_fastpath_op = dict_copy |
| 841 | + return self.new_tuple([], line), self.primitive_op( |
| 842 | + star2_fastpath_op, [value], line |
| 843 | + ) |
| 844 | + |
822 | 845 | star2_result = self._create_dict(star2_keys, star2_values, line) |
823 | 846 |
|
824 | 847 | self.call_c(dict_update_in_display_op, [star2_result, value], line=line) |
|
0 commit comments