Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/pathspec/gitignore.py: 69%

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

45 statements  

1""" 

2This module provides :class:`.GitIgnoreSpec` which replicates *.gitignore* 

3behavior. 

4""" 

5from __future__ import annotations 

6 

7from collections.abc import ( 

8 Callable, 

9 Iterable, 

10 Sequence) 

11from typing import ( 

12 AnyStr, 

13 Optional, # Replaced by `X | None` in 3.10. 

14 TypeVar, 

15 Union, # Replaced by `X | Y` in 3.10. 

16 cast, 

17 overload) 

18 

19try: 

20 import hyperscan 

21except ModuleNotFoundError: 

22 hyperscan = None 

23 

24from ._backends.base import ( 

25 Backend, 

26 BackendNamesHint) 

27from ._backends.agg import ( 

28 make_gitignore_backend) 

29from .pathspec import ( 

30 PathSpec) 

31from .pattern import ( 

32 Pattern) 

33from .patterns.gitwildmatch import ( 

34 GitWildMatchPattern) 

35from ._typing import ( 

36 override) # Added in 3.12. 

37from .util import ( 

38 _is_iterable) 

39 

40Self = TypeVar("Self", bound="GitIgnoreSpec") 

41""" 

42:class:`GitIgnoreSpec` self type hint to support Python v<3.11 using PEP 673 

43recommendation. 

44""" 

45 

46 

47class GitIgnoreSpec(PathSpec): 

48 """ 

49 The :class:`GitIgnoreSpec` class extends :class:`pathspec.pathspec.PathSpec` 

50 to replicate *.gitignore* behavior. 

51 """ 

52 

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

54 """ 

55 Tests the equality of this gitignore-spec with *other* (:class:`GitIgnoreSpec`) 

56 by comparing their :attr:`~pathspec.pattern.Pattern` attributes. A 

57 non-:class:`GitIgnoreSpec` will not compare equal. 

58 """ 

59 if isinstance(other, GitIgnoreSpec): 

60 return super().__eq__(other) 

61 elif isinstance(other, PathSpec): 

62 return False 

63 else: 

64 return NotImplemented 

65 

66 # Support reversed order of arguments from PathSpec. 

67 @overload 

68 @classmethod 

69 def from_lines( 

70 cls: type[Self], 

71 pattern_factory: Union[str, Callable[[AnyStr], Pattern]], 

72 lines: Iterable[AnyStr], 

73 *, 

74 backend: Union[BackendNamesHint, str, None] = None, 

75 _test_backend_factory: Optional[Callable[[Sequence[Pattern]], Backend]] = None, 

76 ) -> Self: 

77 ... 

78 

79 @overload 

80 @classmethod 

81 def from_lines( 

82 cls: type[Self], 

83 lines: Iterable[AnyStr], 

84 pattern_factory: Union[str, Callable[[AnyStr], Pattern], None] = None, 

85 *, 

86 backend: Union[BackendNamesHint, str, None] = None, 

87 _test_backend_factory: Optional[Callable[[Sequence[Pattern]], Backend]] = None, 

88 ) -> Self: 

89 ... 

90 

91 @override 

92 @classmethod 

93 def from_lines( 

94 cls: type[Self], 

95 lines: Iterable[AnyStr], 

96 pattern_factory: Union[str, Callable[[AnyStr], Pattern], None] = None, 

97 *, 

98 backend: Union[BackendNamesHint, str, None] = None, 

99 _test_backend_factory: Optional[Callable[[Sequence[Pattern]], Backend]] = None, 

100 ) -> Self: 

101 """ 

102 Compiles the pattern lines. 

103 

104 *lines* (:class:`~collections.abc.Iterable`) yields each uncompiled pattern 

105 (:class:`str`). This simply has to yield each line so it can be a 

106 :class:`io.TextIOBase` (e.g., from :func:`open` or :class:`io.StringIO`) or 

107 the result from :meth:`str.splitlines`. 

108 

109 *pattern_factory* can be :data:`None`, the name of a registered pattern 

110 factory (:class:`str`), or a :class:`~collections.abc.Callable` used to 

111 compile patterns. The callable must accept an uncompiled pattern 

112 (:class:`str`) and return the compiled pattern (:class:`pathspec.pattern.Pattern`). 

113 Default is :data:`None` for :class:`.GitWildMatchPattern`. 

114 

115 *backend* (:class:`str` or :data:`None`) is the pattern (or regex) matching 

116 backend to use. Default is :data:`None` for "best" to use the best available 

117 backend. Priority of backends is: "hyperscan", "simple". The "simple" 

118 backend is always available. 

119 

120 Returns the :class:`GitIgnoreSpec` instance. 

121 """ 

122 if pattern_factory is None: 

123 pattern_factory = GitWildMatchPattern 

124 

125 elif (isinstance(lines, (str, bytes)) or callable(lines)) and _is_iterable(pattern_factory): 

126 # Support reversed order of arguments from PathSpec. 

127 pattern_factory, lines = lines, pattern_factory 

128 

129 self = super().from_lines(pattern_factory, lines, backend=backend, _test_backend_factory=_test_backend_factory) 

130 return cast(Self, self) 

131 

132 @override 

133 @staticmethod 

134 def _make_backend( 

135 name: BackendNamesHint, 

136 patterns: Sequence[Pattern], 

137 ) -> Backend: 

138 """ 

139 Create the backend for the patterns. 

140 

141 *name* (:class:`str`) is the name of the backend. 

142 

143 *patterns* (:class:`.Sequence` of :class:`.Pattern`) contains the compiled 

144 patterns. 

145 

146 Returns the backend (:class:`.Backend`). 

147 """ 

148 return make_gitignore_backend(name, patterns)