@@ -527,9 +527,12 @@ def pytest_configure(self, config: "Config") -> None:
527527 #
528528 def _set_initial_conftests (
529529 self ,
530- namespace : argparse .Namespace ,
530+ args : Sequence [Union [str , Path ]],
531+ pyargs : bool ,
532+ noconftest : bool ,
531533 rootpath : Path ,
532- testpaths_ini : Sequence [str ],
534+ confcutdir : Optional [Path ],
535+ importmode : Union [ImportMode , str ],
533536 ) -> None :
534537 """Load initial conftest files given a preparsed "namespace".
535538
@@ -539,17 +542,12 @@ def _set_initial_conftests(
539542 common options will not confuse our logic here.
540543 """
541544 current = Path .cwd ()
542- self ._confcutdir = (
543- absolutepath (current / namespace .confcutdir )
544- if namespace .confcutdir
545- else None
546- )
547- self ._noconftest = namespace .noconftest
548- self ._using_pyargs = namespace .pyargs
549- testpaths = namespace .file_or_dir + testpaths_ini
545+ self ._confcutdir = absolutepath (current / confcutdir ) if confcutdir else None
546+ self ._noconftest = noconftest
547+ self ._using_pyargs = pyargs
550548 foundanchor = False
551- for testpath in testpaths :
552- path = str (testpath )
549+ for intitial_path in args :
550+ path = str (intitial_path )
553551 # remove node-id syntax
554552 i = path .find ("::" )
555553 if i != - 1 :
@@ -563,10 +561,10 @@ def _set_initial_conftests(
563561 except OSError : # pragma: no cover
564562 anchor_exists = False
565563 if anchor_exists :
566- self ._try_load_conftest (anchor , namespace . importmode , rootpath )
564+ self ._try_load_conftest (anchor , importmode , rootpath )
567565 foundanchor = True
568566 if not foundanchor :
569- self ._try_load_conftest (current , namespace . importmode , rootpath )
567+ self ._try_load_conftest (current , importmode , rootpath )
570568
571569 def _is_in_confcutdir (self , path : Path ) -> bool :
572570 """Whether a path is within the confcutdir.
@@ -1140,10 +1138,25 @@ def _processopt(self, opt: "Argument") -> None:
11401138
11411139 @hookimpl (trylast = True )
11421140 def pytest_load_initial_conftests (self , early_config : "Config" ) -> None :
1141+ # We haven't fully parsed the command line arguments yet, so
1142+ # early_config.args it not set yet. But we need it for
1143+ # discovering the initial conftests. So "pre-run" the logic here.
1144+ # It will be done for real in `parse()`.
1145+ args , args_source = early_config ._decide_args (
1146+ args = early_config .known_args_namespace .file_or_dir ,
1147+ pyargs = early_config .known_args_namespace .pyargs ,
1148+ testpaths = early_config .getini ("testpaths" ),
1149+ invocation_dir = early_config .invocation_params .dir ,
1150+ rootpath = early_config .rootpath ,
1151+ warn = False ,
1152+ )
11431153 self .pluginmanager ._set_initial_conftests (
1144- early_config .known_args_namespace ,
1154+ args = args ,
1155+ pyargs = early_config .known_args_namespace .pyargs ,
1156+ noconftest = early_config .known_args_namespace .noconftest ,
11451157 rootpath = early_config .rootpath ,
1146- testpaths_ini = self .getini ("testpaths" ),
1158+ confcutdir = early_config .known_args_namespace .confcutdir ,
1159+ importmode = early_config .known_args_namespace .importmode ,
11471160 )
11481161
11491162 def _initini (self , args : Sequence [str ]) -> None :
@@ -1223,6 +1236,49 @@ def _validate_args(self, args: List[str], via: str) -> List[str]:
12231236
12241237 return args
12251238
1239+ def _decide_args (
1240+ self ,
1241+ * ,
1242+ args : List [str ],
1243+ pyargs : List [str ],
1244+ testpaths : List [str ],
1245+ invocation_dir : Path ,
1246+ rootpath : Path ,
1247+ warn : bool ,
1248+ ) -> Tuple [List [str ], ArgsSource ]:
1249+ """Decide the args (initial paths/nodeids) to use given the relevant inputs.
1250+
1251+ :param warn: Whether can issue warnings.
1252+ """
1253+ if args :
1254+ source = Config .ArgsSource .ARGS
1255+ result = args
1256+ else :
1257+ if invocation_dir == rootpath :
1258+ source = Config .ArgsSource .TESTPATHS
1259+ if pyargs :
1260+ result = testpaths
1261+ else :
1262+ result = []
1263+ for path in testpaths :
1264+ result .extend (sorted (glob .iglob (path , recursive = True )))
1265+ if testpaths and not result :
1266+ if warn :
1267+ warning_text = (
1268+ "No files were found in testpaths; "
1269+ "consider removing or adjusting your testpaths configuration. "
1270+ "Searching recursively from the current directory instead."
1271+ )
1272+ self .issue_config_time_warning (
1273+ PytestConfigWarning (warning_text ), stacklevel = 3
1274+ )
1275+ else :
1276+ result = []
1277+ if not result :
1278+ source = Config .ArgsSource .INCOVATION_DIR
1279+ result = [str (invocation_dir )]
1280+ return result , source
1281+
12261282 def _preparse (self , args : List [str ], addopts : bool = True ) -> None :
12271283 if addopts :
12281284 env_addopts = os .environ .get ("PYTEST_ADDOPTS" , "" )
@@ -1371,34 +1427,17 @@ def parse(self, args: List[str], addopts: bool = True) -> None:
13711427 self .hook .pytest_cmdline_preparse (config = self , args = args )
13721428 self ._parser .after_preparse = True # type: ignore
13731429 try :
1374- source = Config .ArgsSource .ARGS
13751430 args = self ._parser .parse_setoption (
13761431 args , self .option , namespace = self .option
13771432 )
1378- if not args :
1379- if self .invocation_params .dir == self .rootpath :
1380- source = Config .ArgsSource .TESTPATHS
1381- testpaths : List [str ] = self .getini ("testpaths" )
1382- if self .known_args_namespace .pyargs :
1383- args = testpaths
1384- else :
1385- args = []
1386- for path in testpaths :
1387- args .extend (sorted (glob .iglob (path , recursive = True )))
1388- if testpaths and not args :
1389- warning_text = (
1390- "No files were found in testpaths; "
1391- "consider removing or adjusting your testpaths configuration. "
1392- "Searching recursively from the current directory instead."
1393- )
1394- self .issue_config_time_warning (
1395- PytestConfigWarning (warning_text ), stacklevel = 3
1396- )
1397- if not args :
1398- source = Config .ArgsSource .INCOVATION_DIR
1399- args = [str (self .invocation_params .dir )]
1400- self .args = args
1401- self .args_source = source
1433+ self .args , self .args_source = self ._decide_args (
1434+ args = args ,
1435+ pyargs = self .known_args_namespace .pyargs ,
1436+ testpaths = self .getini ("testpaths" ),
1437+ invocation_dir = self .invocation_params .dir ,
1438+ rootpath = self .rootpath ,
1439+ warn = True ,
1440+ )
14021441 except PrintHelp :
14031442 pass
14041443
0 commit comments