@@ -788,7 +788,17 @@ def _construct_varargs(
788788 for value , kind , name in args :
789789 if kind == ARG_STAR :
790790 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 )
792802 self .primitive_op (list_extend_op , [star_result , value ], line )
793803 elif kind == ARG_STAR2 :
794804 if star2_result is None :
@@ -885,9 +895,13 @@ def _construct_varargs(
885895 # tuple. Otherwise create the tuple from the list.
886896 if star_result is None :
887897 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
888901 else :
889902 star_result = self .primitive_op (list_tuple_op , [star_result ], line )
890903 if has_star2 and star2_result is None :
904+ # TODO: use dict_copy_op for simple cases of **kwargs
891905 star2_result = self ._create_dict (star2_keys , star2_values , line )
892906
893907 return star_result , star2_result
0 commit comments