Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.9/dist-packages/sphinx/util/_pathlib.py: 24%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

82 statements  

1"""What follows is awful and will be gone in Sphinx 8""" 

2 

3from __future__ import annotations 

4 

5import sys 

6import warnings 

7from pathlib import Path, PosixPath, PurePath, WindowsPath 

8from typing import Any 

9 

10from sphinx.deprecation import RemovedInSphinx80Warning 

11 

12_STR_METHODS = frozenset(str.__dict__) 

13_PATH_NAME = Path().__class__.__name__ 

14 

15_MSG = ( 

16 'Sphinx 8 will drop support for representing paths as strings. ' 

17 'Use "pathlib.Path" or "os.fspath" instead.' 

18) 

19 

20# https://docs.python.org/3/library/stdtypes.html#typesseq-common 

21# https://docs.python.org/3/library/stdtypes.html#string-methods 

22 

23if sys.platform == 'win32': 

24 class _StrPath(WindowsPath): 

25 def replace( # type: ignore[override] 

26 self, old: str, new: str, count: int = -1, /, 

27 ) -> str: 

28 # replace exists in both Path and str; 

29 # in Path it makes filesystem changes, so we use the safer str version 

30 warnings.warn(_MSG, RemovedInSphinx80Warning, stacklevel=2) 

31 return self.__str__().replace(old, new, count) # NoQA: PLC2801 

32 

33 def __getattr__(self, item: str) -> Any: 

34 if item in _STR_METHODS: 

35 warnings.warn(_MSG, RemovedInSphinx80Warning, stacklevel=2) 

36 return getattr(self.__str__(), item) 

37 msg = f'{_PATH_NAME!r} has no attribute {item!r}' 

38 raise AttributeError(msg) 

39 

40 def __add__(self, other: str) -> str: 

41 warnings.warn(_MSG, RemovedInSphinx80Warning, stacklevel=2) 

42 return self.__str__() + other 

43 

44 def __bool__(self) -> bool: 

45 if not self.__str__(): 

46 warnings.warn(_MSG, RemovedInSphinx80Warning, stacklevel=2) 

47 return False 

48 return True 

49 

50 def __contains__(self, item: str) -> bool: 

51 warnings.warn(_MSG, RemovedInSphinx80Warning, stacklevel=2) 

52 return item in self.__str__() 

53 

54 def __eq__(self, other: object) -> bool: 

55 if isinstance(other, PurePath): 

56 return super().__eq__(other) 

57 if isinstance(other, str): 

58 warnings.warn(_MSG, RemovedInSphinx80Warning, stacklevel=2) 

59 return self.__str__() == other 

60 return NotImplemented 

61 

62 def __hash__(self) -> int: 

63 return super().__hash__() 

64 

65 def __getitem__(self, item: int | slice) -> str: 

66 warnings.warn(_MSG, RemovedInSphinx80Warning, stacklevel=2) 

67 return self.__str__()[item] 

68 

69 def __len__(self) -> int: 

70 warnings.warn(_MSG, RemovedInSphinx80Warning, stacklevel=2) 

71 return len(self.__str__()) 

72else: 

73 class _StrPath(PosixPath): 

74 def replace( # type: ignore[override] 

75 self, old: str, new: str, count: int = -1, /, 

76 ) -> str: 

77 # replace exists in both Path and str; 

78 # in Path it makes filesystem changes, so we use the safer str version 

79 warnings.warn(_MSG, RemovedInSphinx80Warning, stacklevel=2) 

80 return self.__str__().replace(old, new, count) # NoQA: PLC2801 

81 

82 def __getattr__(self, item: str) -> Any: 

83 if item in _STR_METHODS: 

84 warnings.warn(_MSG, RemovedInSphinx80Warning, stacklevel=2) 

85 return getattr(self.__str__(), item) 

86 msg = f'{_PATH_NAME!r} has no attribute {item!r}' 

87 raise AttributeError(msg) 

88 

89 def __add__(self, other: str) -> str: 

90 warnings.warn(_MSG, RemovedInSphinx80Warning, stacklevel=2) 

91 return self.__str__() + other 

92 

93 def __bool__(self) -> bool: 

94 if not self.__str__(): 

95 warnings.warn(_MSG, RemovedInSphinx80Warning, stacklevel=2) 

96 return False 

97 return True 

98 

99 def __contains__(self, item: str) -> bool: 

100 warnings.warn(_MSG, RemovedInSphinx80Warning, stacklevel=2) 

101 return item in self.__str__() 

102 

103 def __eq__(self, other: object) -> bool: 

104 if isinstance(other, PurePath): 

105 return super().__eq__(other) 

106 if isinstance(other, str): 

107 warnings.warn(_MSG, RemovedInSphinx80Warning, stacklevel=2) 

108 return self.__str__() == other 

109 return NotImplemented 

110 

111 def __hash__(self) -> int: 

112 return super().__hash__() 

113 

114 def __getitem__(self, item: int | slice) -> str: 

115 warnings.warn(_MSG, RemovedInSphinx80Warning, stacklevel=2) 

116 return self.__str__()[item] 

117 

118 def __len__(self) -> int: 

119 warnings.warn(_MSG, RemovedInSphinx80Warning, stacklevel=2) 

120 return len(self.__str__())