# This module is part of GitPython and is released under the # 3-Clause BSD License: https://opensource.org/license/bsd-3-clause/ import os import sys from typing import ( Any, Callable, Dict, List, NoReturn, Optional, Sequence as Sequence, Tuple, TYPE_CHECKING, Type, TypeVar, Union, ) import warnings if sys.version_info >= (3, 8): from typing import ( Literal, Protocol, SupportsIndex as SupportsIndex, TypedDict, runtime_checkable, ) else: from typing_extensions import ( Literal, Protocol, SupportsIndex as SupportsIndex, TypedDict, runtime_checkable, ) if TYPE_CHECKING: from git.objects import Commit, Tree, TagObject, Blob from git.repo import Repo PathLike = Union[str, "os.PathLike[str]"] """A :class:`str` (Unicode) based file or directory path.""" TBD = Any """Alias of :class:`~typing.Any`, when a type hint is meant to become more specific.""" _T = TypeVar("_T") """Type variable used internally in GitPython.""" AnyGitObject = Union["Commit", "Tree", "TagObject", "Blob"] """Union of the :class:`~git.objects.base.Object`-based types that represent actual git object types. As noted in :class:`~git.objects.base.Object`, which has further details, these are: * :class:`Blob ` * :class:`Tree ` * :class:`Commit ` * :class:`TagObject ` Those GitPython classes represent the four git object types, per :manpage:`gitglossary(7)`: * "blob": https://git-scm.com/docs/gitglossary#def_blob_object * "tree object": https://git-scm.com/docs/gitglossary#def_tree_object * "commit object": https://git-scm.com/docs/gitglossary#def_commit_object * "tag object": https://git-scm.com/docs/gitglossary#def_tag_object For more general information on git objects and their types as git understands them: * "object": https://git-scm.com/docs/gitglossary#def_object * "object type": https://git-scm.com/docs/gitglossary#def_object_type :note: See also the :class:`Tree_ish` and :class:`Commit_ish` unions. """ Tree_ish = Union["Commit", "Tree", "TagObject"] """Union of :class:`~git.objects.base.Object`-based types that are typically tree-ish. See :manpage:`gitglossary(7)` on "tree-ish": https://git-scm.com/docs/gitglossary#def_tree-ish :note: :class:`~git.objects.tree.Tree` and :class:`~git.objects.commit.Commit` are the classes whose instances are all tree-ish. This union includes them, but also :class:`~git.objects.tag.TagObject`, only **most** of whose instances are tree-ish. Whether a particular :class:`~git.objects.tag.TagObject` peels (recursively dereferences) to a tree or commit, rather than a blob, can in general only be known at runtime. In practice, git tag objects are nearly always used for tagging commits, and such tags are tree-ish because commits are tree-ish. :note: See also the :class:`AnyGitObject` union of all four classes corresponding to git object types. """ Commit_ish = Union["Commit", "TagObject"] """Union of :class:`~git.objects.base.Object`-based types that are typically commit-ish. See :manpage:`gitglossary(7)` on "commit-ish": https://git-scm.com/docs/gitglossary#def_commit-ish :note: :class:`~git.objects.commit.Commit` is the only class whose instances are all commit-ish. This union type includes :class:`~git.objects.commit.Commit`, but also :class:`~git.objects.tag.TagObject`, only **most** of whose instances are commit-ish. Whether a particular :class:`~git.objects.tag.TagObject` peels (recursively dereferences) to a commit, rather than a tree or blob, can in general only be known at runtime. In practice, git tag objects are nearly always used for tagging commits, and such tags are of course commit-ish. :note: See also the :class:`AnyGitObject` union of all four classes corresponding to git object types. """ GitObjectTypeString = Literal["commit", "tag", "blob", "tree"] """Literal strings identifying git object types and the :class:`~git.objects.base.Object`-based types that represent them. See the :attr:`Object.type ` attribute. These are its values in :class:`~git.objects.base.Object` subclasses that represent git objects. These literals therefore correspond to the types in the :class:`AnyGitObject` union. These are the same strings git itself uses to identify its four object types. See :manpage:`gitglossary(7)` on "object type": https://git-scm.com/docs/gitglossary#def_object_type """ Lit_commit_ish: Type[Literal["commit", "tag"]] """Deprecated. Type of literal strings identifying typically-commitish git object types. Prior to a bugfix, this type had been defined more broadly. Any usage is in practice ambiguous and likely to be incorrect. This type has therefore been made a static type error to appear in annotations. It is preserved, with a deprecated status, to avoid introducing runtime errors in code that refers to it, but it should not be used. Instead of this type: * For the type of the string literals associated with :class:`Commit_ish`, use ``Literal["commit", "tag"]`` or create a new type alias for it. That is equivalent to this type as currently defined (but usable in statically checked type annotations). * For the type of all four string literals associated with :class:`AnyGitObject`, use :class:`GitObjectTypeString`. That is equivalent to the old definition of this type prior to the bugfix (and is also usable in statically checked type annotations). """ def _getattr(name: str) -> Any: if name != "Lit_commit_ish": raise AttributeError(f"module {__name__!r} has no attribute {name!r}") warnings.warn( "Lit_commit_ish is deprecated. It is currently defined as " '`Literal["commit", "tag"]`, which should be used in its place if desired. It ' 'had previously been defined as `Literal["commit", "tag", "blob", "tree"]`, ' "covering all four git object type strings including those that are never " "commit-ish. For that, use the GitObjectTypeString type instead.", DeprecationWarning, stacklevel=2, ) return Literal["commit", "tag"] if not TYPE_CHECKING: # Preserve static checking for undefined/misspelled attributes. __getattr__ = _getattr def __dir__() -> List[str]: return [*globals(), "Lit_commit_ish"] # Config_levels --------------------------------------------------------- Lit_config_levels = Literal["system", "global", "user", "repository"] """Type of literal strings naming git configuration levels. These strings relate to which file a git configuration variable is in. """ ConfigLevels_Tup = Tuple[Literal["system"], Literal["user"], Literal["global"], Literal["repository"]] """Static type of a tuple of the four strings representing configuration levels.""" # Progress parameter type alias ----------------------------------------- CallableProgress = Optional[Callable[[int, Union[str, float], Union[str, float, None], str], None]] """General type of a function or other callable used as a progress reporter for cloning. This is the type of a function or other callable that reports the progress of a clone, when passed as a ``progress`` argument to :meth:`Repo.clone ` or :meth:`Repo.clone_from `. :note: Those :meth:`~git.repo.base.Repo.clone` and :meth:`~git.repo.base.Repo.clone_from` methods also accept :meth:`~git.util.RemoteProgress` instances, including instances of its :meth:`~git.util.CallableRemoteProgress` subclass. :note: Unlike objects that match this type, :meth:`~git.util.RemoteProgress` instances are not directly callable, not even when they are instances of :meth:`~git.util.CallableRemoteProgress`, which wraps a callable and forwards information to it but is not itself callable. :note: This type also allows ``None``, for cloning without reporting progress. """ # ----------------------------------------------------------------------------------- def assert_never(inp: NoReturn, raise_error: bool = True, exc: Union[Exception, None] = None) -> None: """For use in exhaustive checking of a literal or enum in if/else chains. A call to this function should only be reached if not all members are handled, or if an attempt is made to pass non-members through the chain. :param inp: If all members are handled, the argument for `inp` will have the :class:`~typing.Never`/:class:`~typing.NoReturn` type. Otherwise, the type will mismatch and cause a mypy error. :param raise_error: If ``True``, will also raise :exc:`ValueError` with a general "unhandled literal" message, or the exception object passed as `exc`. :param exc: It not ``None``, this should be an already-constructed exception object, to be raised if `raise_error` is ``True``. """ if raise_error: if exc is None: raise ValueError(f"An unhandled literal ({inp!r}) in an if/else chain was found") else: raise exc class Files_TD(TypedDict): """Dictionary with stat counts for the diff of a particular file. For the :class:`~git.util.Stats.files` attribute of :class:`~git.util.Stats` objects. """ insertions: int deletions: int lines: int change_type: str class Total_TD(TypedDict): """Dictionary with total stats from any number of files. For the :class:`~git.util.Stats.total` attribute of :class:`~git.util.Stats` objects. """ insertions: int deletions: int lines: int files: int class HSH_TD(TypedDict): """Dictionary carrying the same information as a :class:`~git.util.Stats` object.""" total: Total_TD files: Dict[PathLike, Files_TD] @runtime_checkable class Has_Repo(Protocol): """Protocol for having a :attr:`repo` attribute, the repository to operate on.""" repo: "Repo" @runtime_checkable class Has_id_attribute(Protocol): """Protocol for having :attr:`_id_attribute_` used in iteration and traversal.""" _id_attribute_: str