50
50
from _pytest .compat import importlib_metadata
51
51
from _pytest .outcomes import fail
52
52
from _pytest .outcomes import Skipped
53
+ from _pytest .pathlib import absolutepath
53
54
from _pytest .pathlib import bestrelpath
54
55
from _pytest .pathlib import import_path
55
56
from _pytest .pathlib import ImportMode
57
+ from _pytest .pathlib import resolve_package_path
56
58
from _pytest .store import Store
57
59
from _pytest .warning_types import PytestConfigWarning
58
60
@@ -102,9 +104,7 @@ class ExitCode(enum.IntEnum):
102
104
103
105
class ConftestImportFailure (Exception ):
104
106
def __init__ (
105
- self ,
106
- path : py .path .local ,
107
- excinfo : Tuple [Type [Exception ], Exception , TracebackType ],
107
+ self , path : Path , excinfo : Tuple [Type [Exception ], Exception , TracebackType ],
108
108
) -> None :
109
109
super ().__init__ (path , excinfo )
110
110
self .path = path
@@ -342,9 +342,9 @@ def __init__(self) -> None:
342
342
self ._conftest_plugins : Set [types .ModuleType ] = set ()
343
343
344
344
# State related to local conftest plugins.
345
- self ._dirpath2confmods : Dict [py . path . local , List [types .ModuleType ]] = {}
345
+ self ._dirpath2confmods : Dict [Path , List [types .ModuleType ]] = {}
346
346
self ._conftestpath2mod : Dict [Path , types .ModuleType ] = {}
347
- self ._confcutdir : Optional [py . path . local ] = None
347
+ self ._confcutdir : Optional [Path ] = None
348
348
self ._noconftest = False
349
349
self ._duplicatepaths : Set [py .path .local ] = set ()
350
350
@@ -479,9 +479,9 @@ def _set_initial_conftests(self, namespace: argparse.Namespace) -> None:
479
479
All builtin and 3rd party plugins will have been loaded, however, so
480
480
common options will not confuse our logic here.
481
481
"""
482
- current = py . path . local ()
482
+ current = Path . cwd ()
483
483
self ._confcutdir = (
484
- current . join ( namespace .confcutdir , abs = True )
484
+ absolutepath ( current / namespace .confcutdir )
485
485
if namespace .confcutdir
486
486
else None
487
487
)
@@ -495,51 +495,51 @@ def _set_initial_conftests(self, namespace: argparse.Namespace) -> None:
495
495
i = path .find ("::" )
496
496
if i != - 1 :
497
497
path = path [:i ]
498
- anchor = current . join ( path , abs = 1 )
498
+ anchor = absolutepath ( current / path )
499
499
if anchor .exists (): # we found some file object
500
500
self ._try_load_conftest (anchor , namespace .importmode )
501
501
foundanchor = True
502
502
if not foundanchor :
503
503
self ._try_load_conftest (current , namespace .importmode )
504
504
505
505
def _try_load_conftest (
506
- self , anchor : py . path . local , importmode : Union [str , ImportMode ]
506
+ self , anchor : Path , importmode : Union [str , ImportMode ]
507
507
) -> None :
508
508
self ._getconftestmodules (anchor , importmode )
509
509
# let's also consider test* subdirs
510
- if anchor .check ( dir = 1 ):
511
- for x in anchor .listdir ("test*" ):
512
- if x .check ( dir = 1 ):
510
+ if anchor .is_dir ( ):
511
+ for x in anchor .glob ("test*" ):
512
+ if x .is_dir ( ):
513
513
self ._getconftestmodules (x , importmode )
514
514
515
515
@lru_cache (maxsize = 128 )
516
516
def _getconftestmodules (
517
- self , path : py . path . local , importmode : Union [str , ImportMode ],
517
+ self , path : Path , importmode : Union [str , ImportMode ],
518
518
) -> List [types .ModuleType ]:
519
519
if self ._noconftest :
520
520
return []
521
521
522
- if path .isfile ():
523
- directory = path .dirpath ()
522
+ if path .is_file ():
523
+ directory = path .parent
524
524
else :
525
525
directory = path
526
526
527
527
# XXX these days we may rather want to use config.rootpath
528
528
# and allow users to opt into looking into the rootdir parent
529
529
# directories instead of requiring to specify confcutdir.
530
530
clist = []
531
- for parent in directory . parts ( ):
532
- if self ._confcutdir and self ._confcutdir .relto ( parent ) :
531
+ for parent in reversed (( directory , * directory . parents ) ):
532
+ if self ._confcutdir and parent in self ._confcutdir .parents :
533
533
continue
534
- conftestpath = parent . join ( "conftest.py" )
535
- if conftestpath .isfile ():
534
+ conftestpath = parent / "conftest.py"
535
+ if conftestpath .is_file ():
536
536
mod = self ._importconftest (conftestpath , importmode )
537
537
clist .append (mod )
538
538
self ._dirpath2confmods [directory ] = clist
539
539
return clist
540
540
541
541
def _rget_with_confmod (
542
- self , name : str , path : py . path . local , importmode : Union [str , ImportMode ],
542
+ self , name : str , path : Path , importmode : Union [str , ImportMode ],
543
543
) -> Tuple [types .ModuleType , Any ]:
544
544
modules = self ._getconftestmodules (path , importmode )
545
545
for mod in reversed (modules ):
@@ -550,21 +550,21 @@ def _rget_with_confmod(
550
550
raise KeyError (name )
551
551
552
552
def _importconftest (
553
- self , conftestpath : py . path . local , importmode : Union [str , ImportMode ],
553
+ self , conftestpath : Path , importmode : Union [str , ImportMode ],
554
554
) -> types .ModuleType :
555
555
# Use a resolved Path object as key to avoid loading the same conftest
556
556
# twice with build systems that create build directories containing
557
557
# symlinks to actual files.
558
558
# Using Path().resolve() is better than py.path.realpath because
559
559
# it resolves to the correct path/drive in case-insensitive file systems (#5792)
560
- key = Path ( str ( conftestpath )) .resolve ()
560
+ key = conftestpath .resolve ()
561
561
562
562
with contextlib .suppress (KeyError ):
563
563
return self ._conftestpath2mod [key ]
564
564
565
- pkgpath = conftestpath . pypkgpath ( )
565
+ pkgpath = resolve_package_path ( conftestpath )
566
566
if pkgpath is None :
567
- _ensure_removed_sysmodule (conftestpath .purebasename )
567
+ _ensure_removed_sysmodule (conftestpath .stem )
568
568
569
569
try :
570
570
mod = import_path (conftestpath , mode = importmode )
@@ -577,18 +577,18 @@ def _importconftest(
577
577
578
578
self ._conftest_plugins .add (mod )
579
579
self ._conftestpath2mod [key ] = mod
580
- dirpath = conftestpath .dirpath ()
580
+ dirpath = conftestpath .parent
581
581
if dirpath in self ._dirpath2confmods :
582
582
for path , mods in self ._dirpath2confmods .items ():
583
- if path and path .relto ( dirpath ) or path == dirpath :
583
+ if path and dirpath in path .parents or path == dirpath :
584
584
assert mod not in mods
585
585
mods .append (mod )
586
586
self .trace (f"loading conftestmodule { mod !r} " )
587
587
self .consider_conftest (mod )
588
588
return mod
589
589
590
590
def _check_non_top_pytest_plugins (
591
- self , mod : types .ModuleType , conftestpath : py . path . local ,
591
+ self , mod : types .ModuleType , conftestpath : Path ,
592
592
) -> None :
593
593
if (
594
594
hasattr (mod , "pytest_plugins" )
@@ -1412,21 +1412,23 @@ def _getini(self, name: str):
1412
1412
assert type in [None , "string" ]
1413
1413
return value
1414
1414
1415
- def _getconftest_pathlist (
1416
- self , name : str , path : py .path .local
1417
- ) -> Optional [List [py .path .local ]]:
1415
+ def _getconftest_pathlist (self , name : str , path : Path ) -> Optional [List [Path ]]:
1418
1416
try :
1419
1417
mod , relroots = self .pluginmanager ._rget_with_confmod (
1420
1418
name , path , self .getoption ("importmode" )
1421
1419
)
1422
1420
except KeyError :
1423
1421
return None
1424
- modpath = py . path . local (mod .__file__ ).dirpath ()
1425
- values : List [py . path . local ] = []
1422
+ modpath = Path (mod .__file__ ).parent
1423
+ values : List [Path ] = []
1426
1424
for relroot in relroots :
1427
- if not isinstance (relroot , py .path .local ):
1425
+ if isinstance (relroot , Path ):
1426
+ pass
1427
+ elif isinstance (relroot , py .path .local ):
1428
+ relroot = Path (relroot )
1429
+ else :
1428
1430
relroot = relroot .replace ("/" , os .sep )
1429
- relroot = modpath . join ( relroot , abs = True )
1431
+ relroot = absolutepath ( modpath / relroot )
1430
1432
values .append (relroot )
1431
1433
return values
1432
1434
0 commit comments