@@ -788,7 +788,17 @@ def _construct_varargs(
788
788
for value , kind , name in args :
789
789
if kind == ARG_STAR :
790
790
if star_result is None :
791
- star_result = self .new_list_op (star_values , line )
791
+ # fast path if star expr is a tuple:
792
+ # we can pass the immutable tuple straight into the function call.
793
+ if is_tuple_rprimitive (value .type ) and (
794
+ len (args ) == 1 or (len (args ) == 2 and args [1 ][1 ] == ARG_STAR2 )
795
+ ): # only matches fn(*args) and fn(*args, **kwargs)
796
+ # TODO extend this to optimize fn(*args, k=1, **kwargs) case
797
+ star_result = value
798
+ continue
799
+ else :
800
+ # TODO optimize this case using the length utils - currently in review
801
+ star_result = self .new_list_op (star_values , line )
792
802
self .primitive_op (list_extend_op , [star_result , value ], line )
793
803
elif kind == ARG_STAR2 :
794
804
if star2_result is None :
@@ -885,9 +895,13 @@ def _construct_varargs(
885
895
# tuple. Otherwise create the tuple from the list.
886
896
if star_result is None :
887
897
star_result = self .new_tuple (star_values , line )
898
+ elif is_tuple_rprimitive (star_result .type ):
899
+ # We're just passing in the tuple
900
+ pass
888
901
else :
889
902
star_result = self .primitive_op (list_tuple_op , [star_result ], line )
890
903
if has_star2 and star2_result is None :
904
+ # TODO: use dict_copy_op for simple cases of **kwargs
891
905
star2_result = self ._create_dict (star2_keys , star2_values , line )
892
906
893
907
return star_result , star2_result
0 commit comments