@@ -820,8 +820,15 @@ def fixture_union(name,
820820 unpack_into = unpack_into , ** kwargs )
821821
822822
823- def _fixture_union (caller_module , name , fixtures , idstyle , scope = "function" , ids = fixture_alternative_to_str ,
824- unpack_into = None , autouse = False , ** kwargs ):
823+ def _fixture_union (caller_module ,
824+ name , # type: str
825+ fixtures , # type: Iterable[Union[str, Callable]]
826+ idstyle , # type: Optional[IdStyle]
827+ scope = "function" , # type: str
828+ ids = fixture_alternative_to_str , # type: Union[Callable, List[str]]
829+ unpack_into = None , # type: Iterable[str]
830+ autouse = False , # type: bool
831+ ** kwargs ):
825832 """
826833 Internal implementation for fixture_union
827834
@@ -1030,7 +1037,7 @@ def pytest_parametrize_plus(argnames, argvalues, indirect=False, ids=None, scope
10301037 # there are fixture references: we have to create a specific decorator
10311038 caller_module = get_caller_module ()
10321039
1033- def _create_param_fixture (from_i , to_i , p_fix_name ):
1040+ def _create_param_fixture (from_i , to_i , p_names , test_func_name ):
10341041 """ Routine that will be used to create a parameter fixture for argvalues between prev_i and i"""
10351042 selected_argvalues = argvalues [from_i :to_i ]
10361043 try :
@@ -1046,18 +1053,22 @@ def _create_param_fixture(from_i, to_i, p_fix_name):
10461053 selected_ids = get_test_ids_from_param_values (all_param_names , selected_argvalues )
10471054
10481055 if to_i == from_i + 1 :
1049- p_fix_name = "%s_is_%s" % (p_fix_name , from_i )
1056+ p_names_with_idx = "%s_is_%s" % (p_names , from_i )
10501057 else :
1051- p_fix_name = "%s_is_%sto%s" % (p_fix_name , from_i , to_i - 1 )
1058+ p_names_with_idx = "%s_is_%sto%s" % (p_names , from_i , to_i - 1 )
1059+
1060+ # now create a unique fixture name
1061+ p_fix_name = "%s_%s" % (test_func_name , p_names_with_idx )
10521062 p_fix_name = check_name_available (caller_module , p_fix_name , if_name_exists = CHANGE ,
10531063 caller = pytest_parametrize_plus )
1064+
10541065 param_fix = _param_fixture (caller_module , argname = p_fix_name , argvalues = selected_argvalues ,
10551066 ids = selected_ids )
1056- return param_fix
1067+ return param_fix , p_names_with_idx
10571068
1058- def _create_fixture_product (argvalue_i , fixture_ref_positions , base_name ):
1069+ def _create_fixture_product (argvalue_i , fixture_ref_positions , param_names_str , test_func_name ):
10591070 # do not use base name - we dont care if there is another in the same module, it will still be more readable
1060- p_fix_name = "fixtureproduct__% s" % (argvalue_i , )
1071+ p_fix_name = "%s_%s__fixtureproduct__% s" % (test_func_name , param_names_str , argvalue_i )
10611072 p_fix_name = check_name_available (caller_module , p_fix_name , if_name_exists = CHANGE ,
10621073 caller = pytest_parametrize_plus )
10631074 # unpack the fixture references
@@ -1082,11 +1093,13 @@ def parametrize_plus_decorate(test_func):
10821093 raise ValueError ("parameter '%s' not found in test function signature '%s%s'"
10831094 "" % (p , test_func .__name__ , old_sig ))
10841095
1085- # The base name for all fixtures that will be created below
1096+ # The name for the final "union" fixture
10861097 # style_template = "%s_param__%s"
1098+ param_names_str = argnames .replace (' ' , '' ).replace (',' , '_' )
10871099 style_template = "%s_%s"
1088- base_name = style_template % (test_func .__name__ , argnames .replace (' ' , '' ).replace (',' , '_' ))
1089- base_name = check_name_available (caller_module , base_name , if_name_exists = CHANGE , caller = pytest_parametrize_plus )
1100+ fixture_union_name = style_template % (test_func .__name__ , param_names_str )
1101+ fixture_union_name = check_name_available (caller_module , fixture_union_name , if_name_exists = CHANGE ,
1102+ caller = pytest_parametrize_plus )
10901103
10911104 # Retrieve (if ref) or create (for normal argvalues) the fixtures that we will union
10921105 # TODO important note: we could either wish to create one fixture for parameter value or to create one for
@@ -1099,35 +1112,36 @@ def parametrize_plus_decorate(test_func):
10991112 if i > prev_i + 1 :
11001113 # there was a non-empty group of 'normal' parameters before this fixture_ref.
11011114 # create a new fixture parametrized with all of that consecutive group.
1102- param_fix = _create_param_fixture (prev_i + 1 , i , base_name )
1115+ param_fix , _id_for_fix = _create_param_fixture (prev_i + 1 , i , param_names_str , test_func . __name__ )
11031116 fixtures_to_union .append (param_fix )
1104- fixtures_to_union_names_for_ids .append (get_fixture_name ( param_fix ) )
1117+ fixtures_to_union_names_for_ids .append (_id_for_fix )
11051118
11061119 if j_list is None :
11071120 # add the fixture referenced with `fixture_ref`
11081121 referenced_fixture = argvalues [i ].fixture
11091122 fixtures_to_union .append (referenced_fixture )
1110- id_for_fixture = apply_id_style (get_fixture_name (referenced_fixture ), base_name , IdStyle .explicit )
1123+ id_for_fixture = apply_id_style (get_fixture_name (referenced_fixture ), param_names_str , IdStyle .explicit )
11111124 fixtures_to_union_names_for_ids .append (id_for_fixture )
11121125 else :
11131126 # create a fixture refering to all the fixtures required in the tuple
1114- prod_fix = _create_fixture_product (i , j_list , base_name )
1127+ prod_fix = _create_fixture_product (i , j_list , param_names_str , test_func . __name__ )
11151128 fixtures_to_union .append (prod_fix )
1116- id_for_fixture = apply_id_style (get_fixture_name (prod_fix ), base_name , IdStyle .explicit )
1129+ _id_product = "fixtureproduct__%s" % i
1130+ id_for_fixture = apply_id_style (_id_product , param_names_str , IdStyle .explicit )
11171131 fixtures_to_union_names_for_ids .append (id_for_fixture )
11181132 prev_i = i
11191133
11201134 # handle last consecutive group of normal parameters, if any
11211135 i = len (argvalues )
11221136 if i > prev_i + 1 :
1123- param_fix = _create_param_fixture (prev_i + 1 , i , base_name )
1137+ param_fix , _id_for_fix = _create_param_fixture (prev_i + 1 , i , param_names_str , test_func . __name__ )
11241138 fixtures_to_union .append (param_fix )
1125- fixtures_to_union_names_for_ids .append (get_fixture_name ( param_fix ) )
1139+ fixtures_to_union_names_for_ids .append (_id_for_fix )
11261140
11271141 # Finally create a "main" fixture with a unique name for this test function
11281142 # note: the function automatically registers it in the module
11291143 # note 2: idstyle is set to None because we provide an explicit enough list of ids
1130- big_param_fixture = _fixture_union (caller_module , base_name , fixtures_to_union , idstyle = None ,
1144+ big_param_fixture = _fixture_union (caller_module , fixture_union_name , fixtures_to_union , idstyle = None ,
11311145 ids = fixtures_to_union_names_for_ids )
11321146
11331147 # --create the new test function's signature that we want to expose to pytest
@@ -1141,12 +1155,12 @@ def parametrize_plus_decorate(test_func):
11411155 # finally insert the new fixture in that position. Indeed we can not insert first or last, because
11421156 # 'self' arg (case of test class methods) should stay first and exec order should be preserved when possible
11431157 new_sig = add_signature_parameters (new_sig , custom_idx = _first_idx ,
1144- custom = Parameter (base_name , kind = Parameter .POSITIONAL_OR_KEYWORD ))
1158+ custom = Parameter (fixture_union_name , kind = Parameter .POSITIONAL_OR_KEYWORD ))
11451159
11461160 # --Finally create the fixture function, a wrapper of user-provided fixture with the new signature
11471161 def replace_paramfixture_with_values (kwargs ):
11481162 # remove the created fixture value
1149- encompassing_fixture = kwargs .pop (base_name )
1163+ encompassing_fixture = kwargs .pop (fixture_union_name )
11501164 # and add instead the parameter values
11511165 if nb_params > 1 :
11521166 for i , p in enumerate (all_param_names ):
@@ -1160,7 +1174,7 @@ def replace_paramfixture_with_values(kwargs):
11601174 # normal test function with return statement
11611175 @wraps (test_func , new_sig = new_sig )
11621176 def wrapped_test_func (* args , ** kwargs ):
1163- if kwargs .get (base_name , None ) is NOT_USED :
1177+ if kwargs .get (fixture_union_name , None ) is NOT_USED :
11641178 return NOT_USED
11651179 else :
11661180 replace_paramfixture_with_values (kwargs )
@@ -1170,7 +1184,7 @@ def wrapped_test_func(*args, **kwargs):
11701184 # generator test function (with one or several yield statement)
11711185 @wraps (test_func , new_sig = new_sig )
11721186 def wrapped_test_func (* args , ** kwargs ):
1173- if kwargs .get (base_name , None ) is NOT_USED :
1187+ if kwargs .get (fixture_union_name , None ) is NOT_USED :
11741188 yield NOT_USED
11751189 else :
11761190 replace_paramfixture_with_values (kwargs )
0 commit comments