Mercurial > public > mercurial-scm > hg-stable
view mercurial/interfaces/matcher.py @ 52971:469b9a628b51
dirstatemap: update, document and type the identity tracking
This new form should hopefully be clearer and less error prone.
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Tue, 18 Feb 2025 22:24:08 +0100 |
parents | aa948d9e3fee |
children |
line wrap: on
line source
# mercurial/interfaces/matcher - typing protocol for Matcher objects # # This software may be used and distributed according to the terms of the # GNU General Public License version 2 or any later version. from __future__ import annotations import abc from typing import ( Callable, List, Optional, Protocol, Set, Union, ) from ._basetypes import ( HgPathT, UserMsgT, ) class IMatcher(Protocol): """A protocol class that defines the common interface for all file matching classes.""" @abc.abstractmethod def was_tampered_with_nonrec(self) -> bool: ... @abc.abstractmethod def was_tampered_with(self) -> bool: ... @abc.abstractmethod def __call__(self, fn: HgPathT) -> bool: ... # Callbacks related to how the matcher is used by dirstate.walk. # Subscribers to these events must monkeypatch the matcher object. @abc.abstractmethod def bad(self, f: HgPathT, msg: Optional[UserMsgT]) -> None: ... # If traversedir is set, it will be called when a directory discovered # by recursive traversal is visited. traversedir: Optional[Callable[[HgPathT], None]] = None @property @abc.abstractmethod def _files(self) -> List[HgPathT]: ... @abc.abstractmethod def files(self) -> List[HgPathT]: ... @property @abc.abstractmethod def _fileset(self) -> Set[HgPathT]: ... @abc.abstractmethod def exact(self, f: HgPathT) -> bool: """Returns True if f is in .files().""" @abc.abstractmethod def matchfn(self, f: HgPathT) -> bool: ... @abc.abstractmethod def visitdir(self, dir: HgPathT) -> Union[bool, bytes]: """Decides whether a directory should be visited based on whether it has potential matches in it or one of its subdirectories. This is based on the match's primary, included, and excluded patterns. Returns the string 'all' if the given directory and all subdirectories should be visited. Otherwise returns True or False indicating whether the given directory should be visited. """ @abc.abstractmethod def visitchildrenset(self, dir: HgPathT) -> Union[Set[HgPathT], bytes]: """Decides whether a directory should be visited based on whether it has potential matches in it or one of its subdirectories, and potentially lists which subdirectories of that directory should be visited. This is based on the match's primary, included, and excluded patterns. This function is very similar to 'visitdir', and the following mapping can be applied: visitdir | visitchildrenlist ----------+------------------- False | set() 'all' | 'all' True | 'this' OR non-empty set of subdirs -or files- to visit Example: Assume matchers ['path:foo/bar', 'rootfilesin:qux'], we would return the following values (assuming the implementation of visitchildrenset is capable of recognizing this; some implementations are not). '' -> {'foo', 'qux'} 'baz' -> set() 'foo' -> {'bar'} # Ideally this would be 'all', but since the prefix nature of matchers # is applied to the entire matcher, we have to downgrade this to # 'this' due to the non-prefix 'rootfilesin'-kind matcher being mixed # in. 'foo/bar' -> 'this' 'qux' -> 'this' Important: Most matchers do not know if they're representing files or directories. They see ['path:dir/f'] and don't know whether 'f' is a file or a directory, so visitchildrenset('dir') for most matchers will return {'f'}, but if the matcher knows it's a file (like exactmatcher does), it may return 'this'. Do not rely on the return being a set indicating that there are no files in this dir to investigate (or equivalently that if there are files to investigate in 'dir' that it will always return 'this'). """ @abc.abstractmethod def always(self) -> bool: """Matcher will match everything and .files() will be empty -- optimization might be possible.""" @abc.abstractmethod def isexact(self) -> bool: """Matcher will match exactly the list of files in .files() -- optimization might be possible.""" @abc.abstractmethod def prefix(self) -> bool: """Matcher will match the paths in .files() recursively -- optimization might be possible.""" @abc.abstractmethod def anypats(self) -> bool: """None of .always(), .isexact(), and .prefix() is true -- optimizations will be difficult."""