5353from _pytest .config import hookimpl
5454from _pytest .config .argparsing import Parser
5555from _pytest .deprecated import check_ispytest
56+ from _pytest .fixtures import _resolve_args_directness
5657from _pytest .fixtures import FixtureDef
5758from _pytest .fixtures import FixtureRequest
5859from _pytest .fixtures import FuncFixtureInfo
@@ -870,7 +871,6 @@ class IdMaker:
870871 __slots__ = (
871872 "argnames" ,
872873 "config" ,
873- "func_name" ,
874874 "idfn" ,
875875 "ids" ,
876876 "nodeid" ,
@@ -893,9 +893,6 @@ class IdMaker:
893893 # Optionally, the ID of the node being parametrized.
894894 # Used only for clearer error messages.
895895 nodeid : str | None
896- # Optionally, the ID of the function being parametrized.
897- # Used only for clearer error messages.
898- func_name : str | None
899896
900897 def make_unique_parameterset_ids (self ) -> list [str | _HiddenParam ]:
901898 """Make a unique identifier for each ParameterSet, that may be used to
@@ -1083,9 +1080,7 @@ def _complain_multiple_hidden_parameter_sets(self) -> NoReturn:
10831080 )
10841081
10851082 def _make_error_prefix (self ) -> str :
1086- if self .func_name is not None :
1087- return f"In { self .func_name } : "
1088- elif self .nodeid is not None :
1083+ if self .nodeid is not None :
10891084 return f"In { self .nodeid } : "
10901085 else :
10911086 return ""
@@ -1333,7 +1328,9 @@ def parametrize(
13331328 object .__setattr__ (_param_mark ._param_ids_from , "_param_ids_generated" , ids )
13341329
13351330 # Calculate directness.
1336- arg_directness = self ._resolve_args_directness (argnames , indirect )
1331+ arg_directness = _resolve_args_directness (
1332+ argnames , indirect , self .definition .nodeid
1333+ )
13371334 self ._params_directness .update (arg_directness )
13381335
13391336 # Add direct parametrizations as fixturedefs to arg2fixturedefs by
@@ -1435,23 +1432,21 @@ def _resolve_parameter_set_ids(
14351432 ids_ = None
14361433 else :
14371434 idfn = None
1438- ids_ = self ._validate_ids (ids , parametersets , self . function . __name__ )
1435+ ids_ = self ._validate_ids (ids , parametersets )
14391436 id_maker = IdMaker (
14401437 argnames ,
14411438 parametersets ,
14421439 idfn ,
14431440 ids_ ,
14441441 self .config ,
14451442 nodeid = nodeid ,
1446- func_name = self .function .__name__ ,
14471443 )
14481444 return id_maker .make_unique_parameterset_ids ()
14491445
14501446 def _validate_ids (
14511447 self ,
14521448 ids : Iterable [object | None ],
14531449 parametersets : Sequence [ParameterSet ],
1454- func_name : str ,
14551450 ) -> list [object | None ]:
14561451 try :
14571452 num_ids = len (ids ) # type: ignore[arg-type]
@@ -1464,49 +1459,13 @@ def _validate_ids(
14641459
14651460 # num_ids == 0 is a special case: https://github.com/pytest-dev/pytest/issues/1849
14661461 if num_ids != len (parametersets ) and num_ids != 0 :
1467- msg = "In {}: {} parameter sets specified, with different number of ids: {}"
1468- fail (msg .format (func_name , len (parametersets ), num_ids ), pytrace = False )
1469-
1470- return list (itertools .islice (ids , num_ids ))
1471-
1472- def _resolve_args_directness (
1473- self ,
1474- argnames : Sequence [str ],
1475- indirect : bool | Sequence [str ],
1476- ) -> dict [str , Literal ["indirect" , "direct" ]]:
1477- """Resolve if each parametrized argument must be considered an indirect
1478- parameter to a fixture of the same name, or a direct parameter to the
1479- parametrized function, based on the ``indirect`` parameter of the
1480- parametrized() call.
1481-
1482- :param argnames:
1483- List of argument names passed to ``parametrize()``.
1484- :param indirect:
1485- Same as the ``indirect`` parameter of ``parametrize()``.
1486- :returns
1487- A dict mapping each arg name to either "indirect" or "direct".
1488- """
1489- arg_directness : dict [str , Literal ["indirect" , "direct" ]]
1490- if isinstance (indirect , bool ):
1491- arg_directness = dict .fromkeys (
1492- argnames , "indirect" if indirect else "direct"
1493- )
1494- elif isinstance (indirect , Sequence ):
1495- arg_directness = dict .fromkeys (argnames , "direct" )
1496- for arg in indirect :
1497- if arg not in argnames :
1498- fail (
1499- f"In { self .function .__name__ } : indirect fixture '{ arg } ' doesn't exist" ,
1500- pytrace = False ,
1501- )
1502- arg_directness [arg ] = "indirect"
1503- else :
1462+ nodeid = self .definition .nodeid
15041463 fail (
1505- f"In { self .function .__name__ } : expected Sequence or boolean"
1506- f" for indirect, got { type (indirect ).__name__ } " ,
1464+ f"In { nodeid } : { len (parametersets )} parameter sets specified, with different number of ids: { num_ids } " ,
15071465 pytrace = False ,
15081466 )
1509- return arg_directness
1467+
1468+ return list (itertools .islice (ids , num_ids ))
15101469
15111470 def _validate_if_using_arg_names (
15121471 self ,
@@ -1520,12 +1479,12 @@ def _validate_if_using_arg_names(
15201479 :raises ValueError: If validation fails.
15211480 """
15221481 default_arg_names = set (get_default_arg_names (self .function ))
1523- func_name = self .function . __name__
1482+ nodeid = self .definition . nodeid
15241483 for arg in argnames :
15251484 if arg not in self .fixturenames :
15261485 if arg in default_arg_names :
15271486 fail (
1528- f"In { func_name } : function already takes an argument '{ arg } ' with a default value" ,
1487+ f"In { nodeid } : function already takes an argument '{ arg } ' with a default value" ,
15291488 pytrace = False ,
15301489 )
15311490 else :
@@ -1534,7 +1493,7 @@ def _validate_if_using_arg_names(
15341493 else :
15351494 name = "fixture" if indirect else "argument"
15361495 fail (
1537- f"In { func_name } : function uses no { name } '{ arg } '" ,
1496+ f"In { nodeid } : function uses no { name } '{ arg } '" ,
15381497 pytrace = False ,
15391498 )
15401499
0 commit comments