@@ -527,9 +527,12 @@ def pytest_configure(self, config: "Config") -> None:
527
527
#
528
528
def _set_initial_conftests (
529
529
self ,
530
- namespace : argparse .Namespace ,
530
+ args : Sequence [Union [str , Path ]],
531
+ pyargs : bool ,
532
+ noconftest : bool ,
531
533
rootpath : Path ,
532
- testpaths_ini : Sequence [str ],
534
+ confcutdir : Optional [Path ],
535
+ importmode : Union [ImportMode , str ],
533
536
) -> None :
534
537
"""Load initial conftest files given a preparsed "namespace".
535
538
@@ -539,17 +542,12 @@ def _set_initial_conftests(
539
542
common options will not confuse our logic here.
540
543
"""
541
544
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
550
548
foundanchor = False
551
- for testpath in testpaths :
552
- path = str (testpath )
549
+ for intitial_path in args :
550
+ path = str (intitial_path )
553
551
# remove node-id syntax
554
552
i = path .find ("::" )
555
553
if i != - 1 :
@@ -563,10 +561,10 @@ def _set_initial_conftests(
563
561
except OSError : # pragma: no cover
564
562
anchor_exists = False
565
563
if anchor_exists :
566
- self ._try_load_conftest (anchor , namespace . importmode , rootpath )
564
+ self ._try_load_conftest (anchor , importmode , rootpath )
567
565
foundanchor = True
568
566
if not foundanchor :
569
- self ._try_load_conftest (current , namespace . importmode , rootpath )
567
+ self ._try_load_conftest (current , importmode , rootpath )
570
568
571
569
def _is_in_confcutdir (self , path : Path ) -> bool :
572
570
"""Whether a path is within the confcutdir.
@@ -1140,10 +1138,25 @@ def _processopt(self, opt: "Argument") -> None:
1140
1138
1141
1139
@hookimpl (trylast = True )
1142
1140
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
+ )
1143
1153
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 ,
1145
1157
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 ,
1147
1160
)
1148
1161
1149
1162
def _initini (self , args : Sequence [str ]) -> None :
@@ -1223,6 +1236,49 @@ def _validate_args(self, args: List[str], via: str) -> List[str]:
1223
1236
1224
1237
return args
1225
1238
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
+
1226
1282
def _preparse (self , args : List [str ], addopts : bool = True ) -> None :
1227
1283
if addopts :
1228
1284
env_addopts = os .environ .get ("PYTEST_ADDOPTS" , "" )
@@ -1371,34 +1427,17 @@ def parse(self, args: List[str], addopts: bool = True) -> None:
1371
1427
self .hook .pytest_cmdline_preparse (config = self , args = args )
1372
1428
self ._parser .after_preparse = True # type: ignore
1373
1429
try :
1374
- source = Config .ArgsSource .ARGS
1375
1430
args = self ._parser .parse_setoption (
1376
1431
args , self .option , namespace = self .option
1377
1432
)
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
+ )
1402
1441
except PrintHelp :
1403
1442
pass
1404
1443
0 commit comments