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

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

32 statements  

1""" 

2This module provides the simple backend for :class:`~pathspec.gitignore.GitIgnoreSpec`. 

3 

4WARNING: The *pathspec._backends.simple* package is not part of the public API. 

5Its contents and structure are likely to change. 

6""" 

7 

8from collections.abc import ( 

9 Sequence) 

10from typing import ( 

11 Optional) # Replaced by `X | None` in 3.10. 

12 

13from pathspec.pattern import ( 

14 RegexPattern) 

15from pathspec.patterns.gitignore.spec import ( 

16 _DIR_MARK) 

17from pathspec._typing import ( 

18 override) # Added in 3.12. 

19 

20from .pathspec import ( 

21 SimplePsBackend) 

22 

23 

24class SimpleGiBackend(SimplePsBackend): 

25 """ 

26 The :class:`SimpleGiBackend` class is the default (or simple) implementation 

27 used by :class:`~pathspec.gitignore.GitIgnoreSpec` for matching files. 

28 """ 

29 

30 # Change type hint. 

31 _patterns: list[tuple[int, RegexPattern]] # type: ignore[assignment] 

32 

33 def __init__( 

34 self, 

35 patterns: Sequence[RegexPattern], 

36 *, 

37 no_filter: Optional[bool] = None, 

38 no_reverse: Optional[bool] = None, 

39 ) -> None: 

40 """ 

41 Initialize the :class:`SimpleGiBackend` instance. 

42 

43 *patterns* (:class:`Sequence` of :class:`.RegexPattern`) contains the 

44 compiled patterns. 

45 

46 *no_filter* (:class:`bool`) is whether to keep no-op patterns (:data:`True`), 

47 or remove them (:data:`False`). 

48 

49 *no_reverse* (:class:`bool`) is whether to keep the pattern order 

50 (:data:`True`), or reverse the order (:data:`True`). 

51 """ 

52 super().__init__(patterns, no_filter=no_filter, no_reverse=no_reverse) 

53 

54 @override 

55 def match_file(self, file: str) -> tuple[Optional[bool], Optional[int]]: 

56 """ 

57 Check the file against the patterns. 

58 

59 *file* (:class:`str`) is the normalized file path to check. 

60 

61 Returns a :class:`tuple` containing whether to include *file* (:class:`bool` 

62 or :data:`None`), and the index of the last matched pattern (:class:`int` or 

63 :data:`None`). 

64 """ 

65 is_reversed = self._is_reversed 

66 

67 # Resolve the ancestor directory and the file separately: a file negation 

68 # only applies while no ancestor directory is excluded. 

69 dir_include: Optional[bool] = None 

70 dir_index: Optional[int] = None 

71 file_include: Optional[bool] = None 

72 file_index: Optional[int] = None 

73 

74 for index, pattern in self._patterns: 

75 if ( 

76 (include := pattern.include) is not None 

77 and (match := pattern.match_file(file)) is not None 

78 ): 

79 # Pattern matched. 

80 if match.match.groupdict().get(_DIR_MARK): 

81 # Pattern matched by a directory pattern. 

82 if dir_include is None or not is_reversed: 

83 dir_include = include 

84 dir_index = index 

85 elif file_include is None or not is_reversed: 

86 # Pattern matched by a file pattern. 

87 file_include = include 

88 file_index = index 

89 

90 if dir_include: 

91 return (dir_include, dir_index) 

92 elif file_include is not None: 

93 return (file_include, file_index) 

94 else: 

95 return (dir_include, dir_index)